Commit 00f82f1c46
Changed files (17)
src
arch
aarch64
arm
riscv64
sparc64
wasm
x86_64
Liveness
src/arch/aarch64/CodeGen.zig
@@ -521,7 +521,7 @@ fn gen(self: *Self) !void {
const inst = self.air.getMainBody()[arg_index];
assert(self.air.instructions.items(.tag)[inst] == .arg);
- const ty = self.air.typeOfIndex(inst);
+ const ty = self.typeOfIndex(inst);
const abi_size = @intCast(u32, ty.abiSize(mod));
const abi_align = ty.abiAlignment(mod);
@@ -653,13 +653,14 @@ fn gen(self: *Self) !void {
}
fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
+ const mod = self.bin_file.options.module.?;
+ const ip = &mod.intern_pool;
const air_tags = self.air.instructions.items(.tag);
for (body) |inst| {
// TODO: remove now-redundant isUnused calls from AIR handler functions
- if (self.liveness.isUnused(inst) and !self.air.mustLower(inst)) {
+ if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
continue;
- }
const old_air_bookkeeping = self.air_bookkeeping;
try self.ensureProcessDeathCapacity(Liveness.bpi);
@@ -845,6 +846,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.constant => unreachable, // excluded from function bodies
.const_ty => unreachable, // excluded from function bodies
+ .interned => unreachable, // excluded from function bodies
.unreach => self.finishAirBookkeeping(),
.optional_payload => try self.airOptionalPayload(inst),
@@ -1028,7 +1030,7 @@ fn allocMem(
/// Use a pointer instruction as the basis for allocating stack memory.
fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
const mod = self.bin_file.options.module.?;
- const elem_ty = self.air.typeOfIndex(inst).elemType();
+ const elem_ty = self.typeOfIndex(inst).elemType();
if (!elem_ty.hasRuntimeBits(mod)) {
// return the stack offset 0. Stack offset 0 will be where all
@@ -1067,7 +1069,7 @@ fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst
}
pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void {
- const stack_mcv = try self.allocRegOrMem(self.air.typeOfIndex(inst), false, inst);
+ const stack_mcv = try self.allocRegOrMem(self.typeOfIndex(inst), false, inst);
log.debug("spilling {d} to stack mcv {any}", .{ inst, stack_mcv });
const reg_mcv = self.getResolvedInstValue(inst);
@@ -1079,14 +1081,14 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void
const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
try branch.inst_table.put(self.gpa, inst, stack_mcv);
- try self.genSetStack(self.air.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);
+ try self.genSetStack(self.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);
}
/// Save the current instruction stored in the compare flags if
/// occupied
fn spillCompareFlagsIfOccupied(self: *Self) !void {
if (self.compare_flags_inst) |inst_to_save| {
- const ty = self.air.typeOfIndex(inst_to_save);
+ const ty = self.typeOfIndex(inst_to_save);
const mcv = self.getResolvedInstValue(inst_to_save);
const new_mcv = switch (mcv) {
.compare_flags => try self.allocRegOrMem(ty, true, inst_to_save),
@@ -1094,7 +1096,7 @@ fn spillCompareFlagsIfOccupied(self: *Self) !void {
else => unreachable, // mcv doesn't occupy the compare flags
};
- try self.setRegOrMem(self.air.typeOfIndex(inst_to_save), new_mcv, mcv);
+ try self.setRegOrMem(self.typeOfIndex(inst_to_save), new_mcv, mcv);
log.debug("spilling {d} to mcv {any}", .{ inst_to_save, new_mcv });
const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
@@ -1126,9 +1128,9 @@ fn copyToTmpRegister(self: *Self, ty: Type, mcv: MCValue) !Register {
/// This can have a side effect of spilling instructions to the stack to free up a register.
fn copyToNewRegister(self: *Self, reg_owner: Air.Inst.Index, mcv: MCValue) !MCValue {
const raw_reg = try self.register_manager.allocReg(reg_owner, gp);
- const ty = self.air.typeOfIndex(reg_owner);
+ const ty = self.typeOfIndex(reg_owner);
const reg = self.registerAlias(raw_reg, ty);
- try self.genSetReg(self.air.typeOfIndex(reg_owner), reg, mcv);
+ try self.genSetReg(self.typeOfIndex(reg_owner), reg, mcv);
return MCValue{ .register = reg };
}
@@ -1181,10 +1183,10 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const operand = ty_op.operand;
const operand_mcv = try self.resolveInst(operand);
- const operand_ty = self.air.typeOf(operand);
+ const operand_ty = self.typeOf(operand);
const operand_info = operand_ty.intInfo(mod);
- const dest_ty = self.air.typeOfIndex(inst);
+ const dest_ty = self.typeOfIndex(inst);
const dest_info = dest_ty.intInfo(mod);
const result: MCValue = result: {
@@ -1201,14 +1203,14 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
if (dest_info.bits > operand_info.bits) {
const dest_mcv = try self.allocRegOrMem(dest_ty, true, inst);
- try self.setRegOrMem(self.air.typeOfIndex(inst), dest_mcv, truncated);
+ try self.setRegOrMem(self.typeOfIndex(inst), dest_mcv, truncated);
break :result dest_mcv;
} else {
if (self.reuseOperand(inst, operand, 0, truncated)) {
break :result truncated;
} else {
const dest_mcv = try self.allocRegOrMem(dest_ty, true, inst);
- try self.setRegOrMem(self.air.typeOfIndex(inst), dest_mcv, truncated);
+ try self.setRegOrMem(self.typeOfIndex(inst), dest_mcv, truncated);
break :result dest_mcv;
}
}
@@ -1303,8 +1305,8 @@ fn trunc(
fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand = try self.resolveInst(ty_op.operand);
- const operand_ty = self.air.typeOf(ty_op.operand);
- const dest_ty = self.air.typeOfIndex(inst);
+ const operand_ty = self.typeOf(ty_op.operand);
+ const dest_ty = self.typeOfIndex(inst);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {
break :blk try self.trunc(inst, operand, operand_ty, dest_ty);
@@ -1325,7 +1327,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand = try self.resolveInst(ty_op.operand);
- const operand_ty = self.air.typeOf(ty_op.operand);
+ const operand_ty = self.typeOf(ty_op.operand);
switch (operand) {
.dead => unreachable,
.unreach => unreachable,
@@ -1492,8 +1494,8 @@ fn minMax(
fn airMinMax(self: *Self, inst: Air.Inst.Index) !void {
const tag = self.air.instructions.items(.tag)[inst];
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
@@ -1512,9 +1514,9 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const ptr = try self.resolveInst(bin_op.lhs);
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const len = try self.resolveInst(bin_op.rhs);
- const len_ty = self.air.typeOf(bin_op.rhs);
+ const len_ty = self.typeOf(bin_op.rhs);
const ptr_bits = self.target.ptrBitWidth();
const ptr_bytes = @divExact(ptr_bits, 8);
@@ -2436,8 +2438,8 @@ fn ptrArithmetic(
fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
@@ -2487,8 +2489,8 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
@@ -2525,10 +2527,10 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
- const lhs_ty = self.air.typeOf(extra.lhs);
- const rhs_ty = self.air.typeOf(extra.rhs);
+ const lhs_ty = self.typeOf(extra.lhs);
+ const rhs_ty = self.typeOf(extra.rhs);
- const tuple_ty = self.air.typeOfIndex(inst);
+ const tuple_ty = self.typeOfIndex(inst);
const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
const tuple_align = tuple_ty.abiAlignment(mod);
const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
@@ -2653,10 +2655,10 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const result: MCValue = result: {
const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
- const lhs_ty = self.air.typeOf(extra.lhs);
- const rhs_ty = self.air.typeOf(extra.rhs);
+ const lhs_ty = self.typeOf(extra.lhs);
+ const rhs_ty = self.typeOf(extra.rhs);
- const tuple_ty = self.air.typeOfIndex(inst);
+ const tuple_ty = self.typeOfIndex(inst);
const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
const tuple_align = tuple_ty.abiAlignment(mod);
const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
@@ -2877,10 +2879,10 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const result: MCValue = result: {
const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
- const lhs_ty = self.air.typeOf(extra.lhs);
- const rhs_ty = self.air.typeOf(extra.rhs);
+ const lhs_ty = self.typeOf(extra.lhs);
+ const rhs_ty = self.typeOf(extra.rhs);
- const tuple_ty = self.air.typeOfIndex(inst);
+ const tuple_ty = self.typeOfIndex(inst);
const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
const tuple_align = tuple_ty.abiAlignment(mod);
const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
@@ -3013,7 +3015,7 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
- const optional_ty = self.air.typeOf(ty_op.operand);
+ const optional_ty = self.typeOf(ty_op.operand);
const mcv = try self.resolveInst(ty_op.operand);
break :result try self.optionalPayload(inst, mcv, optional_ty);
};
@@ -3132,7 +3134,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const error_union_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
- const error_union_ty = self.air.typeOf(ty_op.operand);
+ const error_union_ty = self.typeOf(ty_op.operand);
break :result try self.errUnionErr(error_union_bind, error_union_ty, inst);
};
@@ -3212,7 +3214,7 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const error_union_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
- const error_union_ty = self.air.typeOf(ty_op.operand);
+ const error_union_ty = self.typeOf(ty_op.operand);
break :result try self.errUnionPayload(error_union_bind, error_union_ty, inst);
};
@@ -3266,12 +3268,12 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
}
const result: MCValue = result: {
- const payload_ty = self.air.typeOf(ty_op.operand);
+ const payload_ty = self.typeOf(ty_op.operand);
if (!payload_ty.hasRuntimeBits(mod)) {
break :result MCValue{ .immediate = 1 };
}
- const optional_ty = self.air.typeOfIndex(inst);
+ const optional_ty = self.typeOfIndex(inst);
const operand = try self.resolveInst(ty_op.operand);
const operand_lock: ?RegisterLock = switch (operand) {
.register => |reg| self.register_manager.lockRegAssumeUnused(reg),
@@ -3433,7 +3435,7 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const slice_ty = self.air.typeOf(bin_op.lhs);
+ const slice_ty = self.typeOf(bin_op.lhs);
const result: MCValue = if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = slice_ty.slicePtrFieldType(&buf);
@@ -3482,8 +3484,8 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {
const base_bind: ReadArg.Bind = .{ .mcv = base_mcv };
const index_bind: ReadArg.Bind = .{ .inst = extra.rhs };
- const slice_ty = self.air.typeOf(extra.lhs);
- const index_ty = self.air.typeOf(extra.rhs);
+ const slice_ty = self.typeOf(extra.lhs);
+ const index_ty = self.typeOf(extra.rhs);
const addr = try self.ptrArithmetic(.ptr_add, base_bind, index_bind, slice_ty, index_ty, null);
break :result addr;
@@ -3499,7 +3501,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const result: MCValue = if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {
const base_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs };
@@ -3516,8 +3518,8 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
const ptr_bind: ReadArg.Bind = .{ .inst = extra.lhs };
const index_bind: ReadArg.Bind = .{ .inst = extra.rhs };
- const ptr_ty = self.air.typeOf(extra.lhs);
- const index_ty = self.air.typeOf(extra.rhs);
+ const ptr_ty = self.typeOf(extra.lhs);
+ const index_ty = self.typeOf(extra.rhs);
const addr = try self.ptrArithmetic(.ptr_add, ptr_bind, index_bind, ptr_ty, index_ty, null);
break :result addr;
@@ -3862,16 +3864,16 @@ fn genInlineMemsetCode(
}
fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
- const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const elem_ty = self.air.typeOfIndex(inst);
const mod = self.bin_file.options.module.?;
+ const ty_op = self.air.instructions.items(.data)[inst].ty_op;
+ const elem_ty = self.typeOfIndex(inst);
const elem_size = elem_ty.abiSize(mod);
const result: MCValue = result: {
if (!elem_ty.hasRuntimeBits(mod))
break :result MCValue.none;
const ptr = try self.resolveInst(ty_op.operand);
- const is_volatile = self.air.typeOf(ty_op.operand).isVolatilePtr();
+ const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr();
if (self.liveness.isUnused(inst) and !is_volatile)
break :result MCValue.dead;
@@ -3886,7 +3888,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
break :blk try self.allocRegOrMem(elem_ty, true, inst);
}
};
- try self.load(dst_mcv, ptr, self.air.typeOf(ty_op.operand));
+ try self.load(dst_mcv, ptr, self.typeOf(ty_op.operand));
break :result dst_mcv;
};
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
@@ -4068,8 +4070,8 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const ptr = try self.resolveInst(bin_op.lhs);
const value = try self.resolveInst(bin_op.rhs);
- const ptr_ty = self.air.typeOf(bin_op.lhs);
- const value_ty = self.air.typeOf(bin_op.rhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
+ const value_ty = self.typeOf(bin_op.rhs);
try self.store(ptr, value, ptr_ty, value_ty);
@@ -4093,7 +4095,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
return if (self.liveness.isUnused(inst)) .dead else result: {
const mod = self.bin_file.options.module.?;
const mcv = try self.resolveInst(operand);
- const ptr_ty = self.air.typeOf(operand);
+ const ptr_ty = self.typeOf(operand);
const struct_ty = ptr_ty.childType();
const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
switch (mcv) {
@@ -4118,7 +4120,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const mod = self.bin_file.options.module.?;
const mcv = try self.resolveInst(operand);
- const struct_ty = self.air.typeOf(operand);
+ const struct_ty = self.typeOf(operand);
const struct_field_ty = struct_ty.structFieldType(index);
const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
@@ -4194,7 +4196,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
while (self.args[arg_index] == .none) arg_index += 1;
self.arg_index = arg_index + 1;
- const ty = self.air.typeOfIndex(inst);
+ const ty = self.typeOfIndex(inst);
const tag = self.air.instructions.items(.tag)[inst];
const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, src_index);
@@ -4247,7 +4249,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
const callee = pl_op.operand;
const extra = self.air.extraData(Air.Call, pl_op.payload);
const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
- const ty = self.air.typeOf(callee);
+ const ty = self.typeOf(callee);
const mod = self.bin_file.options.module.?;
const fn_ty = switch (ty.zigTypeTag(mod)) {
@@ -4294,7 +4296,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
for (info.args, 0..) |mc_arg, arg_i| {
const arg = args[arg_i];
- const arg_ty = self.air.typeOf(arg);
+ const arg_ty = self.typeOf(arg);
const arg_mcv = try self.resolveInst(args[arg_i]);
switch (mc_arg) {
@@ -4470,7 +4472,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const ptr = try self.resolveInst(un_op);
- const ptr_ty = self.air.typeOf(un_op);
+ const ptr_ty = self.typeOf(un_op);
const ret_ty = self.fn_type.fnReturnType();
switch (self.ret_mcv) {
@@ -4512,7 +4514,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const lhs_ty = self.air.typeOf(bin_op.lhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {
break :blk try self.cmp(.{ .inst = bin_op.lhs }, .{ .inst = bin_op.rhs }, lhs_ty, op);
@@ -4652,7 +4654,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const operand = pl_op.operand;
const tag = self.air.instructions.items(.tag)[inst];
- const ty = self.air.typeOf(operand);
+ const ty = self.typeOf(operand);
const mcv = try self.resolveInst(operand);
const name = self.air.nullTerminatedString(pl_op.payload);
@@ -4804,7 +4806,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
log.debug("consolidating else_entry {d} {}=>{}", .{ else_key, else_value, canon_mcv });
// TODO make sure the destination stack offset / register does not already have something
// going on there.
- try self.setRegOrMem(self.air.typeOfIndex(else_key), canon_mcv, else_value);
+ try self.setRegOrMem(self.typeOfIndex(else_key), canon_mcv, else_value);
// TODO track the new register / stack allocation
}
try parent_branch.inst_table.ensureUnusedCapacity(self.gpa, saved_then_branch.inst_table.count());
@@ -4831,7 +4833,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
log.debug("consolidating then_entry {d} {}=>{}", .{ then_key, parent_mcv, then_value });
// TODO make sure the destination stack offset / register does not already have something
// going on there.
- try self.setRegOrMem(self.air.typeOfIndex(then_key), parent_mcv, then_value);
+ try self.setRegOrMem(self.typeOfIndex(then_key), parent_mcv, then_value);
// TODO track the new register / stack allocation
}
@@ -4936,7 +4938,7 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand = try self.resolveInst(un_op);
- const operand_ty = self.air.typeOf(un_op);
+ const operand_ty = self.typeOf(un_op);
break :result try self.isNull(.{ .mcv = operand }, operand_ty);
};
@@ -4947,7 +4949,7 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand_ptr = try self.resolveInst(un_op);
- const ptr_ty = self.air.typeOf(un_op);
+ const ptr_ty = self.typeOf(un_op);
const elem_ty = ptr_ty.elemType();
const operand = try self.allocRegOrMem(elem_ty, true, null);
@@ -4962,7 +4964,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand = try self.resolveInst(un_op);
- const operand_ty = self.air.typeOf(un_op);
+ const operand_ty = self.typeOf(un_op);
break :result try self.isNonNull(.{ .mcv = operand }, operand_ty);
};
@@ -4973,7 +4975,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand_ptr = try self.resolveInst(un_op);
- const ptr_ty = self.air.typeOf(un_op);
+ const ptr_ty = self.typeOf(un_op);
const elem_ty = ptr_ty.elemType();
const operand = try self.allocRegOrMem(elem_ty, true, null);
@@ -4988,7 +4990,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const error_union_bind: ReadArg.Bind = .{ .inst = un_op };
- const error_union_ty = self.air.typeOf(un_op);
+ const error_union_ty = self.typeOf(un_op);
break :result try self.isErr(error_union_bind, error_union_ty);
};
@@ -4999,7 +5001,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand_ptr = try self.resolveInst(un_op);
- const ptr_ty = self.air.typeOf(un_op);
+ const ptr_ty = self.typeOf(un_op);
const elem_ty = ptr_ty.elemType();
const operand = try self.allocRegOrMem(elem_ty, true, null);
@@ -5014,7 +5016,7 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const error_union_bind: ReadArg.Bind = .{ .inst = un_op };
- const error_union_ty = self.air.typeOf(un_op);
+ const error_union_ty = self.typeOf(un_op);
break :result try self.isNonErr(error_union_bind, error_union_ty);
};
@@ -5025,7 +5027,7 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand_ptr = try self.resolveInst(un_op);
- const ptr_ty = self.air.typeOf(un_op);
+ const ptr_ty = self.typeOf(un_op);
const elem_ty = ptr_ty.elemType();
const operand = try self.allocRegOrMem(elem_ty, true, null);
@@ -5093,7 +5095,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
- const condition_ty = self.air.typeOf(pl_op.operand);
+ const condition_ty = self.typeOf(pl_op.operand);
const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
const liveness = try self.liveness.getSwitchBr(
self.gpa,
@@ -5241,7 +5243,7 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
const mod = self.bin_file.options.module.?;
const block_data = self.blocks.getPtr(block).?;
- if (self.air.typeOf(operand).hasRuntimeBits(mod)) {
+ if (self.typeOf(operand).hasRuntimeBits(mod)) {
const operand_mcv = try self.resolveInst(operand);
const block_mcv = block_data.mcv;
if (block_mcv == .none) {
@@ -5249,14 +5251,14 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
.none, .dead, .unreach => unreachable,
.register, .stack_offset, .memory => operand_mcv,
.immediate, .stack_argument_offset, .compare_flags => blk: {
- const new_mcv = try self.allocRegOrMem(self.air.typeOfIndex(block), true, block);
- try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, operand_mcv);
+ const new_mcv = try self.allocRegOrMem(self.typeOfIndex(block), true, block);
+ try self.setRegOrMem(self.typeOfIndex(block), new_mcv, operand_mcv);
break :blk new_mcv;
},
else => return self.fail("TODO implement block_data.mcv = operand_mcv for {}", .{operand_mcv}),
};
} else {
- try self.setRegOrMem(self.air.typeOfIndex(block), block_mcv, operand_mcv);
+ try self.setRegOrMem(self.typeOfIndex(block), block_mcv, operand_mcv);
}
}
return self.brVoid(block);
@@ -5322,7 +5324,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
const arg_mcv = try self.resolveInst(input);
try self.register_manager.getReg(reg, null);
- try self.genSetReg(self.air.typeOf(input), reg, arg_mcv);
+ try self.genSetReg(self.typeOf(input), reg, arg_mcv);
}
{
@@ -5945,7 +5947,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
};
defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);
- const dest_ty = self.air.typeOfIndex(inst);
+ const dest_ty = self.typeOfIndex(inst);
const dest = try self.allocRegOrMem(dest_ty, true, inst);
try self.setRegOrMem(dest_ty, dest, operand);
break :result dest;
@@ -5956,7 +5958,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
- const ptr_ty = self.air.typeOf(ty_op.operand);
+ const ptr_ty = self.typeOf(ty_op.operand);
const ptr = try self.resolveInst(ty_op.operand);
const array_ty = ptr_ty.childType();
const array_len = @intCast(u32, array_ty.arrayLen());
@@ -6076,7 +6078,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
}
fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
- const vector_ty = self.air.typeOfIndex(inst);
+ const vector_ty = self.typeOfIndex(inst);
const len = vector_ty.vectorLen();
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
@@ -6125,7 +6127,7 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {
const body = self.air.extra[extra.end..][0..extra.data.body_len];
const result: MCValue = result: {
const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };
- const error_union_ty = self.air.typeOf(pl_op.operand);
+ const error_union_ty = self.typeOf(pl_op.operand);
const error_union_size = @intCast(u32, error_union_ty.abiSize(mod));
const error_union_align = error_union_ty.abiAlignment(mod);
@@ -6159,7 +6161,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
const mod = self.bin_file.options.module.?;
// If the type has no codegen bits, no need to store it.
- const inst_ty = self.air.typeOf(inst);
+ const inst_ty = self.typeOf(inst);
if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod))
return MCValue{ .none = {} };
@@ -6428,3 +6430,13 @@ 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);
+}
+
+fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
+ const mod = self.bin_file.options.module.?;
+ return self.air.typeOfIndex(inst, mod.intern_pool);
+}
src/arch/arm/CodeGen.zig
@@ -477,6 +477,7 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {
}
fn gen(self: *Self) !void {
+ const mod = self.bin_file.options.module.?;
const cc = self.fn_type.fnCallingConvention();
if (cc != .Naked) {
// push {fp, lr}
@@ -518,9 +519,8 @@ fn gen(self: *Self) !void {
const inst = self.air.getMainBody()[arg_index];
assert(self.air.instructions.items(.tag)[inst] == .arg);
- const ty = self.air.typeOfIndex(inst);
+ const ty = self.typeOfIndex(inst);
- const mod = self.bin_file.options.module.?;
const abi_size = @intCast(u32, ty.abiSize(mod));
const abi_align = ty.abiAlignment(mod);
const stack_offset = try self.allocMem(abi_size, abi_align, inst);
@@ -637,13 +637,14 @@ fn gen(self: *Self) !void {
}
fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
+ const mod = self.bin_file.options.module.?;
+ const ip = &mod.intern_pool;
const air_tags = self.air.instructions.items(.tag);
for (body) |inst| {
// TODO: remove now-redundant isUnused calls from AIR handler functions
- if (self.liveness.isUnused(inst) and !self.air.mustLower(inst)) {
+ if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
continue;
- }
const old_air_bookkeeping = self.air_bookkeeping;
try self.ensureProcessDeathCapacity(Liveness.bpi);
@@ -829,6 +830,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.constant => unreachable, // excluded from function bodies
.const_ty => unreachable, // excluded from function bodies
+ .interned => unreachable, // excluded from function bodies
.unreach => self.finishAirBookkeeping(),
.optional_payload => try self.airOptionalPayload(inst),
@@ -1008,7 +1010,7 @@ fn allocMem(
/// Use a pointer instruction as the basis for allocating stack memory.
fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
const mod = self.bin_file.options.module.?;
- const elem_ty = self.air.typeOfIndex(inst).elemType();
+ const elem_ty = self.typeOfIndex(inst).elemType();
if (!elem_ty.hasRuntimeBits(mod)) {
// As this stack item will never be dereferenced at runtime,
@@ -1050,7 +1052,7 @@ fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst
}
pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void {
- const stack_mcv = try self.allocRegOrMem(self.air.typeOfIndex(inst), false, inst);
+ const stack_mcv = try self.allocRegOrMem(self.typeOfIndex(inst), false, inst);
log.debug("spilling {} (%{d}) to stack mcv {any}", .{ reg, inst, stack_mcv });
const reg_mcv = self.getResolvedInstValue(inst);
@@ -1064,14 +1066,14 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void
const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
try branch.inst_table.put(self.gpa, inst, stack_mcv);
- try self.genSetStack(self.air.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);
+ try self.genSetStack(self.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);
}
/// Save the current instruction stored in the compare flags if
/// occupied
fn spillCompareFlagsIfOccupied(self: *Self) !void {
if (self.cpsr_flags_inst) |inst_to_save| {
- const ty = self.air.typeOfIndex(inst_to_save);
+ const ty = self.typeOfIndex(inst_to_save);
const mcv = self.getResolvedInstValue(inst_to_save);
const new_mcv = switch (mcv) {
.cpsr_flags => try self.allocRegOrMem(ty, true, inst_to_save),
@@ -1081,7 +1083,7 @@ fn spillCompareFlagsIfOccupied(self: *Self) !void {
else => unreachable, // mcv doesn't occupy the compare flags
};
- try self.setRegOrMem(self.air.typeOfIndex(inst_to_save), new_mcv, mcv);
+ try self.setRegOrMem(self.typeOfIndex(inst_to_save), new_mcv, mcv);
log.debug("spilling {d} to mcv {any}", .{ inst_to_save, new_mcv });
const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
@@ -1151,15 +1153,15 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
+ const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
if (self.liveness.isUnused(inst))
return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
const operand = try self.resolveInst(ty_op.operand);
- const operand_ty = self.air.typeOf(ty_op.operand);
- const dest_ty = self.air.typeOfIndex(inst);
+ const operand_ty = self.typeOf(ty_op.operand);
+ const dest_ty = self.typeOfIndex(inst);
- const mod = self.bin_file.options.module.?;
const operand_abi_size = operand_ty.abiSize(mod);
const dest_abi_size = dest_ty.abiSize(mod);
const info_a = operand_ty.intInfo(mod);
@@ -1262,8 +1264,8 @@ fn trunc(
fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
- const operand_ty = self.air.typeOf(ty_op.operand);
- const dest_ty = self.air.typeOfIndex(inst);
+ const operand_ty = self.typeOf(ty_op.operand);
+ const dest_ty = self.typeOfIndex(inst);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {
break :blk try self.trunc(inst, operand_bind, operand_ty, dest_ty);
@@ -1284,7 +1286,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
- const operand_ty = self.air.typeOf(ty_op.operand);
+ const operand_ty = self.typeOf(ty_op.operand);
switch (try operand_bind.resolveToMcv(self)) {
.dead => unreachable,
.unreach => unreachable,
@@ -1467,8 +1469,8 @@ fn minMax(
fn airMinMax(self: *Self, inst: Air.Inst.Index) !void {
const tag = self.air.instructions.items(.tag)[inst];
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
@@ -1487,9 +1489,9 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const ptr = try self.resolveInst(bin_op.lhs);
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const len = try self.resolveInst(bin_op.rhs);
- const len_ty = self.air.typeOf(bin_op.rhs);
+ const len_ty = self.typeOf(bin_op.rhs);
const stack_offset = try self.allocMem(8, 4, inst);
try self.genSetStack(ptr_ty, stack_offset, ptr);
@@ -1501,8 +1503,8 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
@@ -1552,8 +1554,8 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
@@ -1590,10 +1592,10 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
- const lhs_ty = self.air.typeOf(extra.lhs);
- const rhs_ty = self.air.typeOf(extra.rhs);
+ const lhs_ty = self.typeOf(extra.lhs);
+ const rhs_ty = self.typeOf(extra.rhs);
- const tuple_ty = self.air.typeOfIndex(inst);
+ const tuple_ty = self.typeOfIndex(inst);
const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
const tuple_align = tuple_ty.abiAlignment(mod);
const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
@@ -1703,10 +1705,10 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const result: MCValue = result: {
const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
- const lhs_ty = self.air.typeOf(extra.lhs);
- const rhs_ty = self.air.typeOf(extra.rhs);
+ const lhs_ty = self.typeOf(extra.lhs);
+ const rhs_ty = self.typeOf(extra.rhs);
- const tuple_ty = self.air.typeOfIndex(inst);
+ const tuple_ty = self.typeOfIndex(inst);
const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
const tuple_align = tuple_ty.abiAlignment(mod);
const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
@@ -1865,10 +1867,10 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
const mod = self.bin_file.options.module.?;
const result: MCValue = result: {
- const lhs_ty = self.air.typeOf(extra.lhs);
- const rhs_ty = self.air.typeOf(extra.rhs);
+ const lhs_ty = self.typeOf(extra.lhs);
+ const rhs_ty = self.typeOf(extra.rhs);
- const tuple_ty = self.air.typeOfIndex(inst);
+ const tuple_ty = self.typeOfIndex(inst);
const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
const tuple_align = tuple_ty.abiAlignment(mod);
const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
@@ -2019,10 +2021,10 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
}
fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
+ const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
- const optional_ty = self.air.typeOfIndex(inst);
- const mod = self.bin_file.options.module.?;
+ const optional_ty = self.typeOfIndex(inst);
const abi_size = @intCast(u32, optional_ty.abiSize(mod));
// Optional with a zero-bit payload type is just a boolean true
@@ -2105,7 +2107,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const error_union_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
- const error_union_ty = self.air.typeOf(ty_op.operand);
+ const error_union_ty = self.typeOf(ty_op.operand);
break :result try self.errUnionErr(error_union_bind, error_union_ty, inst);
};
@@ -2182,7 +2184,7 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const error_union_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
- const error_union_ty = self.air.typeOf(ty_op.operand);
+ const error_union_ty = self.typeOf(ty_op.operand);
break :result try self.errUnionPayload(error_union_bind, error_union_ty, inst);
};
@@ -2430,7 +2432,7 @@ fn ptrElemVal(
fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const slice_ty = self.air.typeOf(bin_op.lhs);
+ const slice_ty = self.typeOf(bin_op.lhs);
const result: MCValue = if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = slice_ty.slicePtrFieldType(&buf);
@@ -2456,8 +2458,8 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {
const base_bind: ReadArg.Bind = .{ .mcv = base_mcv };
const index_bind: ReadArg.Bind = .{ .inst = extra.rhs };
- const slice_ty = self.air.typeOf(extra.lhs);
- const index_ty = self.air.typeOf(extra.rhs);
+ const slice_ty = self.typeOf(extra.lhs);
+ const index_ty = self.typeOf(extra.rhs);
const addr = try self.ptrArithmetic(.ptr_add, base_bind, index_bind, slice_ty, index_ty, null);
break :result addr;
@@ -2523,7 +2525,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const array_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs };
- const array_ty = self.air.typeOf(bin_op.lhs);
+ const array_ty = self.typeOf(bin_op.lhs);
break :result try self.arrayElemVal(array_bind, index_bind, array_ty, inst);
};
@@ -2532,7 +2534,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const result: MCValue = if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {
const base_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs };
@@ -2549,8 +2551,8 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
const ptr_bind: ReadArg.Bind = .{ .inst = extra.lhs };
const index_bind: ReadArg.Bind = .{ .inst = extra.rhs };
- const ptr_ty = self.air.typeOf(extra.lhs);
- const index_ty = self.air.typeOf(extra.rhs);
+ const ptr_ty = self.typeOf(extra.lhs);
+ const index_ty = self.typeOf(extra.rhs);
const addr = try self.ptrArithmetic(.ptr_add, ptr_bind, index_bind, ptr_ty, index_ty, null);
break :result addr;
@@ -2736,13 +2738,13 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const elem_ty = self.air.typeOfIndex(inst);
+ const elem_ty = self.typeOfIndex(inst);
const result: MCValue = result: {
if (!elem_ty.hasRuntimeBits(mod))
break :result MCValue.none;
const ptr = try self.resolveInst(ty_op.operand);
- const is_volatile = self.air.typeOf(ty_op.operand).isVolatilePtr();
+ const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr();
if (self.liveness.isUnused(inst) and !is_volatile)
break :result MCValue.dead;
@@ -2755,7 +2757,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
break :blk try self.allocRegOrMem(elem_ty, true, inst);
}
};
- try self.load(dest_mcv, ptr, self.air.typeOf(ty_op.operand));
+ try self.load(dest_mcv, ptr, self.typeOf(ty_op.operand));
break :result dest_mcv;
};
@@ -2860,8 +2862,8 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const ptr = try self.resolveInst(bin_op.lhs);
const value = try self.resolveInst(bin_op.rhs);
- const ptr_ty = self.air.typeOf(bin_op.lhs);
- const value_ty = self.air.typeOf(bin_op.rhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
+ const value_ty = self.typeOf(bin_op.rhs);
try self.store(ptr, value, ptr_ty, value_ty);
@@ -2885,7 +2887,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
return if (self.liveness.isUnused(inst)) .dead else result: {
const mod = self.bin_file.options.module.?;
const mcv = try self.resolveInst(operand);
- const ptr_ty = self.air.typeOf(operand);
+ const ptr_ty = self.typeOf(operand);
const struct_ty = ptr_ty.childType();
const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
switch (mcv) {
@@ -2910,7 +2912,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const mcv = try self.resolveInst(operand);
- const struct_ty = self.air.typeOf(operand);
+ const struct_ty = self.typeOf(operand);
const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
const struct_field_ty = struct_ty.structFieldType(index);
@@ -4169,7 +4171,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
while (self.args[arg_index] == .none) arg_index += 1;
self.arg_index = arg_index + 1;
- const ty = self.air.typeOfIndex(inst);
+ const ty = self.typeOfIndex(inst);
const tag = self.air.instructions.items(.tag)[inst];
const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, src_index);
@@ -4222,7 +4224,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
const callee = pl_op.operand;
const extra = self.air.extraData(Air.Call, pl_op.payload);
const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
- const ty = self.air.typeOf(callee);
+ const ty = self.typeOf(callee);
const mod = self.bin_file.options.module.?;
const fn_ty = switch (ty.zigTypeTag(mod)) {
@@ -4276,7 +4278,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
for (info.args, 0..) |mc_arg, arg_i| {
const arg = args[arg_i];
- const arg_ty = self.air.typeOf(arg);
+ const arg_ty = self.typeOf(arg);
const arg_mcv = try self.resolveInst(args[arg_i]);
switch (mc_arg) {
@@ -4418,7 +4420,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const ptr = try self.resolveInst(un_op);
- const ptr_ty = self.air.typeOf(un_op);
+ const ptr_ty = self.typeOf(un_op);
const ret_ty = self.fn_type.fnReturnType();
switch (self.ret_mcv) {
@@ -4461,7 +4463,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const lhs_ty = self.air.typeOf(bin_op.lhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {
break :blk try self.cmp(.{ .inst = bin_op.lhs }, .{ .inst = bin_op.rhs }, lhs_ty, op);
@@ -4600,7 +4602,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const operand = pl_op.operand;
const tag = self.air.instructions.items(.tag)[inst];
- const ty = self.air.typeOf(operand);
+ const ty = self.typeOf(operand);
const mcv = try self.resolveInst(operand);
const name = self.air.nullTerminatedString(pl_op.payload);
@@ -4755,7 +4757,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
log.debug("consolidating else_entry {d} {}=>{}", .{ else_key, else_value, canon_mcv });
// TODO make sure the destination stack offset / register does not already have something
// going on there.
- try self.setRegOrMem(self.air.typeOfIndex(else_key), canon_mcv, else_value);
+ try self.setRegOrMem(self.typeOfIndex(else_key), canon_mcv, else_value);
// TODO track the new register / stack allocation
}
try parent_branch.inst_table.ensureUnusedCapacity(self.gpa, saved_then_branch.inst_table.count());
@@ -4782,7 +4784,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
log.debug("consolidating then_entry {d} {}=>{}", .{ then_key, parent_mcv, then_value });
// TODO make sure the destination stack offset / register does not already have something
// going on there.
- try self.setRegOrMem(self.air.typeOfIndex(then_key), parent_mcv, then_value);
+ try self.setRegOrMem(self.typeOfIndex(then_key), parent_mcv, then_value);
// TODO track the new register / stack allocation
}
@@ -4827,7 +4829,7 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand_bind: ReadArg.Bind = .{ .inst = un_op };
- const operand_ty = self.air.typeOf(un_op);
+ const operand_ty = self.typeOf(un_op);
break :result try self.isNull(operand_bind, operand_ty);
};
@@ -4838,7 +4840,7 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand_ptr = try self.resolveInst(un_op);
- const ptr_ty = self.air.typeOf(un_op);
+ const ptr_ty = self.typeOf(un_op);
const elem_ty = ptr_ty.elemType();
const operand = try self.allocRegOrMem(elem_ty, true, null);
@@ -4853,7 +4855,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand_bind: ReadArg.Bind = .{ .inst = un_op };
- const operand_ty = self.air.typeOf(un_op);
+ const operand_ty = self.typeOf(un_op);
break :result try self.isNonNull(operand_bind, operand_ty);
};
@@ -4864,7 +4866,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand_ptr = try self.resolveInst(un_op);
- const ptr_ty = self.air.typeOf(un_op);
+ const ptr_ty = self.typeOf(un_op);
const elem_ty = ptr_ty.elemType();
const operand = try self.allocRegOrMem(elem_ty, true, null);
@@ -4913,7 +4915,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const error_union_bind: ReadArg.Bind = .{ .inst = un_op };
- const error_union_ty = self.air.typeOf(un_op);
+ const error_union_ty = self.typeOf(un_op);
break :result try self.isErr(error_union_bind, error_union_ty);
};
@@ -4924,7 +4926,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand_ptr = try self.resolveInst(un_op);
- const ptr_ty = self.air.typeOf(un_op);
+ const ptr_ty = self.typeOf(un_op);
const elem_ty = ptr_ty.elemType();
const operand = try self.allocRegOrMem(elem_ty, true, null);
@@ -4939,7 +4941,7 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const error_union_bind: ReadArg.Bind = .{ .inst = un_op };
- const error_union_ty = self.air.typeOf(un_op);
+ const error_union_ty = self.typeOf(un_op);
break :result try self.isNonErr(error_union_bind, error_union_ty);
};
@@ -4950,7 +4952,7 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand_ptr = try self.resolveInst(un_op);
- const ptr_ty = self.air.typeOf(un_op);
+ const ptr_ty = self.typeOf(un_op);
const elem_ty = ptr_ty.elemType();
const operand = try self.allocRegOrMem(elem_ty, true, null);
@@ -5018,7 +5020,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
- const condition_ty = self.air.typeOf(pl_op.operand);
+ const condition_ty = self.typeOf(pl_op.operand);
const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
const liveness = try self.liveness.getSwitchBr(
self.gpa,
@@ -5164,7 +5166,7 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
const mod = self.bin_file.options.module.?;
const block_data = self.blocks.getPtr(block).?;
- if (self.air.typeOf(operand).hasRuntimeBits(mod)) {
+ if (self.typeOf(operand).hasRuntimeBits(mod)) {
const operand_mcv = try self.resolveInst(operand);
const block_mcv = block_data.mcv;
if (block_mcv == .none) {
@@ -5172,14 +5174,14 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
.none, .dead, .unreach => unreachable,
.register, .stack_offset, .memory => operand_mcv,
.immediate, .stack_argument_offset, .cpsr_flags => blk: {
- const new_mcv = try self.allocRegOrMem(self.air.typeOfIndex(block), true, block);
- try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, operand_mcv);
+ const new_mcv = try self.allocRegOrMem(self.typeOfIndex(block), true, block);
+ try self.setRegOrMem(self.typeOfIndex(block), new_mcv, operand_mcv);
break :blk new_mcv;
},
else => return self.fail("TODO implement block_data.mcv = operand_mcv for {}", .{operand_mcv}),
};
} else {
- try self.setRegOrMem(self.air.typeOfIndex(block), block_mcv, operand_mcv);
+ try self.setRegOrMem(self.typeOfIndex(block), block_mcv, operand_mcv);
}
}
return self.brVoid(block);
@@ -5243,7 +5245,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
const arg_mcv = try self.resolveInst(input);
try self.register_manager.getReg(reg, null);
- try self.genSetReg(self.air.typeOf(input), reg, arg_mcv);
+ try self.genSetReg(self.typeOf(input), reg, arg_mcv);
}
{
@@ -5896,7 +5898,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
};
defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);
- const dest_ty = self.air.typeOfIndex(inst);
+ const dest_ty = self.typeOfIndex(inst);
const dest = try self.allocRegOrMem(dest_ty, true, inst);
try self.setRegOrMem(dest_ty, dest, operand);
break :result dest;
@@ -5907,7 +5909,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
- const ptr_ty = self.air.typeOf(ty_op.operand);
+ const ptr_ty = self.typeOf(ty_op.operand);
const ptr = try self.resolveInst(ty_op.operand);
const array_ty = ptr_ty.childType();
const array_len = @intCast(u32, array_ty.arrayLen());
@@ -6023,7 +6025,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
}
fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
- const vector_ty = self.air.typeOfIndex(inst);
+ const vector_ty = self.typeOfIndex(inst);
const len = vector_ty.vectorLen();
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
@@ -6072,7 +6074,7 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {
const body = self.air.extra[extra.end..][0..extra.data.body_len];
const result: MCValue = result: {
const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };
- const error_union_ty = self.air.typeOf(pl_op.operand);
+ const error_union_ty = self.typeOf(pl_op.operand);
const mod = self.bin_file.options.module.?;
const error_union_size = @intCast(u32, error_union_ty.abiSize(mod));
const error_union_align = error_union_ty.abiAlignment(mod);
@@ -6107,7 +6109,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
const mod = self.bin_file.options.module.?;
// If the type has no codegen bits, no need to store it.
- const inst_ty = self.air.typeOf(inst);
+ const inst_ty = self.typeOf(inst);
if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod))
return MCValue{ .none = {} };
@@ -6333,3 +6335,13 @@ fn parseRegName(name: []const u8) ?Register {
}
return std.meta.stringToEnum(Register, name);
}
+
+fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
+ const mod = self.bin_file.options.module.?;
+ 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);
+}
src/arch/riscv64/CodeGen.zig
@@ -470,13 +470,14 @@ fn gen(self: *Self) !void {
}
fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
+ const mod = self.bin_file.options.module.?;
+ const ip = &mod.intern_pool;
const air_tags = self.air.instructions.items(.tag);
for (body) |inst| {
// TODO: remove now-redundant isUnused calls from AIR handler functions
- if (self.liveness.isUnused(inst) and !self.air.mustLower(inst)) {
+ if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
continue;
- }
const old_air_bookkeeping = self.air_bookkeeping;
try self.ensureProcessDeathCapacity(Liveness.bpi);
@@ -658,6 +659,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.constant => unreachable, // excluded from function bodies
.const_ty => unreachable, // excluded from function bodies
+ .interned => unreachable, // excluded from function bodies
.unreach => self.finishAirBookkeeping(),
.optional_payload => try self.airOptionalPayload(inst),
@@ -804,8 +806,8 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u
/// Use a pointer instruction as the basis for allocating stack memory.
fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
- const elem_ty = self.air.typeOfIndex(inst).elemType();
const mod = self.bin_file.options.module.?;
+ const elem_ty = self.typeOfIndex(inst).elemType();
const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
};
@@ -815,8 +817,8 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
}
fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
- const elem_ty = self.air.typeOfIndex(inst);
const mod = self.bin_file.options.module.?;
+ const elem_ty = self.typeOfIndex(inst);
const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
};
@@ -845,7 +847,7 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void
assert(reg == reg_mcv.register);
const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
try branch.inst_table.put(self.gpa, inst, stack_mcv);
- try self.genSetStack(self.air.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);
+ try self.genSetStack(self.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);
}
/// Copies a value to a register without tracking the register. The register is not considered
@@ -862,7 +864,7 @@ fn copyToTmpRegister(self: *Self, ty: Type, mcv: MCValue) !Register {
/// This can have a side effect of spilling instructions to the stack to free up a register.
fn copyToNewRegister(self: *Self, reg_owner: Air.Inst.Index, mcv: MCValue) !MCValue {
const reg = try self.register_manager.allocReg(reg_owner, gp);
- try self.genSetReg(self.air.typeOfIndex(reg_owner), reg, mcv);
+ try self.genSetReg(self.typeOfIndex(reg_owner), reg, mcv);
return MCValue{ .register = reg };
}
@@ -894,10 +896,10 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
const mod = self.bin_file.options.module.?;
- const operand_ty = self.air.typeOf(ty_op.operand);
+ const operand_ty = self.typeOf(ty_op.operand);
const operand = try self.resolveInst(ty_op.operand);
const info_a = operand_ty.intInfo(mod);
- const info_b = self.air.typeOfIndex(inst).intInfo(mod);
+ const info_b = self.typeOfIndex(inst).intInfo(mod);
if (info_a.signedness != info_b.signedness)
return self.fail("TODO gen intcast sign safety in semantic analysis", .{});
@@ -1126,8 +1128,8 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else try self.binOp(tag, inst, lhs, rhs, lhs_ty, rhs_ty);
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
@@ -1138,8 +1140,8 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else try self.binOp(tag, inst, lhs, rhs, lhs_ty, rhs_ty);
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
@@ -1333,7 +1335,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const mod = self.bin_file.options.module.?;
- const optional_ty = self.air.typeOfIndex(inst);
+ const optional_ty = self.typeOfIndex(inst);
// Optional with a zero-bit payload type is just a boolean true
if (optional_ty.abiSize(mod) == 1)
@@ -1525,15 +1527,15 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
}
fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
+ const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const elem_ty = self.air.typeOfIndex(inst);
+ const elem_ty = self.typeOfIndex(inst);
const result: MCValue = result: {
- const mod = self.bin_file.options.module.?;
if (!elem_ty.hasRuntimeBits(mod))
break :result MCValue.none;
const ptr = try self.resolveInst(ty_op.operand);
- const is_volatile = self.air.typeOf(ty_op.operand).isVolatilePtr();
+ const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr();
if (self.liveness.isUnused(inst) and !is_volatile)
break :result MCValue.dead;
@@ -1545,7 +1547,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
break :blk try self.allocRegOrMem(inst, true);
}
};
- try self.load(dst_mcv, ptr, self.air.typeOf(ty_op.operand));
+ try self.load(dst_mcv, ptr, self.typeOf(ty_op.operand));
break :result dst_mcv;
};
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
@@ -1586,8 +1588,8 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const ptr = try self.resolveInst(bin_op.lhs);
const value = try self.resolveInst(bin_op.rhs);
- const ptr_ty = self.air.typeOf(bin_op.lhs);
- const value_ty = self.air.typeOf(bin_op.rhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
+ const value_ty = self.typeOf(bin_op.rhs);
try self.store(ptr, value, ptr_ty, value_ty);
@@ -1647,7 +1649,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
const arg_index = self.arg_index;
self.arg_index += 1;
- const ty = self.air.typeOfIndex(inst);
+ const ty = self.typeOfIndex(inst);
_ = ty;
const result = self.args[arg_index];
@@ -1704,7 +1706,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
const mod = self.bin_file.options.module.?;
if (modifier == .always_tail) return self.fail("TODO implement tail calls for riscv64", .{});
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
- const fn_ty = self.air.typeOf(pl_op.operand);
+ const fn_ty = self.typeOf(pl_op.operand);
const callee = pl_op.operand;
const extra = self.air.extraData(Air.Call, pl_op.payload);
const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
@@ -1717,7 +1719,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
if (self.bin_file.cast(link.File.Elf)) |elf_file| {
for (info.args, 0..) |mc_arg, arg_i| {
const arg = args[arg_i];
- const arg_ty = self.air.typeOf(arg);
+ const arg_ty = self.typeOf(arg);
const arg_mcv = try self.resolveInst(args[arg_i]);
switch (mc_arg) {
@@ -1829,9 +1831,9 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
if (self.liveness.isUnused(inst))
return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });
- const ty = self.air.typeOf(bin_op.lhs);
+ const ty = self.typeOf(bin_op.lhs);
const mod = self.bin_file.options.module.?;
- assert(ty.eql(self.air.typeOf(bin_op.rhs), mod));
+ assert(ty.eql(self.typeOf(bin_op.rhs), mod));
if (ty.zigTypeTag(mod) == .ErrorSet)
return self.fail("TODO implement cmp for errors", .{});
@@ -1950,7 +1952,7 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
break :blk try self.allocRegOrMem(inst, true);
}
};
- try self.load(operand, operand_ptr, self.air.typeOf(un_op));
+ try self.load(operand, operand_ptr, self.typeOf(un_op));
break :result try self.isNull(operand);
};
return self.finishAir(inst, result, .{ un_op, .none, .none });
@@ -1977,7 +1979,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
break :blk try self.allocRegOrMem(inst, true);
}
};
- try self.load(operand, operand_ptr, self.air.typeOf(un_op));
+ try self.load(operand, operand_ptr, self.typeOf(un_op));
break :result try self.isNonNull(operand);
};
return self.finishAir(inst, result, .{ un_op, .none, .none });
@@ -2004,7 +2006,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
break :blk try self.allocRegOrMem(inst, true);
}
};
- try self.load(operand, operand_ptr, self.air.typeOf(un_op));
+ try self.load(operand, operand_ptr, self.typeOf(un_op));
break :result try self.isErr(operand);
};
return self.finishAir(inst, result, .{ un_op, .none, .none });
@@ -2031,7 +2033,7 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
break :blk try self.allocRegOrMem(inst, true);
}
};
- try self.load(operand, operand_ptr, self.air.typeOf(un_op));
+ try self.load(operand, operand_ptr, self.typeOf(un_op));
break :result try self.isNonErr(operand);
};
return self.finishAir(inst, result, .{ un_op, .none, .none });
@@ -2112,13 +2114,13 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
const block_data = self.blocks.getPtr(block).?;
const mod = self.bin_file.options.module.?;
- if (self.air.typeOf(operand).hasRuntimeBits(mod)) {
+ if (self.typeOf(operand).hasRuntimeBits(mod)) {
const operand_mcv = try self.resolveInst(operand);
const block_mcv = block_data.mcv;
if (block_mcv == .none) {
block_data.mcv = operand_mcv;
} else {
- try self.setRegOrMem(self.air.typeOfIndex(block), block_mcv, operand_mcv);
+ try self.setRegOrMem(self.typeOfIndex(block), block_mcv, operand_mcv);
}
}
return self.brVoid(block);
@@ -2181,7 +2183,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
const arg_mcv = try self.resolveInst(input);
try self.register_manager.getReg(reg, null);
- try self.genSetReg(self.air.typeOf(input), reg, arg_mcv);
+ try self.genSetReg(self.typeOf(input), reg, arg_mcv);
}
{
@@ -2377,7 +2379,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);
const dest = try self.allocRegOrMem(inst, true);
- try self.setRegOrMem(self.air.typeOfIndex(inst), dest, operand);
+ try self.setRegOrMem(self.typeOfIndex(inst), dest, operand);
break :result dest;
};
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
@@ -2494,7 +2496,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
}
fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
- const vector_ty = self.air.typeOfIndex(inst);
+ const vector_ty = self.typeOfIndex(inst);
const len = vector_ty.vectorLen();
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
@@ -2541,7 +2543,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
const mod = self.bin_file.options.module.?;
// If the type has no codegen bits, no need to store it.
- const inst_ty = self.air.typeOf(inst);
+ const inst_ty = self.typeOf(inst);
if (!inst_ty.hasRuntimeBits(mod))
return MCValue{ .none = {} };
@@ -2733,3 +2735,13 @@ fn parseRegName(name: []const u8) ?Register {
}
return std.meta.stringToEnum(Register, name);
}
+
+fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
+ const mod = self.bin_file.options.module.?;
+ 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);
+}
src/arch/sparc64/CodeGen.zig
@@ -490,13 +490,14 @@ fn gen(self: *Self) !void {
}
fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
+ const mod = self.bin_file.options.module.?;
+ const ip = &mod.intern_pool;
const air_tags = self.air.instructions.items(.tag);
for (body) |inst| {
// TODO: remove now-redundant isUnused calls from AIR handler functions
- if (self.liveness.isUnused(inst) and !self.air.mustLower(inst)) {
+ if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
continue;
- }
const old_air_bookkeeping = self.air_bookkeeping;
try self.ensureProcessDeathCapacity(Liveness.bpi);
@@ -678,6 +679,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.constant => unreachable, // excluded from function bodies
.const_ty => unreachable, // excluded from function bodies
+ .interned => unreachable, // excluded from function bodies
.unreach => self.finishAirBookkeeping(),
.optional_payload => try self.airOptionalPayload(inst),
@@ -762,8 +764,8 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const lhs = try self.resolveInst(extra.lhs);
const rhs = try self.resolveInst(extra.rhs);
- const lhs_ty = self.air.typeOf(extra.lhs);
- const rhs_ty = self.air.typeOf(extra.rhs);
+ const lhs_ty = self.typeOf(extra.lhs);
+ const rhs_ty = self.typeOf(extra.rhs);
switch (lhs_ty.zigTypeTag(mod)) {
.Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),
@@ -836,7 +838,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
}
fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
- const vector_ty = self.air.typeOfIndex(inst);
+ const vector_ty = self.typeOfIndex(inst);
const len = vector_ty.vectorLen();
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
@@ -871,7 +873,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
- const ptr_ty = self.air.typeOf(ty_op.operand);
+ const ptr_ty = self.typeOf(ty_op.operand);
const ptr = try self.resolveInst(ty_op.operand);
const array_ty = ptr_ty.childType();
const array_len = @intCast(u32, array_ty.arrayLen());
@@ -935,7 +937,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
const arg_mcv = try self.resolveInst(input);
try self.register_manager.getReg(reg, null);
- try self.genSetReg(self.air.typeOf(input), reg, arg_mcv);
+ try self.genSetReg(self.typeOf(input), reg, arg_mcv);
}
{
@@ -1008,16 +1010,16 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
}
fn airArg(self: *Self, inst: Air.Inst.Index) !void {
+ const mod = self.bin_file.options.module.?;
const arg_index = self.arg_index;
self.arg_index += 1;
- const ty = self.air.typeOfIndex(inst);
+ const ty = self.typeOfIndex(inst);
const arg = self.args[arg_index];
const mcv = blk: {
switch (arg) {
.stack_offset => |off| {
- const mod = self.bin_file.options.module.?;
const abi_size = math.cast(u32, ty.abiSize(mod)) orelse {
return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)});
};
@@ -1063,8 +1065,8 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
const result: MCValue = if (self.liveness.isUnused(inst))
.dead
else
@@ -1088,8 +1090,8 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
const result: MCValue = if (self.liveness.isUnused(inst))
.dead
else
@@ -1115,7 +1117,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);
const dest = try self.allocRegOrMem(inst, true);
- try self.setRegOrMem(self.air.typeOfIndex(inst), dest, operand);
+ try self.setRegOrMem(self.typeOfIndex(inst), dest, operand);
break :result dest;
};
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
@@ -1218,7 +1220,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
// TODO: Fold byteswap+store into a single ST*A and load+byteswap into a single LD*A.
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand = try self.resolveInst(ty_op.operand);
- const operand_ty = self.air.typeOf(ty_op.operand);
+ const operand_ty = self.typeOf(ty_op.operand);
switch (operand_ty.zigTypeTag(mod)) {
.Vector => return self.fail("TODO byteswap for vectors", .{}),
.Int => {
@@ -1294,7 +1296,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
const callee = pl_op.operand;
const extra = self.air.extraData(Air.Call, pl_op.payload);
const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end .. extra.end + extra.data.args_len]);
- const ty = self.air.typeOf(callee);
+ const ty = self.typeOf(callee);
const mod = self.bin_file.options.module.?;
const fn_ty = switch (ty.zigTypeTag(mod)) {
.Fn => ty,
@@ -1318,7 +1320,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
for (info.args, 0..) |mc_arg, arg_i| {
const arg = args[arg_i];
- const arg_ty = self.air.typeOf(arg);
+ const arg_ty = self.typeOf(arg);
const arg_mcv = try self.resolveInst(arg);
switch (mc_arg) {
@@ -1428,7 +1430,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const lhs_ty = self.air.typeOf(bin_op.lhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
const int_ty = switch (lhs_ty.zigTypeTag(mod)) {
.Vector => unreachable, // Handled by cmp_vector.
@@ -1605,7 +1607,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
log.debug("consolidating else_entry {d} {}=>{}", .{ else_key, else_value, canon_mcv });
// TODO make sure the destination stack offset / register does not already have something
// going on there.
- try self.setRegOrMem(self.air.typeOfIndex(else_key), canon_mcv, else_value);
+ try self.setRegOrMem(self.typeOfIndex(else_key), canon_mcv, else_value);
// TODO track the new register / stack allocation
}
try parent_branch.inst_table.ensureUnusedCapacity(self.gpa, saved_then_branch.inst_table.count());
@@ -1632,7 +1634,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
log.debug("consolidating then_entry {d} {}=>{}", .{ then_key, parent_mcv, then_value });
// TODO make sure the destination stack offset / register does not already have something
// going on there.
- try self.setRegOrMem(self.air.typeOfIndex(then_key), parent_mcv, then_value);
+ try self.setRegOrMem(self.typeOfIndex(then_key), parent_mcv, then_value);
// TODO track the new register / stack allocation
}
@@ -1755,10 +1757,10 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
const mod = self.bin_file.options.module.?;
- const operand_ty = self.air.typeOf(ty_op.operand);
+ const operand_ty = self.typeOf(ty_op.operand);
const operand = try self.resolveInst(ty_op.operand);
const info_a = operand_ty.intInfo(mod);
- const info_b = self.air.typeOfIndex(inst).intInfo(mod);
+ const info_b = self.typeOfIndex(inst).intInfo(mod);
if (info_a.signedness != info_b.signedness)
return self.fail("TODO gen intcast sign safety in semantic analysis", .{});
@@ -1780,7 +1782,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand = try self.resolveInst(un_op);
- const ty = self.air.typeOf(un_op);
+ const ty = self.typeOf(un_op);
break :result try self.isErr(ty, operand);
};
return self.finishAir(inst, result, .{ un_op, .none, .none });
@@ -1790,7 +1792,7 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand = try self.resolveInst(un_op);
- const ty = self.air.typeOf(un_op);
+ const ty = self.typeOf(un_op);
break :result try self.isNonErr(ty, operand);
};
return self.finishAir(inst, result, .{ un_op, .none, .none });
@@ -1815,16 +1817,16 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
}
fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
- const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const elem_ty = self.air.typeOfIndex(inst);
const mod = self.bin_file.options.module.?;
+ const ty_op = self.air.instructions.items(.data)[inst].ty_op;
+ const elem_ty = self.typeOfIndex(inst);
const elem_size = elem_ty.abiSize(mod);
const result: MCValue = result: {
if (!elem_ty.hasRuntimeBits(mod))
break :result MCValue.none;
const ptr = try self.resolveInst(ty_op.operand);
- const is_volatile = self.air.typeOf(ty_op.operand).isVolatilePtr();
+ const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr();
if (self.liveness.isUnused(inst) and !is_volatile)
break :result MCValue.dead;
@@ -1839,7 +1841,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
break :blk try self.allocRegOrMem(inst, true);
}
};
- try self.load(dst_mcv, ptr, self.air.typeOf(ty_op.operand));
+ try self.load(dst_mcv, ptr, self.typeOf(ty_op.operand));
break :result dst_mcv;
};
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
@@ -1882,8 +1884,8 @@ fn airMinMax(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
const result: MCValue = if (self.liveness.isUnused(inst))
.dead
@@ -1897,8 +1899,8 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
assert(lhs_ty.eql(rhs_ty, self.bin_file.options.module.?));
if (self.liveness.isUnused(inst))
@@ -2045,8 +2047,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const lhs = try self.resolveInst(extra.lhs);
const rhs = try self.resolveInst(extra.rhs);
- const lhs_ty = self.air.typeOf(extra.lhs);
- const rhs_ty = self.air.typeOf(extra.rhs);
+ const lhs_ty = self.typeOf(extra.lhs);
+ const rhs_ty = self.typeOf(extra.rhs);
switch (lhs_ty.zigTypeTag(mod)) {
.Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),
@@ -2108,7 +2110,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand = try self.resolveInst(ty_op.operand);
- const operand_ty = self.air.typeOf(ty_op.operand);
+ const operand_ty = self.typeOf(ty_op.operand);
switch (operand) {
.dead => unreachable,
.unreach => unreachable,
@@ -2285,8 +2287,8 @@ fn airRem(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
// TODO add safety check
@@ -2341,8 +2343,8 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const lhs = try self.resolveInst(extra.lhs);
const rhs = try self.resolveInst(extra.rhs);
- const lhs_ty = self.air.typeOf(extra.lhs);
- const rhs_ty = self.air.typeOf(extra.rhs);
+ const lhs_ty = self.typeOf(extra.lhs);
+ const rhs_ty = self.typeOf(extra.rhs);
switch (lhs_ty.zigTypeTag(mod)) {
.Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),
@@ -2429,9 +2431,9 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const ptr = try self.resolveInst(bin_op.lhs);
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const len = try self.resolveInst(bin_op.rhs);
- const len_ty = self.air.typeOf(bin_op.rhs);
+ const len_ty = self.typeOf(bin_op.rhs);
const ptr_bits = self.target.ptrBitWidth();
const ptr_bytes = @divExact(ptr_bits, 8);
@@ -2453,7 +2455,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
const slice_mcv = try self.resolveInst(bin_op.lhs);
const index_mcv = try self.resolveInst(bin_op.rhs);
- const slice_ty = self.air.typeOf(bin_op.lhs);
+ const slice_ty = self.typeOf(bin_op.lhs);
const elem_ty = slice_ty.childType();
const mod = self.bin_file.options.module.?;
const elem_size = elem_ty.abiSize(mod);
@@ -2544,8 +2546,8 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const ptr = try self.resolveInst(bin_op.lhs);
const value = try self.resolveInst(bin_op.rhs);
- const ptr_ty = self.air.typeOf(bin_op.lhs);
- const value_ty = self.air.typeOf(bin_op.rhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
+ const value_ty = self.typeOf(bin_op.rhs);
try self.store(ptr, value, ptr_ty, value_ty);
@@ -2573,7 +2575,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const mod = self.bin_file.options.module.?;
const mcv = try self.resolveInst(operand);
- const struct_ty = self.air.typeOf(operand);
+ const struct_ty = self.typeOf(operand);
const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
switch (mcv) {
@@ -2659,8 +2661,8 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand = try self.resolveInst(ty_op.operand);
- const operand_ty = self.air.typeOf(ty_op.operand);
- const dest_ty = self.air.typeOfIndex(inst);
+ const operand_ty = self.typeOf(ty_op.operand);
+ const dest_ty = self.typeOfIndex(inst);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {
break :blk try self.trunc(inst, operand, operand_ty, dest_ty);
@@ -2674,7 +2676,7 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {
const extra = self.air.extraData(Air.Try, pl_op.payload);
const body = self.air.extra[extra.end..][0..extra.data.body_len];
const result: MCValue = result: {
- const error_union_ty = self.air.typeOf(pl_op.operand);
+ const error_union_ty = self.typeOf(pl_op.operand);
const error_union = try self.resolveInst(pl_op.operand);
const is_err_result = try self.isErr(error_union_ty, error_union);
const reloc = try self.condBr(is_err_result);
@@ -2706,7 +2708,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
- const error_union_ty = self.air.typeOf(ty_op.operand);
+ const error_union_ty = self.typeOf(ty_op.operand);
const payload_ty = error_union_ty.errorUnionPayload();
const mcv = try self.resolveInst(ty_op.operand);
const mod = self.bin_file.options.module.?;
@@ -2720,7 +2722,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
- const error_union_ty = self.air.typeOf(ty_op.operand);
+ const error_union_ty = self.typeOf(ty_op.operand);
const payload_ty = error_union_ty.errorUnionPayload();
const mod = self.bin_file.options.module.?;
if (!payload_ty.hasRuntimeBits(mod)) break :result MCValue.none;
@@ -2753,12 +2755,12 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
}
fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
+ const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
- const optional_ty = self.air.typeOfIndex(inst);
+ const optional_ty = self.typeOfIndex(inst);
// Optional with a zero-bit payload type is just a boolean true
- const mod = self.bin_file.options.module.?;
if (optional_ty.abiSize(mod) == 1)
break :result MCValue{ .immediate = 1 };
@@ -2794,9 +2796,9 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u
/// Use a pointer instruction as the basis for allocating stack memory.
fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
- const elem_ty = self.air.typeOfIndex(inst).elemType();
-
const mod = self.bin_file.options.module.?;
+ const elem_ty = self.typeOfIndex(inst).elemType();
+
if (!elem_ty.hasRuntimeBits(mod)) {
// As this stack item will never be dereferenced at runtime,
// return the stack offset 0. Stack offset 0 will be where all
@@ -2814,8 +2816,8 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
}
fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
- const elem_ty = self.air.typeOfIndex(inst);
const mod = self.bin_file.options.module.?;
+ const elem_ty = self.typeOfIndex(inst);
const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
};
@@ -3406,7 +3408,7 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
const block_data = self.blocks.getPtr(block).?;
const mod = self.bin_file.options.module.?;
- if (self.air.typeOf(operand).hasRuntimeBits(mod)) {
+ if (self.typeOf(operand).hasRuntimeBits(mod)) {
const operand_mcv = try self.resolveInst(operand);
const block_mcv = block_data.mcv;
if (block_mcv == .none) {
@@ -3415,13 +3417,13 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
.register, .stack_offset, .memory => operand_mcv,
.immediate => blk: {
const new_mcv = try self.allocRegOrMem(block, true);
- try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, operand_mcv);
+ try self.setRegOrMem(self.typeOfIndex(block), new_mcv, operand_mcv);
break :blk new_mcv;
},
else => return self.fail("TODO implement block_data.mcv = operand_mcv for {}", .{operand_mcv}),
};
} else {
- try self.setRegOrMem(self.air.typeOfIndex(block), block_mcv, operand_mcv);
+ try self.setRegOrMem(self.typeOfIndex(block), block_mcv, operand_mcv);
}
}
return self.brVoid(block);
@@ -4549,7 +4551,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)
fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
const mod = self.bin_file.options.module.?;
- const ty = self.air.typeOf(ref);
+ const ty = self.typeOf(ref);
// If the type has no codegen bits, no need to store it.
if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;
@@ -4654,7 +4656,7 @@ fn spillConditionFlagsIfOccupied(self: *Self) !void {
else => unreachable, // mcv doesn't occupy the compare flags
};
- try self.setRegOrMem(self.air.typeOfIndex(inst_to_save), new_mcv, mcv);
+ try self.setRegOrMem(self.typeOfIndex(inst_to_save), new_mcv, mcv);
log.debug("spilling {d} to mcv {any}", .{ inst_to_save, new_mcv });
const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
@@ -4678,7 +4680,7 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void
assert(reg == reg_mcv.register);
const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
try branch.inst_table.put(self.gpa, inst, stack_mcv);
- try self.genSetStack(self.air.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);
+ try self.genSetStack(self.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);
}
fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {
@@ -4726,7 +4728,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
return if (self.liveness.isUnused(inst)) .dead else result: {
const mod = self.bin_file.options.module.?;
const mcv = try self.resolveInst(operand);
- const ptr_ty = self.air.typeOf(operand);
+ const ptr_ty = self.typeOf(operand);
const struct_ty = ptr_ty.childType();
const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
switch (mcv) {
@@ -4885,3 +4887,13 @@ fn wantSafety(self: *Self) bool {
.ReleaseSmall => false,
};
}
+
+fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
+ const mod = self.bin_file.options.module.?;
+ 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);
+}
src/arch/wasm/CodeGen.zig
@@ -790,7 +790,7 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
const mod = func.bin_file.base.options.module.?;
const val = func.air.value(ref, mod).?;
- const ty = func.air.typeOf(ref);
+ const ty = func.typeOf(ref);
if (!ty.hasRuntimeBitsIgnoreComptime(mod) and !ty.isInt(mod) and !ty.isError(mod)) {
gop.value_ptr.* = WValue{ .none = {} };
return gop.value_ptr.*;
@@ -1260,7 +1260,7 @@ fn genFunc(func: *CodeGen) InnerError!void {
// we emit an unreachable instruction to tell the stack validator that part will never be reached.
if (func_type.returns.len != 0 and func.air.instructions.len > 0) {
const inst = @intCast(u32, func.air.instructions.len - 1);
- const last_inst_ty = func.air.typeOfIndex(inst);
+ const last_inst_ty = func.typeOfIndex(inst);
if (!last_inst_ty.hasRuntimeBitsIgnoreComptime(mod) or last_inst_ty.isNoReturn()) {
try func.addTag(.@"unreachable");
}
@@ -1541,7 +1541,7 @@ fn allocStack(func: *CodeGen, ty: Type) !WValue {
/// if it is set, to ensure the stack alignment will be set correctly.
fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue {
const mod = func.bin_file.base.options.module.?;
- const ptr_ty = func.air.typeOfIndex(inst);
+ const ptr_ty = func.typeOfIndex(inst);
const pointee_ty = ptr_ty.childType();
if (func.initial_stack_value == .none) {
@@ -1834,6 +1834,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
return switch (air_tags[inst]) {
.constant => unreachable,
.const_ty => unreachable,
+ .interned => unreachable,
.add => func.airBinOp(inst, .add),
.add_sat => func.airSatBinOp(inst, .add),
@@ -2073,8 +2074,11 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
+ const mod = func.bin_file.base.options.module.?;
+ const ip = &mod.intern_pool;
+
for (body) |inst| {
- if (func.liveness.isUnused(inst) and !func.air.mustLower(inst)) {
+ if (func.liveness.isUnused(inst) and !func.air.mustLower(inst, ip.*)) {
continue;
}
const old_bookkeeping_value = func.air_bookkeeping;
@@ -2134,8 +2138,8 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
- const child_type = func.air.typeOfIndex(inst).childType();
const mod = func.bin_file.base.options.module.?;
+ const child_type = func.typeOfIndex(inst).childType();
var result = result: {
if (!child_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
@@ -2157,7 +2161,7 @@ fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const un_op = func.air.instructions.items(.data)[inst].un_op;
const operand = try func.resolveInst(un_op);
- const ret_ty = func.air.typeOf(un_op).childType();
+ const ret_ty = func.typeOf(un_op).childType();
const fn_info = func.decl.ty.fnInfo();
if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
@@ -2179,7 +2183,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
const extra = func.air.extraData(Air.Call, pl_op.payload);
const args = @ptrCast([]const Air.Inst.Ref, func.air.extra[extra.end..][0..extra.data.args_len]);
- const ty = func.air.typeOf(pl_op.operand);
+ const ty = func.typeOf(pl_op.operand);
const mod = func.bin_file.base.options.module.?;
const fn_ty = switch (ty.zigTypeTag(mod)) {
@@ -2228,7 +2232,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
for (args) |arg| {
const arg_val = try func.resolveInst(arg);
- const arg_ty = func.air.typeOf(arg);
+ const arg_ty = func.typeOf(arg);
if (!arg_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
try func.lowerArg(fn_ty.fnInfo().cc, arg_ty, arg_val);
@@ -2296,7 +2300,7 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
const lhs = try func.resolveInst(bin_op.lhs);
const rhs = try func.resolveInst(bin_op.rhs);
- const ptr_ty = func.air.typeOf(bin_op.lhs);
+ const ptr_ty = func.typeOf(bin_op.lhs);
const ptr_info = ptr_ty.ptrInfo().data;
const ty = ptr_ty.childType();
@@ -2449,7 +2453,7 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const operand = try func.resolveInst(ty_op.operand);
const ty = func.air.getRefType(ty_op.ty);
- const ptr_ty = func.air.typeOf(ty_op.operand);
+ const ptr_ty = func.typeOf(ty_op.operand);
const ptr_info = ptr_ty.ptrInfo().data;
if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return func.finishAir(inst, .none, &.{ty_op.operand});
@@ -2522,11 +2526,11 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu
}
fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
+ const mod = func.bin_file.base.options.module.?;
const arg_index = func.arg_index;
const arg = func.args[arg_index];
const cc = func.decl.ty.fnInfo().cc;
- const arg_ty = func.air.typeOfIndex(inst);
- const mod = func.bin_file.base.options.module.?;
+ const arg_ty = func.typeOfIndex(inst);
if (cc == .C) {
const arg_classes = abi.classifyType(arg_ty, mod);
for (arg_classes) |class| {
@@ -2572,8 +2576,8 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const lhs = try func.resolveInst(bin_op.lhs);
const rhs = try func.resolveInst(bin_op.rhs);
- const lhs_ty = func.air.typeOf(bin_op.lhs);
- const rhs_ty = func.air.typeOf(bin_op.rhs);
+ const lhs_ty = func.typeOf(bin_op.lhs);
+ const rhs_ty = func.typeOf(bin_op.rhs);
// For certain operations, such as shifting, the types are different.
// When converting this to a WebAssembly type, they *must* match to perform
@@ -2770,7 +2774,7 @@ const FloatOp = enum {
fn airUnaryFloatOp(func: *CodeGen, inst: Air.Inst.Index, op: FloatOp) InnerError!void {
const un_op = func.air.instructions.items(.data)[inst].un_op;
const operand = try func.resolveInst(un_op);
- const ty = func.air.typeOf(un_op);
+ const ty = func.typeOf(un_op);
const result = try (try func.floatOp(op, ty, &.{operand})).toLocal(func, ty);
func.finishAir(inst, result, &.{un_op});
@@ -2847,8 +2851,8 @@ fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
const lhs = try func.resolveInst(bin_op.lhs);
const rhs = try func.resolveInst(bin_op.rhs);
- const lhs_ty = func.air.typeOf(bin_op.lhs);
- const rhs_ty = func.air.typeOf(bin_op.rhs);
+ const lhs_ty = func.typeOf(bin_op.lhs);
+ const rhs_ty = func.typeOf(bin_op.rhs);
if (lhs_ty.zigTypeTag(mod) == .Vector or rhs_ty.zigTypeTag(mod) == .Vector) {
return func.fail("TODO: Implement wrapping arithmetic for vectors", .{});
@@ -3387,7 +3391,7 @@ fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) In
const lhs = try func.resolveInst(bin_op.lhs);
const rhs = try func.resolveInst(bin_op.rhs);
- const operand_ty = func.air.typeOf(bin_op.lhs);
+ const operand_ty = func.typeOf(bin_op.lhs);
const result = try (try func.cmp(lhs, rhs, operand_ty, op)).toLocal(func, Type.u32); // comparison result is always 32 bits
func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
}
@@ -3488,7 +3492,7 @@ fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const block = func.blocks.get(br.block_inst).?;
// if operand has codegen bits we should break with a value
- if (func.air.typeOf(br.operand).hasRuntimeBitsIgnoreComptime(mod)) {
+ if (func.typeOf(br.operand).hasRuntimeBitsIgnoreComptime(mod)) {
const operand = try func.resolveInst(br.operand);
try func.lowerToStack(operand);
@@ -3509,7 +3513,7 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const operand = try func.resolveInst(ty_op.operand);
- const operand_ty = func.air.typeOf(ty_op.operand);
+ const operand_ty = func.typeOf(ty_op.operand);
const mod = func.bin_file.base.options.module.?;
const result = result: {
@@ -3575,8 +3579,8 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const result = result: {
const operand = try func.resolveInst(ty_op.operand);
- const wanted_ty = func.air.typeOfIndex(inst);
- const given_ty = func.air.typeOf(ty_op.operand);
+ const wanted_ty = func.typeOfIndex(inst);
+ const given_ty = func.typeOf(ty_op.operand);
if (given_ty.isAnyFloat() or wanted_ty.isAnyFloat()) {
const bitcast_result = try func.bitcast(wanted_ty, given_ty, operand);
break :result try bitcast_result.toLocal(func, wanted_ty);
@@ -3609,7 +3613,7 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const extra = func.air.extraData(Air.StructField, ty_pl.payload);
const struct_ptr = try func.resolveInst(extra.data.struct_operand);
- const struct_ty = func.air.typeOf(extra.data.struct_operand).childType();
+ const struct_ty = func.typeOf(extra.data.struct_operand).childType();
const result = try func.structFieldPtr(inst, extra.data.struct_operand, struct_ptr, struct_ty, extra.data.field_index);
func.finishAir(inst, result, &.{extra.data.struct_operand});
}
@@ -3617,7 +3621,7 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const struct_ptr = try func.resolveInst(ty_op.operand);
- const struct_ty = func.air.typeOf(ty_op.operand).childType();
+ const struct_ty = func.typeOf(ty_op.operand).childType();
const result = try func.structFieldPtr(inst, ty_op.operand, struct_ptr, struct_ty, index);
func.finishAir(inst, result, &.{ty_op.operand});
@@ -3632,7 +3636,7 @@ fn structFieldPtr(
index: u32,
) InnerError!WValue {
const mod = func.bin_file.base.options.module.?;
- const result_ty = func.air.typeOfIndex(inst);
+ const result_ty = func.typeOfIndex(inst);
const offset = switch (struct_ty.containerLayout()) {
.Packed => switch (struct_ty.zigTypeTag(mod)) {
.Struct => offset: {
@@ -3663,7 +3667,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const struct_field = func.air.extraData(Air.StructField, ty_pl.payload).data;
- const struct_ty = func.air.typeOf(struct_field.struct_operand);
+ const struct_ty = func.typeOf(struct_field.struct_operand);
const operand = try func.resolveInst(struct_field.struct_operand);
const field_index = struct_field.field_index;
const field_ty = struct_ty.structFieldType(field_index);
@@ -3762,7 +3766,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const blocktype = wasm.block_empty;
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
const target = try func.resolveInst(pl_op.operand);
- const target_ty = func.air.typeOf(pl_op.operand);
+ const target_ty = func.typeOf(pl_op.operand);
const switch_br = func.air.extraData(Air.SwitchBr, pl_op.payload);
const liveness = try func.liveness.getSwitchBr(func.gpa, inst, switch_br.data.cases_len + 1);
defer func.gpa.free(liveness.deaths);
@@ -3940,7 +3944,7 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro
const mod = func.bin_file.base.options.module.?;
const un_op = func.air.instructions.items(.data)[inst].un_op;
const operand = try func.resolveInst(un_op);
- const err_union_ty = func.air.typeOf(un_op);
+ const err_union_ty = func.typeOf(un_op);
const pl_ty = err_union_ty.errorUnionPayload();
const result = result: {
@@ -3976,7 +3980,7 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const operand = try func.resolveInst(ty_op.operand);
- const op_ty = func.air.typeOf(ty_op.operand);
+ const op_ty = func.typeOf(ty_op.operand);
const err_ty = if (op_is_ptr) op_ty.childType() else op_ty;
const payload_ty = err_ty.errorUnionPayload();
@@ -4004,7 +4008,7 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const operand = try func.resolveInst(ty_op.operand);
- const op_ty = func.air.typeOf(ty_op.operand);
+ const op_ty = func.typeOf(ty_op.operand);
const err_ty = if (op_is_ptr) op_ty.childType() else op_ty;
const payload_ty = err_ty.errorUnionPayload();
@@ -4028,9 +4032,9 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const operand = try func.resolveInst(ty_op.operand);
- const err_ty = func.air.typeOfIndex(inst);
+ const err_ty = func.typeOfIndex(inst);
- const pl_ty = func.air.typeOf(ty_op.operand);
+ const pl_ty = func.typeOf(ty_op.operand);
const result = result: {
if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
break :result func.reuseOperand(ty_op.operand, operand);
@@ -4082,7 +4086,7 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty = func.air.getRefType(ty_op.ty);
const operand = try func.resolveInst(ty_op.operand);
- const operand_ty = func.air.typeOf(ty_op.operand);
+ const operand_ty = func.typeOf(ty_op.operand);
const mod = func.bin_file.base.options.module.?;
if (ty.zigTypeTag(mod) == .Vector or operand_ty.zigTypeTag(mod) == .Vector) {
return func.fail("todo Wasm intcast for vectors", .{});
@@ -4155,7 +4159,7 @@ fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind:
const un_op = func.air.instructions.items(.data)[inst].un_op;
const operand = try func.resolveInst(un_op);
- const op_ty = func.air.typeOf(un_op);
+ const op_ty = func.typeOf(un_op);
const optional_ty = if (op_kind == .ptr) op_ty.childType() else op_ty;
const is_null = try func.isNull(operand, optional_ty, opcode);
const result = try is_null.toLocal(func, optional_ty);
@@ -4196,8 +4200,8 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod
fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
- const opt_ty = func.air.typeOf(ty_op.operand);
- const payload_ty = func.air.typeOfIndex(inst);
+ const opt_ty = func.typeOf(ty_op.operand);
+ const payload_ty = func.typeOfIndex(inst);
if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
return func.finishAir(inst, .none, &.{ty_op.operand});
}
@@ -4219,7 +4223,7 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const operand = try func.resolveInst(ty_op.operand);
- const opt_ty = func.air.typeOf(ty_op.operand).childType();
+ const opt_ty = func.typeOf(ty_op.operand).childType();
const mod = func.bin_file.base.options.module.?;
const result = result: {
@@ -4238,7 +4242,7 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const operand = try func.resolveInst(ty_op.operand);
- const opt_ty = func.air.typeOf(ty_op.operand).childType();
+ const opt_ty = func.typeOf(ty_op.operand).childType();
var buf: Type.Payload.ElemType = undefined;
const payload_ty = opt_ty.optionalChild(&buf);
if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
@@ -4263,7 +4267,7 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
- const payload_ty = func.air.typeOf(ty_op.operand);
+ const payload_ty = func.typeOf(ty_op.operand);
const mod = func.bin_file.base.options.module.?;
const result = result: {
@@ -4276,7 +4280,7 @@ fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
const operand = try func.resolveInst(ty_op.operand);
- const op_ty = func.air.typeOfIndex(inst);
+ const op_ty = func.typeOfIndex(inst);
if (op_ty.optionalReprIsPayload(mod)) {
break :result func.reuseOperand(ty_op.operand, operand);
}
@@ -4304,7 +4308,7 @@ fn airSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const lhs = try func.resolveInst(bin_op.lhs);
const rhs = try func.resolveInst(bin_op.rhs);
- const slice_ty = func.air.typeOfIndex(inst);
+ const slice_ty = func.typeOfIndex(inst);
const slice = try func.allocStack(slice_ty);
try func.store(slice, lhs, Type.usize, 0);
@@ -4323,7 +4327,7 @@ fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
- const slice_ty = func.air.typeOf(bin_op.lhs);
+ const slice_ty = func.typeOf(bin_op.lhs);
const slice = try func.resolveInst(bin_op.lhs);
const index = try func.resolveInst(bin_op.rhs);
const elem_ty = slice_ty.childType();
@@ -4395,7 +4399,7 @@ fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const operand = try func.resolveInst(ty_op.operand);
const wanted_ty = func.air.getRefType(ty_op.ty);
- const op_ty = func.air.typeOf(ty_op.operand);
+ const op_ty = func.typeOf(ty_op.operand);
const result = try func.trunc(operand, wanted_ty, op_ty);
func.finishAir(inst, try result.toLocal(func, wanted_ty), &.{ty_op.operand});
@@ -4432,7 +4436,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const operand = try func.resolveInst(ty_op.operand);
- const array_ty = func.air.typeOf(ty_op.operand).childType();
+ const array_ty = func.typeOf(ty_op.operand).childType();
const slice_ty = func.air.getRefType(ty_op.ty);
// create a slice on the stack
@@ -4453,7 +4457,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airPtrToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const un_op = func.air.instructions.items(.data)[inst].un_op;
const operand = try func.resolveInst(un_op);
- const ptr_ty = func.air.typeOf(un_op);
+ const ptr_ty = func.typeOf(un_op);
const result = if (ptr_ty.isSlice())
try func.slicePtr(operand)
else switch (operand) {
@@ -4467,7 +4471,7 @@ fn airPtrToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
- const ptr_ty = func.air.typeOf(bin_op.lhs);
+ const ptr_ty = func.typeOf(bin_op.lhs);
const ptr = try func.resolveInst(bin_op.lhs);
const index = try func.resolveInst(bin_op.rhs);
const elem_ty = ptr_ty.childType();
@@ -4505,7 +4509,7 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;
- const ptr_ty = func.air.typeOf(bin_op.lhs);
+ const ptr_ty = func.typeOf(bin_op.lhs);
const elem_ty = func.air.getRefType(ty_pl.ty).childType();
const mod = func.bin_file.base.options.module.?;
const elem_size = elem_ty.abiSize(mod);
@@ -4538,7 +4542,7 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
const ptr = try func.resolveInst(bin_op.lhs);
const offset = try func.resolveInst(bin_op.rhs);
- const ptr_ty = func.air.typeOf(bin_op.lhs);
+ const ptr_ty = func.typeOf(bin_op.lhs);
const pointee_ty = switch (ptr_ty.ptrSize()) {
.One => ptr_ty.childType().childType(), // ptr to array, so get array element type
else => ptr_ty.childType(),
@@ -4568,7 +4572,7 @@ fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const ptr = try func.resolveInst(bin_op.lhs);
- const ptr_ty = func.air.typeOf(bin_op.lhs);
+ const ptr_ty = func.typeOf(bin_op.lhs);
const value = try func.resolveInst(bin_op.rhs);
const len = switch (ptr_ty.ptrSize()) {
.Slice => try func.sliceLen(ptr),
@@ -4683,7 +4687,7 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue
fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
- const array_ty = func.air.typeOf(bin_op.lhs);
+ const array_ty = func.typeOf(bin_op.lhs);
const array = try func.resolveInst(bin_op.lhs);
const index = try func.resolveInst(bin_op.rhs);
const elem_ty = array_ty.childType();
@@ -4750,12 +4754,12 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airFloatToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
+ const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const operand = try func.resolveInst(ty_op.operand);
- const dest_ty = func.air.typeOfIndex(inst);
- const op_ty = func.air.typeOf(ty_op.operand);
- const mod = func.bin_file.base.options.module.?;
+ const dest_ty = func.typeOfIndex(inst);
+ const op_ty = func.typeOf(ty_op.operand);
if (op_ty.abiSize(mod) > 8) {
return func.fail("TODO: floatToInt for integers/floats with bitsize larger than 64 bits", .{});
@@ -4775,12 +4779,12 @@ fn airFloatToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airIntToFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
+ const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const operand = try func.resolveInst(ty_op.operand);
- const dest_ty = func.air.typeOfIndex(inst);
- const op_ty = func.air.typeOf(ty_op.operand);
- const mod = func.bin_file.base.options.module.?;
+ const dest_ty = func.typeOfIndex(inst);
+ const op_ty = func.typeOf(ty_op.operand);
if (op_ty.abiSize(mod) > 8) {
return func.fail("TODO: intToFloat for integers/floats with bitsize larger than 64 bits", .{});
@@ -4804,7 +4808,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const operand = try func.resolveInst(ty_op.operand);
- const ty = func.air.typeOfIndex(inst);
+ const ty = func.typeOfIndex(inst);
const elem_ty = ty.childType();
if (determineSimdStoreStrategy(ty, mod) == .direct) blk: {
@@ -4881,7 +4885,7 @@ fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
- const inst_ty = func.air.typeOfIndex(inst);
+ const inst_ty = func.typeOfIndex(inst);
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const extra = func.air.extraData(Air.Shuffle, ty_pl.payload).data;
@@ -4894,7 +4898,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const elem_size = child_ty.abiSize(mod);
// TODO: One of them could be by ref; handle in loop
- if (isByRef(func.air.typeOf(extra.a), mod) or isByRef(inst_ty, mod)) {
+ if (isByRef(func.typeOf(extra.a), mod) or isByRef(inst_ty, mod)) {
const result = try func.allocStack(inst_ty);
for (0..mask_len) |index| {
@@ -4951,11 +4955,11 @@ fn airReduce(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
+ const mod = func.bin_file.base.options.module.?;
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
- const result_ty = func.air.typeOfIndex(inst);
+ const result_ty = func.typeOfIndex(inst);
const len = @intCast(usize, result_ty.arrayLen());
const elements = @ptrCast([]const Air.Inst.Ref, func.air.extra[ty_pl.payload..][0..len]);
- const mod = func.bin_file.base.options.module.?;
const result: WValue = result_value: {
switch (result_ty.zigTypeTag(mod)) {
@@ -5085,7 +5089,7 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const extra = func.air.extraData(Air.UnionInit, ty_pl.payload).data;
const result = result: {
- const union_ty = func.air.typeOfIndex(inst);
+ const union_ty = func.typeOfIndex(inst);
const layout = union_ty.unionGetLayout(mod);
const union_obj = union_ty.cast(Type.Payload.Union).?.data;
const field = union_obj.fields.values()[extra.field_index];
@@ -5164,7 +5168,7 @@ fn airPrefetch(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airWasmMemorySize(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
- const result = try func.allocLocal(func.air.typeOfIndex(inst));
+ const result = try func.allocLocal(func.typeOfIndex(inst));
try func.addLabel(.memory_size, pl_op.payload);
try func.addLabel(.local_set, result.local.value);
func.finishAir(inst, result, &.{pl_op.operand});
@@ -5174,7 +5178,7 @@ fn airWasmMemoryGrow(func: *CodeGen, inst: Air.Inst.Index) !void {
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
const operand = try func.resolveInst(pl_op.operand);
- const result = try func.allocLocal(func.air.typeOfIndex(inst));
+ const result = try func.allocLocal(func.typeOfIndex(inst));
try func.emitWValue(operand);
try func.addLabel(.memory_grow, pl_op.payload);
try func.addLabel(.local_set, result.local.value);
@@ -5263,8 +5267,8 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std
fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
- const un_ty = func.air.typeOf(bin_op.lhs).childType();
- const tag_ty = func.air.typeOf(bin_op.rhs);
+ const un_ty = func.typeOf(bin_op.lhs).childType();
+ const tag_ty = func.typeOf(bin_op.rhs);
const layout = un_ty.unionGetLayout(mod);
if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
@@ -5288,8 +5292,8 @@ fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
- const un_ty = func.air.typeOf(ty_op.operand);
- const tag_ty = func.air.typeOfIndex(inst);
+ const un_ty = func.typeOf(ty_op.operand);
+ const tag_ty = func.typeOfIndex(inst);
const layout = un_ty.unionGetLayout(mod);
if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ty_op.operand});
@@ -5307,9 +5311,9 @@ fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airFpext(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
- const dest_ty = func.air.typeOfIndex(inst);
+ const dest_ty = func.typeOfIndex(inst);
const operand = try func.resolveInst(ty_op.operand);
- const extended = try func.fpext(operand, func.air.typeOf(ty_op.operand), dest_ty);
+ const extended = try func.fpext(operand, func.typeOf(ty_op.operand), dest_ty);
const result = try extended.toLocal(func, dest_ty);
func.finishAir(inst, result, &.{ty_op.operand});
}
@@ -5352,9 +5356,9 @@ fn fpext(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!
fn airFptrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
- const dest_ty = func.air.typeOfIndex(inst);
+ const dest_ty = func.typeOfIndex(inst);
const operand = try func.resolveInst(ty_op.operand);
- const truncated = try func.fptrunc(operand, func.air.typeOf(ty_op.operand), dest_ty);
+ const truncated = try func.fptrunc(operand, func.typeOf(ty_op.operand), dest_ty);
const result = try truncated.toLocal(func, dest_ty);
func.finishAir(inst, result, &.{ty_op.operand});
}
@@ -5393,7 +5397,7 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
- const err_set_ty = func.air.typeOf(ty_op.operand).childType();
+ const err_set_ty = func.typeOf(ty_op.operand).childType();
const payload_ty = err_set_ty.errorUnionPayload();
const operand = try func.resolveInst(ty_op.operand);
@@ -5448,10 +5452,10 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const dst = try func.resolveInst(bin_op.lhs);
- const dst_ty = func.air.typeOf(bin_op.lhs);
+ const dst_ty = func.typeOf(bin_op.lhs);
const ptr_elem_ty = dst_ty.childType();
const src = try func.resolveInst(bin_op.rhs);
- const src_ty = func.air.typeOf(bin_op.rhs);
+ const src_ty = func.typeOf(bin_op.rhs);
const len = switch (dst_ty.ptrSize()) {
.Slice => blk: {
const slice_len = try func.sliceLen(dst);
@@ -5485,12 +5489,12 @@ fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
+ const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const operand = try func.resolveInst(ty_op.operand);
- const op_ty = func.air.typeOf(ty_op.operand);
- const result_ty = func.air.typeOfIndex(inst);
- const mod = func.bin_file.base.options.module.?;
+ const op_ty = func.typeOf(ty_op.operand);
+ const result_ty = func.typeOfIndex(inst);
if (op_ty.zigTypeTag(mod) == .Vector) {
return func.fail("TODO: Implement @popCount for vectors", .{});
@@ -5585,7 +5589,7 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
const lhs_op = try func.resolveInst(extra.lhs);
const rhs_op = try func.resolveInst(extra.rhs);
- const lhs_ty = func.air.typeOf(extra.lhs);
+ const lhs_ty = func.typeOf(extra.lhs);
const mod = func.bin_file.base.options.module.?;
if (lhs_ty.zigTypeTag(mod) == .Vector) {
@@ -5599,7 +5603,7 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
};
if (wasm_bits == 128) {
- const result = try func.addSubWithOverflowBigInt(lhs_op, rhs_op, lhs_ty, func.air.typeOfIndex(inst), op);
+ const result = try func.addSubWithOverflowBigInt(lhs_op, rhs_op, lhs_ty, func.typeOfIndex(inst), op);
return func.finishAir(inst, result, &.{ extra.lhs, extra.rhs });
}
@@ -5649,7 +5653,7 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
var overflow_local = try overflow_bit.toLocal(func, Type.u32);
defer overflow_local.free(func);
- const result_ptr = try func.allocStack(func.air.typeOfIndex(inst));
+ const result_ptr = try func.allocStack(func.typeOfIndex(inst));
try func.store(result_ptr, result, lhs_ty, 0);
const offset = @intCast(u32, lhs_ty.abiSize(mod));
try func.store(result_ptr, overflow_local, Type.initTag(.u1), offset);
@@ -5729,8 +5733,8 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const lhs = try func.resolveInst(extra.lhs);
const rhs = try func.resolveInst(extra.rhs);
- const lhs_ty = func.air.typeOf(extra.lhs);
- const rhs_ty = func.air.typeOf(extra.rhs);
+ const lhs_ty = func.typeOf(extra.lhs);
+ const rhs_ty = func.typeOf(extra.rhs);
if (lhs_ty.zigTypeTag(mod) == .Vector) {
return func.fail("TODO: Implement overflow arithmetic for vectors", .{});
@@ -5771,7 +5775,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
var overflow_local = try overflow_bit.toLocal(func, Type.initTag(.u1));
defer overflow_local.free(func);
- const result_ptr = try func.allocStack(func.air.typeOfIndex(inst));
+ const result_ptr = try func.allocStack(func.typeOfIndex(inst));
try func.store(result_ptr, result, lhs_ty, 0);
const offset = @intCast(u32, lhs_ty.abiSize(mod));
try func.store(result_ptr, overflow_local, Type.initTag(.u1), offset);
@@ -5785,7 +5789,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const lhs = try func.resolveInst(extra.lhs);
const rhs = try func.resolveInst(extra.rhs);
- const lhs_ty = func.air.typeOf(extra.lhs);
+ const lhs_ty = func.typeOf(extra.lhs);
const mod = func.bin_file.base.options.module.?;
if (lhs_ty.zigTypeTag(mod) == .Vector) {
@@ -5946,7 +5950,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
var bin_op_local = try bin_op.toLocal(func, lhs_ty);
defer bin_op_local.free(func);
- const result_ptr = try func.allocStack(func.air.typeOfIndex(inst));
+ const result_ptr = try func.allocStack(func.typeOfIndex(inst));
try func.store(result_ptr, bin_op_local, lhs_ty, 0);
const offset = @intCast(u32, lhs_ty.abiSize(mod));
try func.store(result_ptr, overflow_bit, Type.initTag(.u1), offset);
@@ -5955,10 +5959,10 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: enum { max, min }) InnerError!void {
+ const mod = func.bin_file.base.options.module.?;
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
- const ty = func.air.typeOfIndex(inst);
- const mod = func.bin_file.base.options.module.?;
+ const ty = func.typeOfIndex(inst);
if (ty.zigTypeTag(mod) == .Vector) {
return func.fail("TODO: `@maximum` and `@minimum` for vectors", .{});
}
@@ -5986,11 +5990,11 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: enum { max, min }) InnerE
}
fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
+ const mod = func.bin_file.base.options.module.?;
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data;
- const ty = func.air.typeOfIndex(inst);
- const mod = func.bin_file.base.options.module.?;
+ const ty = func.typeOfIndex(inst);
if (ty.zigTypeTag(mod) == .Vector) {
return func.fail("TODO: `@mulAdd` for vectors", .{});
}
@@ -6020,11 +6024,11 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
+ const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
- const ty = func.air.typeOf(ty_op.operand);
- const result_ty = func.air.typeOfIndex(inst);
- const mod = func.bin_file.base.options.module.?;
+ const ty = func.typeOf(ty_op.operand);
+ const result_ty = func.typeOfIndex(inst);
if (ty.zigTypeTag(mod) == .Vector) {
return func.fail("TODO: `@clz` for vectors", .{});
}
@@ -6073,12 +6077,12 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
+ const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
- const ty = func.air.typeOf(ty_op.operand);
- const result_ty = func.air.typeOfIndex(inst);
+ const ty = func.typeOf(ty_op.operand);
+ const result_ty = func.typeOfIndex(inst);
- const mod = func.bin_file.base.options.module.?;
if (ty.zigTypeTag(mod) == .Vector) {
return func.fail("TODO: `@ctz` for vectors", .{});
}
@@ -6141,7 +6145,7 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void {
if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
- const ty = func.air.typeOf(pl_op.operand);
+ const ty = func.typeOf(pl_op.operand);
const operand = try func.resolveInst(pl_op.operand);
log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), operand });
@@ -6179,7 +6183,7 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const err_union = try func.resolveInst(pl_op.operand);
const extra = func.air.extraData(Air.Try, pl_op.payload);
const body = func.air.extra[extra.end..][0..extra.data.body_len];
- const err_union_ty = func.air.typeOf(pl_op.operand);
+ const err_union_ty = func.typeOf(pl_op.operand);
const result = try lowerTry(func, inst, err_union, body, err_union_ty, false);
func.finishAir(inst, result, &.{pl_op.operand});
}
@@ -6189,7 +6193,7 @@ fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const extra = func.air.extraData(Air.TryPtr, ty_pl.payload);
const err_union_ptr = try func.resolveInst(extra.data.ptr);
const body = func.air.extra[extra.end..][0..extra.data.body_len];
- const err_union_ty = func.air.typeOf(extra.data.ptr).childType();
+ const err_union_ty = func.typeOf(extra.data.ptr).childType();
const result = try lowerTry(func, inst, err_union_ptr, body, err_union_ty, true);
func.finishAir(inst, result, &.{extra.data.ptr});
}
@@ -6251,11 +6255,11 @@ fn lowerTry(
}
fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
+ const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
- const ty = func.air.typeOfIndex(inst);
+ const ty = func.typeOfIndex(inst);
const operand = try func.resolveInst(ty_op.operand);
- const mod = func.bin_file.base.options.module.?;
if (ty.zigTypeTag(mod) == .Vector) {
return func.fail("TODO: @byteSwap for vectors", .{});
@@ -6325,7 +6329,7 @@ fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
- const ty = func.air.typeOfIndex(inst);
+ const ty = func.typeOfIndex(inst);
const lhs = try func.resolveInst(bin_op.lhs);
const rhs = try func.resolveInst(bin_op.rhs);
@@ -6340,7 +6344,7 @@ fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
- const ty = func.air.typeOfIndex(inst);
+ const ty = func.typeOfIndex(inst);
const lhs = try func.resolveInst(bin_op.lhs);
const rhs = try func.resolveInst(bin_op.rhs);
@@ -6361,7 +6365,7 @@ fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const mod = func.bin_file.base.options.module.?;
- const ty = func.air.typeOfIndex(inst);
+ const ty = func.typeOfIndex(inst);
const lhs = try func.resolveInst(bin_op.lhs);
const rhs = try func.resolveInst(bin_op.rhs);
@@ -6512,7 +6516,7 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const mod = func.bin_file.base.options.module.?;
- const ty = func.air.typeOfIndex(inst);
+ const ty = func.typeOfIndex(inst);
const lhs = try func.resolveInst(bin_op.lhs);
const rhs = try func.resolveInst(bin_op.rhs);
@@ -6626,7 +6630,7 @@ fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const mod = func.bin_file.base.options.module.?;
- const ty = func.air.typeOfIndex(inst);
+ const ty = func.typeOfIndex(inst);
const int_info = ty.intInfo(mod);
const is_signed = int_info.signedness == .signed;
if (int_info.bits > 64) {
@@ -6785,11 +6789,11 @@ fn callIntrinsic(
fn airTagName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const un_op = func.air.instructions.items(.data)[inst].un_op;
const operand = try func.resolveInst(un_op);
- const enum_ty = func.air.typeOf(un_op);
+ const enum_ty = func.typeOf(un_op);
const func_sym_index = try func.getTagNameFunction(enum_ty);
- const result_ptr = try func.allocStack(func.air.typeOfIndex(inst));
+ const result_ptr = try func.allocStack(func.typeOfIndex(inst));
try func.lowerToStack(result_ptr);
try func.emitWValue(operand);
try func.addLabel(.call, func_sym_index);
@@ -7061,9 +7065,9 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const extra = func.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
- const ptr_ty = func.air.typeOf(extra.ptr);
+ const ptr_ty = func.typeOf(extra.ptr);
const ty = ptr_ty.childType();
- const result_ty = func.air.typeOfIndex(inst);
+ const result_ty = func.typeOfIndex(inst);
const ptr_operand = try func.resolveInst(extra.ptr);
const expected_val = try func.resolveInst(extra.expected_value);
@@ -7133,7 +7137,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const atomic_load = func.air.instructions.items(.data)[inst].atomic_load;
const ptr = try func.resolveInst(atomic_load.ptr);
- const ty = func.air.typeOfIndex(inst);
+ const ty = func.typeOfIndex(inst);
if (func.useAtomicFeature()) {
const tag: wasm.AtomicsOpcode = switch (ty.abiSize(mod)) {
@@ -7163,7 +7167,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ptr = try func.resolveInst(pl_op.operand);
const operand = try func.resolveInst(extra.operand);
- const ty = func.air.typeOfIndex(inst);
+ const ty = func.typeOfIndex(inst);
const op: std.builtin.AtomicRmwOp = extra.op();
if (func.useAtomicFeature()) {
@@ -7348,7 +7352,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ptr = try func.resolveInst(bin_op.lhs);
const operand = try func.resolveInst(bin_op.rhs);
- const ptr_ty = func.air.typeOf(bin_op.lhs);
+ const ptr_ty = func.typeOf(bin_op.lhs);
const ty = ptr_ty.childType();
if (func.useAtomicFeature()) {
@@ -7380,3 +7384,13 @@ fn airFrameAddress(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const result = try WValue.toLocal(.stack, func, Type.usize);
return func.finishAir(inst, result, &.{});
}
+
+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);
+}
+
+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);
+}
src/arch/x86_64/CodeGen.zig
@@ -447,7 +447,7 @@ const InstTracking = struct {
else => unreachable,
}
tracking_log.debug("spill %{d} from {} to {}", .{ inst, self.short, self.long });
- try function.genCopy(function.air.typeOfIndex(inst), self.long, self.short);
+ try function.genCopy(function.typeOfIndex(inst), self.long, self.short);
}
fn reuseFrame(self: *InstTracking) void {
@@ -537,7 +537,7 @@ const InstTracking = struct {
inst: Air.Inst.Index,
target: InstTracking,
) !void {
- const ty = function.air.typeOfIndex(inst);
+ const ty = function.typeOfIndex(inst);
if ((self.long == .none or self.long == .reserved_frame) and target.long == .load_frame)
try function.genCopy(ty, target.long, self.short);
try function.genCopy(ty, target.short, self.short);
@@ -1725,6 +1725,8 @@ fn gen(self: *Self) InnerError!void {
}
fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
+ const mod = self.bin_file.options.module.?;
+ const ip = &mod.intern_pool;
const air_tags = self.air.instructions.items(.tag);
for (body) |inst| {
@@ -1733,7 +1735,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)) 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()});
@@ -1919,6 +1921,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.constant => unreachable, // excluded from function bodies
.const_ty => unreachable, // excluded from function bodies
+ .interned => unreachable, // excluded from function bodies
.unreach => if (self.wantSafety()) try self.airTrap() else self.finishAirBookkeeping(),
.optional_payload => try self.airOptionalPayload(inst),
@@ -2255,7 +2258,7 @@ fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex {
/// Use a pointer instruction as the basis for allocating stack memory.
fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex {
const mod = self.bin_file.options.module.?;
- const ptr_ty = self.air.typeOfIndex(inst);
+ const ptr_ty = self.typeOfIndex(inst);
const val_ty = ptr_ty.childType();
return self.allocFrameIndex(FrameAlloc.init(.{
.size = math.cast(u32, val_ty.abiSize(mod)) orelse {
@@ -2266,7 +2269,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex {
}
fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
- return self.allocRegOrMemAdvanced(self.air.typeOfIndex(inst), inst, reg_ok);
+ return self.allocRegOrMemAdvanced(self.typeOfIndex(inst), inst, reg_ok);
}
fn allocTempRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool) !MCValue {
@@ -2485,7 +2488,7 @@ fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {
.load_frame => .{ .register_offset = .{
.reg = (try self.copyToRegisterWithInstTracking(
inst,
- self.air.typeOfIndex(inst),
+ self.typeOfIndex(inst),
self.ret_mcv.long,
)).register,
.off = self.ret_mcv.short.indirect.off,
@@ -2496,9 +2499,9 @@ fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {
fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const dst_ty = self.air.typeOfIndex(inst);
+ const dst_ty = self.typeOfIndex(inst);
const dst_bits = dst_ty.floatBits(self.target.*);
- const src_ty = self.air.typeOf(ty_op.operand);
+ const src_ty = self.typeOf(ty_op.operand);
const src_bits = src_ty.floatBits(self.target.*);
const src_mcv = try self.resolveInst(ty_op.operand);
@@ -2562,9 +2565,9 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void {
fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const dst_ty = self.air.typeOfIndex(inst);
+ const dst_ty = self.typeOfIndex(inst);
const dst_bits = dst_ty.floatBits(self.target.*);
- const src_ty = self.air.typeOf(ty_op.operand);
+ const src_ty = self.typeOf(ty_op.operand);
const src_bits = src_ty.floatBits(self.target.*);
const src_mcv = try self.resolveInst(ty_op.operand);
@@ -2625,10 +2628,10 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = result: {
- const src_ty = self.air.typeOf(ty_op.operand);
+ const src_ty = self.typeOf(ty_op.operand);
const src_int_info = src_ty.intInfo(mod);
- const dst_ty = self.air.typeOfIndex(inst);
+ const dst_ty = self.typeOfIndex(inst);
const dst_int_info = dst_ty.intInfo(mod);
const abi_size = @intCast(u32, dst_ty.abiSize(mod));
@@ -2707,9 +2710,9 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const dst_ty = self.air.typeOfIndex(inst);
+ const dst_ty = self.typeOfIndex(inst);
const dst_abi_size = @intCast(u32, dst_ty.abiSize(mod));
- const src_ty = self.air.typeOf(ty_op.operand);
+ const src_ty = self.typeOf(ty_op.operand);
const src_abi_size = @intCast(u32, src_ty.abiSize(mod));
const result = result: {
@@ -2818,7 +2821,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
fn airBoolToInt(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
- const ty = self.air.typeOfIndex(inst);
+ const ty = self.typeOfIndex(inst);
const operand = try self.resolveInst(un_op);
const dst_mcv = if (self.reuseOperand(inst, un_op, 0, operand))
@@ -2834,11 +2837,11 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
- const slice_ty = self.air.typeOfIndex(inst);
+ const slice_ty = self.typeOfIndex(inst);
const ptr = try self.resolveInst(bin_op.lhs);
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const len = try self.resolveInst(bin_op.rhs);
- const len_ty = self.air.typeOf(bin_op.rhs);
+ const len_ty = self.typeOf(bin_op.rhs);
const frame_index = try self.allocFrameIndex(FrameAlloc.initType(slice_ty, mod));
try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr);
@@ -2877,7 +2880,7 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {
const air_tag = self.air.instructions.items(.tag);
const air_data = self.air.instructions.items(.data);
- const dst_ty = self.air.typeOf(dst_air);
+ const dst_ty = self.typeOf(dst_air);
const dst_info = dst_ty.intInfo(mod);
if (Air.refToIndex(dst_air)) |inst| {
switch (air_tag[inst]) {
@@ -2889,7 +2892,7 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {
@boolToInt(src_int.positive and dst_info.signedness == .signed);
},
.intcast => {
- const src_ty = self.air.typeOf(air_data[inst].ty_op.operand);
+ const src_ty = self.typeOf(air_data[inst].ty_op.operand);
const src_info = src_ty.intInfo(mod);
return @min(switch (src_info.signedness) {
.signed => switch (dst_info.signedness) {
@@ -2913,7 +2916,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const result = result: {
const tag = self.air.instructions.items(.tag)[inst];
- const dst_ty = self.air.typeOfIndex(inst);
+ const dst_ty = self.typeOfIndex(inst);
switch (dst_ty.zigTypeTag(mod)) {
.Float, .Vector => break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs),
else => {},
@@ -2942,7 +2945,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const ty = self.air.typeOf(bin_op.lhs);
+ const ty = self.typeOf(bin_op.lhs);
const lhs_mcv = try self.resolveInst(bin_op.lhs);
const dst_mcv = if (lhs_mcv.isRegister() and self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv))
@@ -3021,7 +3024,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const ty = self.air.typeOf(bin_op.lhs);
+ const ty = self.typeOf(bin_op.lhs);
const lhs_mcv = try self.resolveInst(bin_op.lhs);
const dst_mcv = if (lhs_mcv.isRegister() and self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv))
@@ -3093,7 +3096,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const ty = self.air.typeOf(bin_op.lhs);
+ const ty = self.typeOf(bin_op.lhs);
try self.spillRegisters(&.{ .rax, .rdx });
const reg_locks = self.register_manager.lockRegs(2, .{ .rax, .rdx });
@@ -3151,7 +3154,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const result: MCValue = result: {
const tag = self.air.instructions.items(.tag)[inst];
- const ty = self.air.typeOf(bin_op.lhs);
+ const ty = self.typeOf(bin_op.lhs);
switch (ty.zigTypeTag(mod)) {
.Vector => return self.fail("TODO implement add/sub with overflow for Vector type", .{}),
.Int => {
@@ -3168,7 +3171,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
.signed => .o,
};
- const tuple_ty = self.air.typeOfIndex(inst);
+ const tuple_ty = self.typeOfIndex(inst);
if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) {
switch (partial_mcv) {
.register => |reg| {
@@ -3211,8 +3214,8 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const result: MCValue = result: {
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
switch (lhs_ty.zigTypeTag(mod)) {
.Vector => return self.fail("TODO implement shl with overflow for Vector type", .{}),
.Int => {
@@ -3241,7 +3244,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
try self.genBinOpMir(.{ ._, .cmp }, lhs_ty, tmp_mcv, lhs);
const cc = Condition.ne;
- const tuple_ty = self.air.typeOfIndex(inst);
+ const tuple_ty = self.typeOfIndex(inst);
if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) {
switch (partial_mcv) {
.register => |reg| {
@@ -3349,7 +3352,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
- const dst_ty = self.air.typeOf(bin_op.lhs);
+ const dst_ty = self.typeOf(bin_op.lhs);
const result: MCValue = switch (dst_ty.zigTypeTag(mod)) {
.Vector => return self.fail("TODO implement mul_with_overflow for Vector type", .{}),
.Int => result: {
@@ -3370,7 +3373,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const tuple_ty = self.air.typeOfIndex(inst);
+ const tuple_ty = self.typeOfIndex(inst);
const extra_bits = if (dst_info.bits <= 64)
self.regExtraBits(dst_ty)
else
@@ -3525,8 +3528,8 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {
try self.register_manager.getReg(.rcx, null);
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
const result = try self.genShiftBinOp(tag, inst, lhs, rhs, lhs_ty, rhs_ty);
@@ -3543,7 +3546,7 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = result: {
- const pl_ty = self.air.typeOfIndex(inst);
+ const pl_ty = self.typeOfIndex(inst);
const opt_mcv = try self.resolveInst(ty_op.operand);
if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) {
@@ -3568,7 +3571,7 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const dst_ty = self.air.typeOfIndex(inst);
+ const dst_ty = self.typeOfIndex(inst);
const opt_mcv = try self.resolveInst(ty_op.operand);
const dst_mcv = if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv))
@@ -3582,8 +3585,8 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result = result: {
- const dst_ty = self.air.typeOfIndex(inst);
- const src_ty = self.air.typeOf(ty_op.operand);
+ const dst_ty = self.typeOfIndex(inst);
+ const src_ty = self.typeOf(ty_op.operand);
const opt_ty = src_ty.childType();
const src_mcv = try self.resolveInst(ty_op.operand);
@@ -3615,7 +3618,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const err_union_ty = self.air.typeOf(ty_op.operand);
+ const err_union_ty = self.typeOf(ty_op.operand);
const err_ty = err_union_ty.errorUnionSet();
const payload_ty = err_union_ty.errorUnionPayload();
const operand = try self.resolveInst(ty_op.operand);
@@ -3662,7 +3665,7 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const err_union_ty = self.air.typeOf(ty_op.operand);
+ const err_union_ty = self.typeOf(ty_op.operand);
const operand = try self.resolveInst(ty_op.operand);
const result = try self.genUnwrapErrorUnionPayloadMir(inst, err_union_ty, operand);
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
@@ -3720,7 +3723,7 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const src_ty = self.air.typeOf(ty_op.operand);
+ const src_ty = self.typeOf(ty_op.operand);
const src_mcv = try self.resolveInst(ty_op.operand);
const src_reg = switch (src_mcv) {
.register => |reg| reg,
@@ -3756,7 +3759,7 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const src_ty = self.air.typeOf(ty_op.operand);
+ const src_ty = self.typeOf(ty_op.operand);
const src_mcv = try self.resolveInst(ty_op.operand);
const src_reg = switch (src_mcv) {
.register => |reg| reg,
@@ -3765,7 +3768,7 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
const src_lock = self.register_manager.lockRegAssumeUnused(src_reg);
defer self.register_manager.unlockReg(src_lock);
- const dst_ty = self.air.typeOfIndex(inst);
+ const dst_ty = self.typeOfIndex(inst);
const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
src_reg
else
@@ -3791,7 +3794,7 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = result: {
- const src_ty = self.air.typeOf(ty_op.operand);
+ const src_ty = self.typeOf(ty_op.operand);
const src_mcv = try self.resolveInst(ty_op.operand);
const src_reg = switch (src_mcv) {
.register => |reg| reg,
@@ -3816,7 +3819,7 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
if (self.liveness.isUnused(inst)) break :result .unreach;
- const dst_ty = self.air.typeOfIndex(inst);
+ const dst_ty = self.typeOfIndex(inst);
const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
src_reg
else
@@ -3856,10 +3859,10 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = result: {
- const pl_ty = self.air.typeOf(ty_op.operand);
+ const pl_ty = self.typeOf(ty_op.operand);
if (!pl_ty.hasRuntimeBits(mod)) break :result .{ .immediate = 1 };
- const opt_ty = self.air.typeOfIndex(inst);
+ const opt_ty = self.typeOfIndex(inst);
const pl_mcv = try self.resolveInst(ty_op.operand);
const same_repr = opt_ty.optionalReprIsPayload(mod);
if (same_repr and self.reuseOperand(inst, ty_op.operand, 0, pl_mcv)) break :result pl_mcv;
@@ -3952,7 +3955,7 @@ fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv;
const dst_mcv = try self.allocRegOrMem(inst, true);
- const dst_ty = self.air.typeOfIndex(inst);
+ const dst_ty = self.typeOfIndex(inst);
try self.genCopy(dst_ty, dst_mcv, src_mcv);
break :result dst_mcv;
};
@@ -3980,7 +3983,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const src_ty = self.air.typeOf(ty_op.operand);
+ const src_ty = self.typeOf(ty_op.operand);
const src_mcv = try self.resolveInst(ty_op.operand);
const src_reg = switch (src_mcv) {
.register => |reg| reg,
@@ -3989,7 +3992,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
const src_lock = self.register_manager.lockRegAssumeUnused(src_reg);
defer self.register_manager.unlockReg(src_lock);
- const dst_ty = self.air.typeOfIndex(inst);
+ const dst_ty = self.typeOfIndex(inst);
const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
src_reg
else
@@ -4014,7 +4017,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const dst_ty = self.air.typeOfIndex(inst);
+ const dst_ty = self.typeOfIndex(inst);
const opt_mcv = try self.resolveInst(ty_op.operand);
const dst_mcv = if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv))
@@ -4046,7 +4049,7 @@ fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Regi
fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
const mod = self.bin_file.options.module.?;
- const slice_ty = self.air.typeOf(lhs);
+ const slice_ty = self.typeOf(lhs);
const slice_mcv = try self.resolveInst(lhs);
const slice_mcv_lock: ?RegisterLock = switch (slice_mcv) {
.register => |reg| self.register_manager.lockRegAssumeUnused(reg),
@@ -4059,7 +4062,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);
- const index_ty = self.air.typeOf(rhs);
+ const index_ty = self.typeOf(rhs);
const index_mcv = try self.resolveInst(rhs);
const index_mcv_lock: ?RegisterLock = switch (index_mcv) {
.register => |reg| self.register_manager.lockRegAssumeUnused(reg),
@@ -4083,7 +4086,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const slice_ty = self.air.typeOf(bin_op.lhs);
+ const slice_ty = self.typeOf(bin_op.lhs);
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);
@@ -4105,7 +4108,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const array_ty = self.air.typeOf(bin_op.lhs);
+ const array_ty = self.typeOf(bin_op.lhs);
const array = try self.resolveInst(bin_op.lhs);
const array_lock: ?RegisterLock = switch (array) {
.register => |reg| self.register_manager.lockRegAssumeUnused(reg),
@@ -4116,7 +4119,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
const elem_ty = array_ty.childType();
const elem_abi_size = elem_ty.abiSize(mod);
- const index_ty = self.air.typeOf(bin_op.rhs);
+ const index_ty = self.typeOf(bin_op.rhs);
const index = try self.resolveInst(bin_op.rhs);
const index_lock: ?RegisterLock = switch (index) {
.register => |reg| self.register_manager.lockRegAssumeUnused(reg),
@@ -4170,14 +4173,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
// this is identical to the `airPtrElemPtr` codegen expect here an
// additional `mov` is needed at the end to get the actual value
const elem_ty = ptr_ty.elemType2(mod);
const elem_abi_size = @intCast(u32, elem_ty.abiSize(mod));
- const index_ty = self.air.typeOf(bin_op.rhs);
+ const index_ty = self.typeOf(bin_op.rhs);
const index_mcv = try self.resolveInst(bin_op.rhs);
const index_lock = switch (index_mcv) {
.register => |reg| self.register_manager.lockRegAssumeUnused(reg),
@@ -4218,7 +4221,7 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
- const ptr_ty = self.air.typeOf(extra.lhs);
+ const ptr_ty = self.typeOf(extra.lhs);
const ptr = try self.resolveInst(extra.lhs);
const ptr_lock: ?RegisterLock = switch (ptr) {
.register => |reg| self.register_manager.lockRegAssumeUnused(reg),
@@ -4228,7 +4231,7 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
const elem_ty = ptr_ty.elemType2(mod);
const elem_abi_size = elem_ty.abiSize(mod);
- const index_ty = self.air.typeOf(extra.rhs);
+ const index_ty = self.typeOf(extra.rhs);
const index = try self.resolveInst(extra.rhs);
const index_lock: ?RegisterLock = switch (index) {
.register => |reg| self.register_manager.lockRegAssumeUnused(reg),
@@ -4249,9 +4252,9 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const ptr_union_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_union_ty = self.typeOf(bin_op.lhs);
const union_ty = ptr_union_ty.childType();
- const tag_ty = self.air.typeOf(bin_op.rhs);
+ const tag_ty = self.typeOf(bin_op.rhs);
const layout = union_ty.unionGetLayout(mod);
if (layout.tag_size == 0) {
@@ -4296,8 +4299,8 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const tag_ty = self.air.typeOfIndex(inst);
- const union_ty = self.air.typeOf(ty_op.operand);
+ const tag_ty = self.typeOfIndex(inst);
+ const union_ty = self.typeOf(ty_op.operand);
const layout = union_ty.unionGetLayout(mod);
if (layout.tag_size == 0) {
@@ -4350,8 +4353,8 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result = result: {
- const dst_ty = self.air.typeOfIndex(inst);
- const src_ty = self.air.typeOf(ty_op.operand);
+ const dst_ty = self.typeOfIndex(inst);
+ const src_ty = self.typeOf(ty_op.operand);
const src_mcv = try self.resolveInst(ty_op.operand);
const mat_src_mcv = switch (src_mcv) {
@@ -4479,8 +4482,8 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result = result: {
- const dst_ty = self.air.typeOfIndex(inst);
- const src_ty = self.air.typeOf(ty_op.operand);
+ const dst_ty = self.typeOfIndex(inst);
+ const src_ty = self.typeOf(ty_op.operand);
const src_bits = src_ty.bitSize(mod);
const src_mcv = try self.resolveInst(ty_op.operand);
@@ -4575,7 +4578,7 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = result: {
- const src_ty = self.air.typeOf(ty_op.operand);
+ const src_ty = self.typeOf(ty_op.operand);
const src_abi_size = @intCast(u32, src_ty.abiSize(mod));
const src_mcv = try self.resolveInst(ty_op.operand);
@@ -4745,7 +4748,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const src_ty = self.air.typeOf(ty_op.operand);
+ const src_ty = self.typeOf(ty_op.operand);
const src_mcv = try self.resolveInst(ty_op.operand);
const dst_mcv = try self.byteSwap(inst, src_ty, src_mcv, true);
@@ -4766,7 +4769,7 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const src_ty = self.air.typeOf(ty_op.operand);
+ const src_ty = self.typeOf(ty_op.operand);
const src_abi_size = @intCast(u32, src_ty.abiSize(mod));
const src_mcv = try self.resolveInst(ty_op.operand);
@@ -4876,12 +4879,12 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const tag = self.air.instructions.items(.tag)[inst];
const un_op = self.air.instructions.items(.data)[inst].un_op;
- const ty = self.air.typeOf(un_op);
+ const ty = self.typeOf(un_op);
const abi_size: u32 = switch (ty.abiSize(mod)) {
1...16 => 16,
17...32 => 32,
else => return self.fail("TODO implement airFloatSign for {}", .{
- ty.fmt(self.bin_file.options.module.?),
+ ty.fmt(mod),
}),
};
const scalar_bits = ty.scalarType(mod).floatBits(self.target.*);
@@ -5005,7 +5008,7 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {
fn airRound(self: *Self, inst: Air.Inst.Index, mode: u4) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
- const ty = self.air.typeOf(un_op);
+ const ty = self.typeOf(un_op);
const src_mcv = try self.resolveInst(un_op);
const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, un_op, 0, src_mcv))
@@ -5093,7 +5096,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4
fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const un_op = self.air.instructions.items(.data)[inst].un_op;
- const ty = self.air.typeOf(un_op);
+ const ty = self.typeOf(un_op);
const abi_size = @intCast(u32, ty.abiSize(mod));
const src_mcv = try self.resolveInst(un_op);
@@ -5399,7 +5402,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro
fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const elem_ty = self.air.typeOfIndex(inst);
+ const elem_ty = self.typeOfIndex(inst);
const result: MCValue = result: {
if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;
@@ -5407,7 +5410,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rdi, .rsi, .rcx });
defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
- const ptr_ty = self.air.typeOf(ty_op.operand);
+ const ptr_ty = self.typeOf(ty_op.operand);
const elem_size = elem_ty.abiSize(mod);
const elem_rc = regClassForType(elem_ty, mod);
@@ -5548,7 +5551,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
}
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const ptr_mcv = try self.resolveInst(bin_op.lhs);
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const src_mcv = try self.resolveInst(bin_op.rhs);
if (ptr_ty.ptrInfo().data.host_size > 0) {
try self.packedStore(ptr_ty, ptr_mcv, src_mcv);
@@ -5573,8 +5576,8 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
const mod = self.bin_file.options.module.?;
- const ptr_field_ty = self.air.typeOfIndex(inst);
- const ptr_container_ty = self.air.typeOf(operand);
+ const ptr_field_ty = self.typeOfIndex(inst);
+ const ptr_container_ty = self.typeOf(operand);
const container_ty = ptr_container_ty.childType();
const field_offset = @intCast(i32, switch (container_ty.containerLayout()) {
.Auto, .Extern => container_ty.structFieldOffset(index, mod),
@@ -5602,7 +5605,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
const operand = extra.struct_operand;
const index = extra.field_index;
- const container_ty = self.air.typeOf(operand);
+ const container_ty = self.typeOf(operand);
const container_rc = regClassForType(container_ty, mod);
const field_ty = container_ty.structFieldType(index);
if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;
@@ -5756,7 +5759,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
- const inst_ty = self.air.typeOfIndex(inst);
+ const inst_ty = self.typeOfIndex(inst);
const parent_ty = inst_ty.childType();
const field_offset = @intCast(i32, parent_ty.structFieldOffset(extra.field_index, mod));
@@ -5772,7 +5775,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: Air.Inst.Ref) !MCValue {
const mod = self.bin_file.options.module.?;
- const src_ty = self.air.typeOf(src_air);
+ const src_ty = self.typeOf(src_air);
const src_mcv = try self.resolveInst(src_air);
if (src_ty.zigTypeTag(mod) == .Vector) {
return self.fail("TODO implement genUnOp for {}", .{src_ty.fmt(self.bin_file.options.module.?)});
@@ -6358,8 +6361,8 @@ fn genBinOp(
rhs_air: Air.Inst.Ref,
) !MCValue {
const mod = self.bin_file.options.module.?;
- const lhs_ty = self.air.typeOf(lhs_air);
- const rhs_ty = self.air.typeOf(rhs_air);
+ const lhs_ty = self.typeOf(lhs_air);
+ const rhs_ty = self.typeOf(rhs_air);
const abi_size = @intCast(u32, lhs_ty.abiSize(mod));
const maybe_mask_reg = switch (air_tag) {
@@ -7918,6 +7921,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
}
fn airArg(self: *Self, inst: Air.Inst.Index) !void {
+ const mod = self.bin_file.options.module.?;
// skip zero-bit arguments as they don't have a corresponding arg instruction
var arg_index = self.arg_index;
while (self.args[arg_index] == .none) arg_index += 1;
@@ -7931,9 +7935,9 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
else => return self.fail("TODO implement arg for {}", .{dst_mcv}),
}
- const ty = self.air.typeOfIndex(inst);
+ const ty = self.typeOfIndex(inst);
const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
- const name = self.owner.mod_fn.getParamName(self.bin_file.options.module.?, src_index);
+ const name = self.owner.mod_fn.getParamName(mod, src_index);
try self.genArgDbgInfo(ty, name, dst_mcv);
break :result dst_mcv;
@@ -8050,7 +8054,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
const callee = pl_op.operand;
const extra = self.air.extraData(Air.Call, pl_op.payload);
const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
- const ty = self.air.typeOf(callee);
+ const ty = self.typeOf(callee);
const fn_ty = switch (ty.zigTypeTag(mod)) {
.Fn => ty,
@@ -8085,7 +8089,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
else => unreachable,
}
for (args, info.args) |arg, mc_arg| {
- const arg_ty = self.air.typeOf(arg);
+ const arg_ty = self.typeOf(arg);
const arg_mcv = try self.resolveInst(arg);
switch (mc_arg) {
.none => {},
@@ -8112,7 +8116,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
defer if (ret_lock) |lock| self.register_manager.unlockReg(lock);
for (args, info.args) |arg, mc_arg| {
- const arg_ty = self.air.typeOf(arg);
+ const arg_ty = self.typeOf(arg);
const arg_mcv = try self.resolveInst(arg);
switch (mc_arg) {
.none, .load_frame => {},
@@ -8241,7 +8245,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const ptr = try self.resolveInst(un_op);
- const ptr_ty = self.air.typeOf(un_op);
+ const ptr_ty = self.typeOf(un_op);
switch (self.ret_mcv.short) {
.none => {},
.register => try self.load(self.ret_mcv.short, ptr_ty, ptr),
@@ -8258,7 +8262,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
const mod = self.bin_file.options.module.?;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const ty = self.air.typeOf(bin_op.lhs);
+ const ty = self.typeOf(bin_op.lhs);
try self.spillEflagsIfOccupied();
self.eflags_inst = inst;
@@ -8476,7 +8480,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
try self.spillEflagsIfOccupied();
self.eflags_inst = inst;
- const op_ty = self.air.typeOf(un_op);
+ const op_ty = self.typeOf(un_op);
const op_abi_size = @intCast(u32, op_ty.abiSize(mod));
const op_mcv = try self.resolveInst(un_op);
const dst_reg = switch (op_mcv) {
@@ -8496,7 +8500,7 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const extra = self.air.extraData(Air.Try, pl_op.payload);
const body = self.air.extra[extra.end..][0..extra.data.body_len];
- const err_union_ty = self.air.typeOf(pl_op.operand);
+ const err_union_ty = self.typeOf(pl_op.operand);
const result = try self.genTry(inst, pl_op.operand, body, err_union_ty, false);
return self.finishAir(inst, result, .{ .none, .none, .none });
}
@@ -8505,7 +8509,7 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);
const body = self.air.extra[extra.end..][0..extra.data.body_len];
- const err_union_ty = self.air.typeOf(extra.data.ptr).childType();
+ const err_union_ty = self.typeOf(extra.data.ptr).childType();
const result = try self.genTry(inst, extra.data.ptr, body, err_union_ty, true);
return self.finishAir(inst, result, .{ .none, .none, .none });
}
@@ -8584,7 +8588,7 @@ fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const operand = pl_op.operand;
- const ty = self.air.typeOf(operand);
+ const ty = self.typeOf(operand);
const mcv = try self.resolveInst(operand);
const name = self.air.nullTerminatedString(pl_op.payload);
@@ -8626,7 +8630,7 @@ fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !u32 {
fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const cond = try self.resolveInst(pl_op.operand);
- const cond_ty = self.air.typeOf(pl_op.operand);
+ const cond_ty = self.typeOf(pl_op.operand);
const extra = self.air.extraData(Air.CondBr, pl_op.payload);
const then_body = self.air.extra[extra.end..][0..extra.data.then_body_len];
const else_body = self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
@@ -8871,7 +8875,7 @@ fn isNonErr(self: *Self, inst: Air.Inst.Index, ty: Type, operand: MCValue) !MCVa
fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const operand = try self.resolveInst(un_op);
- const ty = self.air.typeOf(un_op);
+ const ty = self.typeOf(un_op);
const result = try self.isNull(inst, ty, operand);
return self.finishAir(inst, result, .{ un_op, .none, .none });
}
@@ -8879,7 +8883,7 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const operand = try self.resolveInst(un_op);
- const ty = self.air.typeOf(un_op);
+ const ty = self.typeOf(un_op);
const result = try self.isNullPtr(inst, ty, operand);
return self.finishAir(inst, result, .{ un_op, .none, .none });
}
@@ -8887,7 +8891,7 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const operand = try self.resolveInst(un_op);
- const ty = self.air.typeOf(un_op);
+ const ty = self.typeOf(un_op);
const result = switch (try self.isNull(inst, ty, operand)) {
.eflags => |cc| .{ .eflags = cc.negate() },
else => unreachable,
@@ -8898,7 +8902,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const operand = try self.resolveInst(un_op);
- const ty = self.air.typeOf(un_op);
+ const ty = self.typeOf(un_op);
const result = switch (try self.isNullPtr(inst, ty, operand)) {
.eflags => |cc| .{ .eflags = cc.negate() },
else => unreachable,
@@ -8909,7 +8913,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const operand = try self.resolveInst(un_op);
- const ty = self.air.typeOf(un_op);
+ const ty = self.typeOf(un_op);
const result = try self.isErr(inst, ty, operand);
return self.finishAir(inst, result, .{ un_op, .none, .none });
}
@@ -8932,7 +8936,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
break :blk try self.allocRegOrMem(inst, true);
}
};
- const ptr_ty = self.air.typeOf(un_op);
+ const ptr_ty = self.typeOf(un_op);
try self.load(operand, ptr_ty, operand_ptr);
const result = try self.isErr(inst, ptr_ty.childType(), operand);
@@ -8943,7 +8947,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const operand = try self.resolveInst(un_op);
- const ty = self.air.typeOf(un_op);
+ const ty = self.typeOf(un_op);
const result = try self.isNonErr(inst, ty, operand);
return self.finishAir(inst, result, .{ un_op, .none, .none });
}
@@ -8966,7 +8970,7 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
break :blk try self.allocRegOrMem(inst, true);
}
};
- const ptr_ty = self.air.typeOf(un_op);
+ const ptr_ty = self.typeOf(un_op);
try self.load(operand, ptr_ty, operand_ptr);
const result = try self.isNonErr(inst, ptr_ty.childType(), operand);
@@ -9032,7 +9036,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const condition = try self.resolveInst(pl_op.operand);
- const condition_ty = self.air.typeOf(pl_op.operand);
+ const condition_ty = self.typeOf(pl_op.operand);
const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
var extra_index: usize = switch_br.end;
var case_i: u32 = 0;
@@ -9119,7 +9123,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
const br = self.air.instructions.items(.data)[inst].br;
const src_mcv = try self.resolveInst(br.operand);
- const block_ty = self.air.typeOfIndex(br.block_inst);
+ const block_ty = self.typeOfIndex(br.block_inst);
const block_unused =
!block_ty.hasRuntimeBitsIgnoreComptime(mod) or self.liveness.isUnused(br.block_inst);
const block_tracking = self.inst_tracking.getPtr(br.block_inst).?;
@@ -9244,7 +9248,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
const arg_mcv = try self.resolveInst(input);
try self.register_manager.getReg(reg, null);
- try self.genSetReg(reg, self.air.typeOf(input), arg_mcv);
+ try self.genSetReg(reg, self.typeOf(input), arg_mcv);
}
{
@@ -10169,7 +10173,7 @@ fn airPtrToInt(self: *Self, inst: Air.Inst.Index) !void {
if (self.reuseOperand(inst, un_op, 0, src_mcv)) break :result src_mcv;
const dst_mcv = try self.allocRegOrMem(inst, true);
- const dst_ty = self.air.typeOfIndex(inst);
+ const dst_ty = self.typeOfIndex(inst);
try self.genCopy(dst_ty, dst_mcv, src_mcv);
break :result dst_mcv;
};
@@ -10179,8 +10183,8 @@ fn airPtrToInt(self: *Self, inst: Air.Inst.Index) !void {
fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const dst_ty = self.air.typeOfIndex(inst);
- const src_ty = self.air.typeOf(ty_op.operand);
+ const dst_ty = self.typeOfIndex(inst);
+ const src_ty = self.typeOf(ty_op.operand);
const result = result: {
const dst_rc = regClassForType(dst_ty, mod);
@@ -10241,8 +10245,8 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const slice_ty = self.air.typeOfIndex(inst);
- const ptr_ty = self.air.typeOf(ty_op.operand);
+ const slice_ty = self.typeOfIndex(inst);
+ const ptr_ty = self.typeOf(ty_op.operand);
const ptr = try self.resolveInst(ty_op.operand);
const array_ty = ptr_ty.childType();
const array_len = array_ty.arrayLen();
@@ -10264,11 +10268,11 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const src_ty = self.air.typeOf(ty_op.operand);
+ const src_ty = self.typeOf(ty_op.operand);
const src_bits = @intCast(u32, src_ty.bitSize(mod));
const src_signedness =
if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned;
- const dst_ty = self.air.typeOfIndex(inst);
+ const dst_ty = self.typeOfIndex(inst);
const src_size = math.divCeil(u32, @max(switch (src_signedness) {
.signed => src_bits,
@@ -10318,8 +10322,8 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const src_ty = self.air.typeOf(ty_op.operand);
- const dst_ty = self.air.typeOfIndex(inst);
+ const src_ty = self.typeOf(ty_op.operand);
+ const dst_ty = self.typeOfIndex(inst);
const dst_bits = @intCast(u32, dst_ty.bitSize(mod));
const dst_signedness =
if (dst_ty.isAbiInt(mod)) dst_ty.intInfo(mod).signedness else .unsigned;
@@ -10371,8 +10375,8 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
- const ptr_ty = self.air.typeOf(extra.ptr);
- const val_ty = self.air.typeOf(extra.expected_value);
+ const ptr_ty = self.typeOf(extra.ptr);
+ const val_ty = self.typeOf(extra.expected_value);
const val_abi_size = @intCast(u32, val_ty.abiSize(mod));
try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx });
@@ -10712,10 +10716,10 @@ fn airAtomicRmw(self: *Self, inst: Air.Inst.Index) !void {
const unused = self.liveness.isUnused(inst);
- const ptr_ty = self.air.typeOf(pl_op.operand);
+ const ptr_ty = self.typeOf(pl_op.operand);
const ptr_mcv = try self.resolveInst(pl_op.operand);
- const val_ty = self.air.typeOf(extra.operand);
+ const val_ty = self.typeOf(extra.operand);
const val_mcv = try self.resolveInst(extra.operand);
const result =
@@ -10726,7 +10730,7 @@ fn airAtomicRmw(self: *Self, inst: Air.Inst.Index) !void {
fn airAtomicLoad(self: *Self, inst: Air.Inst.Index) !void {
const atomic_load = self.air.instructions.items(.data)[inst].atomic_load;
- const ptr_ty = self.air.typeOf(atomic_load.ptr);
+ const ptr_ty = self.typeOf(atomic_load.ptr);
const ptr_mcv = try self.resolveInst(atomic_load.ptr);
const ptr_lock = switch (ptr_mcv) {
.register => |reg| self.register_manager.lockRegAssumeUnused(reg),
@@ -10747,10 +10751,10 @@ fn airAtomicLoad(self: *Self, inst: Air.Inst.Index) !void {
fn airAtomicStore(self: *Self, inst: Air.Inst.Index, order: std.builtin.AtomicOrder) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const ptr_mcv = try self.resolveInst(bin_op.lhs);
- const val_ty = self.air.typeOf(bin_op.rhs);
+ const val_ty = self.typeOf(bin_op.rhs);
const val_mcv = try self.resolveInst(bin_op.rhs);
const result = try self.atomicOp(ptr_mcv, val_mcv, ptr_ty, val_ty, true, null, order);
@@ -10768,7 +10772,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const dst_ptr = try self.resolveInst(bin_op.lhs);
- const dst_ptr_ty = self.air.typeOf(bin_op.lhs);
+ const dst_ptr_ty = self.typeOf(bin_op.lhs);
const dst_ptr_lock: ?RegisterLock = switch (dst_ptr) {
.register => |reg| self.register_manager.lockRegAssumeUnused(reg),
else => null,
@@ -10776,7 +10780,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
defer if (dst_ptr_lock) |lock| self.register_manager.unlockReg(lock);
const src_val = try self.resolveInst(bin_op.rhs);
- const elem_ty = self.air.typeOf(bin_op.rhs);
+ const elem_ty = self.typeOf(bin_op.rhs);
const src_val_lock: ?RegisterLock = switch (src_val) {
.register => |reg| self.register_manager.lockRegAssumeUnused(reg),
else => null,
@@ -10888,7 +10892,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const dst_ptr = try self.resolveInst(bin_op.lhs);
- const dst_ptr_ty = self.air.typeOf(bin_op.lhs);
+ const dst_ptr_ty = self.typeOf(bin_op.lhs);
const dst_ptr_lock: ?RegisterLock = switch (dst_ptr) {
.register => |reg| self.register_manager.lockRegAssumeUnused(reg),
else => null,
@@ -10922,8 +10926,8 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {
fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const un_op = self.air.instructions.items(.data)[inst].un_op;
- const inst_ty = self.air.typeOfIndex(inst);
- const enum_ty = self.air.typeOf(un_op);
+ const inst_ty = self.typeOfIndex(inst);
+ const enum_ty = self.typeOf(un_op);
// We need a properly aligned and sized call frame to be able to call this function.
{
@@ -10964,7 +10968,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const un_op = self.air.instructions.items(.data)[inst].un_op;
- const err_ty = self.air.typeOf(un_op);
+ const err_ty = self.typeOf(un_op);
const err_mcv = try self.resolveInst(un_op);
const err_reg = try self.copyToTmpRegister(err_ty, err_mcv);
const err_lock = self.register_manager.lockRegAssumeUnused(err_reg);
@@ -11046,7 +11050,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
fn airSplat(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const vector_ty = self.air.typeOfIndex(inst);
+ const vector_ty = self.typeOfIndex(inst);
const dst_rc = regClassForType(vector_ty, mod);
const scalar_ty = vector_ty.scalarType(mod);
@@ -11266,7 +11270,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
- const result_ty = self.air.typeOfIndex(inst);
+ const result_ty = self.typeOfIndex(inst);
const len = @intCast(usize, result_ty.arrayLen());
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
@@ -11411,10 +11415,10 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
const result: MCValue = result: {
- const union_ty = self.air.typeOfIndex(inst);
+ const union_ty = self.typeOfIndex(inst);
const layout = union_ty.unionGetLayout(mod);
- const src_ty = self.air.typeOf(extra.init);
+ const src_ty = self.typeOf(extra.init);
const src_mcv = try self.resolveInst(extra.init);
if (layout.tag_size == 0) {
if (self.reuseOperand(inst, extra.init, 0, src_mcv)) break :result src_mcv;
@@ -11461,7 +11465,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
- const ty = self.air.typeOfIndex(inst);
+ const ty = self.typeOfIndex(inst);
if (!self.hasFeature(.fma)) return self.fail("TODO implement airMulAdd for {}", .{
ty.fmt(self.bin_file.options.module.?),
@@ -11609,7 +11613,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
const mod = self.bin_file.options.module.?;
- const ty = self.air.typeOf(ref);
+ const ty = self.typeOf(ref);
// If the type has no codegen bits, no need to store it.
if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;
@@ -11713,7 +11717,7 @@ fn resolveCallingConventionValues(
defer self.gpa.free(param_types);
fn_ty.fnParamTypes(param_types);
// TODO: promote var arg types
- for (param_types[param_len..], var_args) |*param_ty, arg| param_ty.* = self.air.typeOf(arg);
+ for (param_types[param_len..], var_args) |*param_ty, arg| param_ty.* = self.typeOf(arg);
var result: CallMCValues = .{
.args = try self.gpa.alloc(MCValue, param_types.len),
// These undefined values must be populated before returning from this function.
@@ -12023,3 +12027,13 @@ fn hasAnyFeatures(self: *Self, features: anytype) bool {
fn hasAllFeatures(self: *Self, features: anytype) bool {
return Target.x86.featureSetHasAll(self.target.cpu.features, features);
}
+
+fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
+ const mod = self.bin_file.options.module.?;
+ 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);
+}
src/codegen/c.zig
@@ -288,7 +288,7 @@ pub const Function = struct {
const mod = f.object.dg.module;
const val = f.air.value(ref, mod).?;
- const ty = f.air.typeOf(ref);
+ const ty = f.typeOf(ref);
const result: CValue = if (lowersToArray(ty, mod)) result: {
const writer = f.object.code_header.writer();
@@ -355,7 +355,7 @@ pub const Function = struct {
switch (c_value) {
.constant => |inst| {
const mod = f.object.dg.module;
- const ty = f.air.typeOf(inst);
+ const ty = f.typeOf(inst);
const val = f.air.value(inst, mod).?;
return f.object.dg.renderValue(w, ty, val, location);
},
@@ -368,7 +368,7 @@ pub const Function = struct {
switch (c_value) {
.constant => |inst| {
const mod = f.object.dg.module;
- const ty = f.air.typeOf(inst);
+ const ty = f.typeOf(inst);
const val = f.air.value(inst, mod).?;
try w.writeAll("(*");
try f.object.dg.renderValue(w, ty, val, .Other);
@@ -382,7 +382,7 @@ pub const Function = struct {
switch (c_value) {
.constant => |inst| {
const mod = f.object.dg.module;
- const ty = f.air.typeOf(inst);
+ const ty = f.typeOf(inst);
const val = f.air.value(inst, mod).?;
try f.object.dg.renderValue(w, ty, val, .Other);
try w.writeByte('.');
@@ -396,7 +396,7 @@ pub const Function = struct {
switch (c_value) {
.constant => |inst| {
const mod = f.object.dg.module;
- const ty = f.air.typeOf(inst);
+ const ty = f.typeOf(inst);
const val = f.air.value(inst, mod).?;
try w.writeByte('(');
try f.object.dg.renderValue(w, ty, val, .Other);
@@ -486,6 +486,16 @@ pub const Function = struct {
f.object.dg.ctypes.deinit(gpa);
f.object.dg.fwd_decl.deinit();
}
+
+ fn typeOf(f: *Function, inst: Air.Inst.Ref) Type {
+ const mod = f.object.dg.module;
+ 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);
+ }
};
/// This data is available when outputting .c code for a `Module`.
@@ -2802,17 +2812,19 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con
fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfMemory }!void {
const mod = f.object.dg.module;
+ const ip = &mod.intern_pool;
const air_tags = f.air.instructions.items(.tag);
for (body) |inst| {
- if (f.liveness.isUnused(inst) and !f.air.mustLower(inst)) {
+ if (f.liveness.isUnused(inst) and !f.air.mustLower(inst, ip.*))
continue;
- }
const result_value = switch (air_tags[inst]) {
// zig fmt: off
.constant => unreachable, // excluded from function bodies
.const_ty => unreachable, // excluded from function bodies
+ .interned => unreachable, // excluded from function bodies
+
.arg => try airArg(f, inst),
.trap => try airTrap(f.object.writer()),
@@ -2837,7 +2849,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
.div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .none),
.rem => blk: {
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
- const lhs_scalar_ty = f.air.typeOf(bin_op.lhs).scalarType(mod);
+ const lhs_scalar_ty = f.typeOf(bin_op.lhs).scalarType(mod);
// For binary operations @TypeOf(lhs)==@TypeOf(rhs),
// so we only check one.
break :blk if (lhs_scalar_ty.isInt(mod))
@@ -3088,7 +3100,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: []const u8) !CValue {
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
@@ -3107,7 +3119,7 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
@@ -3136,8 +3148,8 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
- const inst_ty = f.air.typeOfIndex(inst);
- const ptr_ty = f.air.typeOf(bin_op.lhs);
+ const inst_ty = f.typeOfIndex(inst);
+ const ptr_ty = f.typeOf(bin_op.lhs);
const elem_ty = ptr_ty.childType();
const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(mod);
@@ -3169,7 +3181,7 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
@@ -3198,8 +3210,8 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
- const inst_ty = f.air.typeOfIndex(inst);
- const slice_ty = f.air.typeOf(bin_op.lhs);
+ const inst_ty = f.typeOfIndex(inst);
+ const slice_ty = f.typeOf(bin_op.lhs);
const elem_ty = slice_ty.elemType2(mod);
const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(mod);
@@ -3226,7 +3238,7 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
return .none;
@@ -3251,7 +3263,7 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const elem_type = inst_ty.elemType();
if (!elem_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return .{ .undef = inst_ty };
@@ -3267,7 +3279,7 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const elem_ty = inst_ty.elemType();
if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return .{ .undef = inst_ty };
@@ -3282,7 +3294,7 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const inst_cty = try f.typeToIndex(inst_ty, .parameter);
const i = f.next_arg_index;
@@ -3309,7 +3321,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
- const ptr_ty = f.air.typeOf(ty_op.operand);
+ const ptr_ty = f.typeOf(ty_op.operand);
const ptr_scalar_ty = ptr_ty.scalarType(mod);
const ptr_info = ptr_scalar_ty.ptrInfo().data;
const src_ty = ptr_info.pointee_type;
@@ -3399,7 +3411,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
const un_op = f.air.instructions.items(.data)[inst].un_op;
const writer = f.object.writer();
const op_inst = Air.refToIndex(un_op);
- const op_ty = f.air.typeOf(un_op);
+ const op_ty = f.typeOf(un_op);
const ret_ty = if (is_ptr) op_ty.childType() else op_ty;
var lowered_ret_buf: LowerFnRetTyBuffer = undefined;
const lowered_ret_ty = lowerFnRetTy(ret_ty, &lowered_ret_buf, mod);
@@ -3453,9 +3465,9 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const inst_scalar_ty = inst_ty.scalarType(mod);
- const operand_ty = f.air.typeOf(ty_op.operand);
+ const operand_ty = f.typeOf(ty_op.operand);
const scalar_ty = operand_ty.scalarType(mod);
const writer = f.object.writer();
@@ -3478,13 +3490,13 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const inst_scalar_ty = inst_ty.scalarType(mod);
const dest_int_info = inst_scalar_ty.intInfo(mod);
const dest_bits = dest_int_info.bits;
const dest_c_bits = toCIntBits(dest_int_info.bits) orelse
return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
- const operand_ty = f.air.typeOf(ty_op.operand);
+ const operand_ty = f.typeOf(ty_op.operand);
const scalar_ty = operand_ty.scalarType(mod);
const scalar_int_info = scalar_ty.intInfo(mod);
@@ -3572,7 +3584,7 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {
const operand = try f.resolveInst(un_op);
try reap(f, inst, &.{un_op});
const writer = f.object.writer();
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const local = try f.allocLocal(inst, inst_ty);
const a = try Assignment.start(f, writer, inst_ty);
try f.writeCValue(writer, local, .Other);
@@ -3587,12 +3599,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
// *a = b;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
- const ptr_ty = f.air.typeOf(bin_op.lhs);
+ const ptr_ty = f.typeOf(bin_op.lhs);
const ptr_scalar_ty = ptr_ty.scalarType(mod);
const ptr_info = ptr_scalar_ty.ptrInfo().data;
const ptr_val = try f.resolveInst(bin_op.lhs);
- const src_ty = f.air.typeOf(bin_op.rhs);
+ const src_ty = f.typeOf(bin_op.rhs);
const val_is_undef = if (f.air.value(bin_op.rhs, mod)) |v| v.isUndefDeep() else false;
@@ -3737,8 +3749,8 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
const rhs = try f.resolveInst(bin_op.rhs);
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
- const inst_ty = f.air.typeOfIndex(inst);
- const operand_ty = f.air.typeOf(bin_op.lhs);
+ const inst_ty = f.typeOfIndex(inst);
+ const operand_ty = f.typeOf(bin_op.lhs);
const scalar_ty = operand_ty.scalarType(mod);
const w = f.object.writer();
@@ -3769,14 +3781,14 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
- const operand_ty = f.air.typeOf(ty_op.operand);
+ const operand_ty = f.typeOf(ty_op.operand);
const scalar_ty = operand_ty.scalarType(mod);
if (scalar_ty.tag() != .bool) return try airUnBuiltinCall(f, inst, "not", .bits);
const op = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
@@ -3802,7 +3814,7 @@ fn airBinOp(
) !CValue {
const mod = f.object.dg.module;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
- const operand_ty = f.air.typeOf(bin_op.lhs);
+ const operand_ty = f.typeOf(bin_op.lhs);
const scalar_ty = operand_ty.scalarType(mod);
if ((scalar_ty.isInt(mod) and scalar_ty.bitSize(mod) > 64) or scalar_ty.isRuntimeFloat())
return try airBinBuiltinCall(f, inst, operation, info);
@@ -3811,7 +3823,7 @@ fn airBinOp(
const rhs = try f.resolveInst(bin_op.rhs);
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
@@ -3839,7 +3851,7 @@ fn airCmpOp(
operator: std.math.CompareOperator,
) !CValue {
const mod = f.object.dg.module;
- const lhs_ty = f.air.typeOf(data.lhs);
+ const lhs_ty = f.typeOf(data.lhs);
const scalar_ty = lhs_ty.scalarType(mod);
const scalar_bits = scalar_ty.bitSize(mod);
@@ -3855,12 +3867,12 @@ fn airCmpOp(
if (scalar_ty.isRuntimeFloat())
return airCmpBuiltinCall(f, inst, data, operator, .operator, .none);
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const lhs = try f.resolveInst(data.lhs);
const rhs = try f.resolveInst(data.rhs);
try reap(f, inst, &.{ data.lhs, data.rhs });
- const rhs_ty = f.air.typeOf(data.rhs);
+ const rhs_ty = f.typeOf(data.rhs);
const need_cast = lhs_ty.isSinglePointer() or rhs_ty.isSinglePointer();
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
@@ -3891,7 +3903,7 @@ fn airEquality(
const mod = f.object.dg.module;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
- const operand_ty = f.air.typeOf(bin_op.lhs);
+ const operand_ty = f.typeOf(bin_op.lhs);
const operand_bits = operand_ty.bitSize(mod);
if (operand_ty.isInt(mod) and operand_bits > 64)
return airCmpBuiltinCall(
@@ -3910,7 +3922,7 @@ fn airEquality(
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
const writer = f.object.writer();
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const local = try f.allocLocal(inst, inst_ty);
try f.writeCValue(writer, local, .Other);
try writer.writeAll(" = ");
@@ -3954,7 +3966,7 @@ fn airEquality(
fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
const un_op = f.air.instructions.items(.data)[inst].un_op;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const operand = try f.resolveInst(un_op);
try reap(f, inst, &.{un_op});
@@ -3976,7 +3988,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
const rhs = try f.resolveInst(bin_op.rhs);
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const inst_scalar_ty = inst_ty.scalarType(mod);
const elem_ty = inst_scalar_ty.elemType2(mod);
@@ -4019,7 +4031,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
const mod = f.object.dg.module;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const inst_scalar_ty = inst_ty.scalarType(mod);
if (inst_scalar_ty.isInt(mod) and inst_scalar_ty.bitSize(mod) > 64)
@@ -4065,7 +4077,7 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
const len = try f.resolveInst(bin_op.rhs);
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = inst_ty.slicePtrFieldType(&buf);
@@ -4110,7 +4122,7 @@ fn airCall(
const resolved_args = try gpa.alloc(CValue, args.len);
defer gpa.free(resolved_args);
for (resolved_args, args) |*resolved_arg, arg| {
- const arg_ty = f.air.typeOf(arg);
+ const arg_ty = f.typeOf(arg);
const arg_cty = try f.typeToIndex(arg_ty, .parameter);
if (f.indexToCType(arg_cty).tag() == .void) {
resolved_arg.* = .none;
@@ -4141,7 +4153,7 @@ fn airCall(
for (args) |arg| try bt.feed(arg);
}
- const callee_ty = f.air.typeOf(pl_op.operand);
+ const callee_ty = f.typeOf(pl_op.operand);
const fn_ty = switch (callee_ty.zigTypeTag(mod)) {
.Fn => callee_ty,
.Pointer => callee_ty.childType(),
@@ -4279,7 +4291,7 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
f.next_block_index += 1;
const writer = f.object.writer();
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const result = if (inst_ty.tag() != .void and !f.liveness.isUnused(inst))
try f.allocLocal(inst, inst_ty)
else
@@ -4302,7 +4314,7 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
try f.object.indent_writer.insertNewline();
// noreturn blocks have no `br` instructions reaching them, so we don't want a label
- if (!f.air.typeOfIndex(inst).isNoReturn()) {
+ if (!f.typeOfIndex(inst).isNoReturn()) {
// label must be followed by an expression, include an empty one.
try writer.print("zig_block_{d}:;\n", .{block_id});
}
@@ -4314,7 +4326,7 @@ fn airTry(f: *Function, inst: Air.Inst.Index) !CValue {
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
const extra = f.air.extraData(Air.Try, pl_op.payload);
const body = f.air.extra[extra.end..][0..extra.data.body_len];
- const err_union_ty = f.air.typeOf(pl_op.operand);
+ const err_union_ty = f.typeOf(pl_op.operand);
return lowerTry(f, inst, pl_op.operand, body, err_union_ty, false);
}
@@ -4322,7 +4334,7 @@ fn airTryPtr(f: *Function, inst: Air.Inst.Index) !CValue {
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const extra = f.air.extraData(Air.TryPtr, ty_pl.payload);
const body = f.air.extra[extra.end..][0..extra.data.body_len];
- const err_union_ty = f.air.typeOf(extra.data.ptr).childType();
+ const err_union_ty = f.typeOf(extra.data.ptr).childType();
return lowerTry(f, inst, extra.data.ptr, body, err_union_ty, true);
}
@@ -4336,7 +4348,7 @@ fn lowerTry(
) !CValue {
const mod = f.object.dg.module;
const err_union = try f.resolveInst(operand);
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const liveness_condbr = f.liveness.getCondBr(inst);
const writer = f.object.writer();
const payload_ty = err_union_ty.errorUnionPayload();
@@ -4404,7 +4416,7 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {
// If result is .none then the value of the block is unused.
if (result != .none) {
- const operand_ty = f.air.typeOf(branch.operand);
+ const operand_ty = f.typeOf(branch.operand);
const operand = try f.resolveInst(branch.operand);
try reap(f, inst, &.{branch.operand});
@@ -4421,10 +4433,10 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {
fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
- const dest_ty = f.air.typeOfIndex(inst);
+ const dest_ty = f.typeOfIndex(inst);
const operand = try f.resolveInst(ty_op.operand);
- const operand_ty = f.air.typeOf(ty_op.operand);
+ const operand_ty = f.typeOf(ty_op.operand);
const bitcasted = try bitcast(f, dest_ty, operand, operand_ty);
try reap(f, inst, &.{ty_op.operand});
@@ -4684,7 +4696,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
const condition = try f.resolveInst(pl_op.operand);
try reap(f, inst, &.{pl_op.operand});
- const condition_ty = f.air.typeOf(pl_op.operand);
+ const condition_ty = f.typeOf(pl_op.operand);
const switch_br = f.air.extraData(Air.SwitchBr, pl_op.payload);
const writer = f.object.writer();
@@ -4784,7 +4796,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
const result = result: {
const writer = f.object.writer();
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const local = if (inst_ty.hasRuntimeBitsIgnoreComptime(mod)) local: {
const local = try f.allocLocal(inst, inst_ty);
if (f.wantSafety()) {
@@ -4814,7 +4826,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
const is_reg = constraint[1] == '{';
if (is_reg) {
- const output_ty = if (output == .none) inst_ty else f.air.typeOf(output).childType();
+ const output_ty = if (output == .none) inst_ty else f.typeOf(output).childType();
try writer.writeAll("register ");
const alignment = 0;
const local_value = try f.allocLocalValue(output_ty, alignment);
@@ -4847,7 +4859,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
const is_reg = constraint[0] == '{';
const input_val = try f.resolveInst(input);
if (asmInputNeedsLocal(constraint, input_val)) {
- const input_ty = f.air.typeOf(input);
+ const input_ty = f.typeOf(input);
if (is_reg) try writer.writeAll("register ");
const alignment = 0;
const local_value = try f.allocLocalValue(input_ty, alignment);
@@ -5048,7 +5060,7 @@ fn airIsNull(
try f.writeCValue(writer, operand, .Other);
}
- const operand_ty = f.air.typeOf(un_op);
+ const operand_ty = f.typeOf(un_op);
const optional_ty = if (is_ptr) operand_ty.childType() else operand_ty;
var payload_buf: Type.Payload.ElemType = undefined;
const payload_ty = optional_ty.optionalChild(&payload_buf);
@@ -5083,7 +5095,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
- const opt_ty = f.air.typeOf(ty_op.operand);
+ const opt_ty = f.typeOf(ty_op.operand);
var buf: Type.Payload.ElemType = undefined;
const payload_ty = opt_ty.optionalChild(&buf);
@@ -5092,7 +5104,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
return .none;
}
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
@@ -5119,9 +5131,9 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
const writer = f.object.writer();
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
- const ptr_ty = f.air.typeOf(ty_op.operand);
+ const ptr_ty = f.typeOf(ty_op.operand);
const opt_ty = ptr_ty.childType();
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
if (!inst_ty.childType().hasRuntimeBitsIgnoreComptime(mod)) {
return .{ .undef = inst_ty };
@@ -5149,11 +5161,11 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
const writer = f.object.writer();
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
- const operand_ty = f.air.typeOf(ty_op.operand);
+ const operand_ty = f.typeOf(ty_op.operand);
const opt_ty = operand_ty.elemType();
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
if (opt_ty.optionalReprIsPayload(mod)) {
if (f.liveness.isUnused(inst)) {
@@ -5249,7 +5261,7 @@ fn airStructFieldPtr(f: *Function, inst: Air.Inst.Index) !CValue {
const container_ptr_val = try f.resolveInst(extra.struct_operand);
try reap(f, inst, &.{extra.struct_operand});
- const container_ptr_ty = f.air.typeOf(extra.struct_operand);
+ const container_ptr_ty = f.typeOf(extra.struct_operand);
return fieldPtr(f, inst, container_ptr_ty, container_ptr_val, extra.field_index);
}
@@ -5258,7 +5270,7 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue
const container_ptr_val = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
- const container_ptr_ty = f.air.typeOf(ty_op.operand);
+ const container_ptr_ty = f.typeOf(ty_op.operand);
return fieldPtr(f, inst, container_ptr_ty, container_ptr_val, index);
}
@@ -5267,10 +5279,10 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
- const container_ptr_ty = f.air.typeOfIndex(inst);
+ const container_ptr_ty = f.typeOfIndex(inst);
const container_ty = container_ptr_ty.childType();
- const field_ptr_ty = f.air.typeOf(extra.field_ptr);
+ const field_ptr_ty = f.typeOf(extra.field_ptr);
const field_ptr_val = try f.resolveInst(extra.field_ptr);
try reap(f, inst, &.{extra.field_ptr});
@@ -5334,7 +5346,7 @@ fn fieldPtr(
) !CValue {
const mod = f.object.dg.module;
const container_ty = container_ptr_ty.elemType();
- const field_ptr_ty = f.air.typeOfIndex(inst);
+ const field_ptr_ty = f.typeOfIndex(inst);
// Ensure complete type definition is visible before accessing fields.
_ = try f.typeToIndex(container_ty, .complete);
@@ -5385,7 +5397,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
try reap(f, inst, &.{extra.struct_operand});
return .none;
@@ -5393,7 +5405,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
const struct_byval = try f.resolveInst(extra.struct_operand);
try reap(f, inst, &.{extra.struct_operand});
- const struct_ty = f.air.typeOf(extra.struct_operand);
+ const struct_ty = f.typeOf(extra.struct_operand);
const writer = f.object.writer();
// Ensure complete type definition is visible before accessing fields.
@@ -5514,9 +5526,9 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const operand = try f.resolveInst(ty_op.operand);
- const operand_ty = f.air.typeOf(ty_op.operand);
+ const operand_ty = f.typeOf(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
const operand_is_ptr = operand_ty.zigTypeTag(mod) == .Pointer;
@@ -5553,10 +5565,10 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
- const operand_ty = f.air.typeOf(ty_op.operand);
+ const operand_ty = f.typeOf(ty_op.operand);
const error_union_ty = if (is_ptr) operand_ty.childType() else operand_ty;
const writer = f.object.writer();
@@ -5589,9 +5601,9 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const repr_is_payload = inst_ty.optionalReprIsPayload(mod);
- const payload_ty = f.air.typeOf(ty_op.operand);
+ const payload_ty = f.typeOf(ty_op.operand);
const payload = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
@@ -5621,7 +5633,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const payload_ty = inst_ty.errorUnionPayload();
const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(mod);
const err_ty = inst_ty.errorUnionSet();
@@ -5661,7 +5673,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
const writer = f.object.writer();
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const operand = try f.resolveInst(ty_op.operand);
- const error_union_ty = f.air.typeOf(ty_op.operand).childType();
+ const error_union_ty = f.typeOf(ty_op.operand).childType();
const error_ty = error_union_ty.errorUnionSet();
const payload_ty = error_union_ty.errorUnionPayload();
@@ -5684,7 +5696,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
// Then return the payload pointer (only if it is used)
if (f.liveness.isUnused(inst)) return .none;
- const local = try f.allocLocal(inst, f.air.typeOfIndex(inst));
+ const local = try f.allocLocal(inst, f.typeOfIndex(inst));
try f.writeCValue(writer, local, .Other);
try writer.writeAll(" = &(");
try f.writeCValueDeref(writer, operand);
@@ -5711,7 +5723,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const payload_ty = inst_ty.errorUnionPayload();
const payload = try f.resolveInst(ty_op.operand);
const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(mod);
@@ -5747,7 +5759,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
const writer = f.object.writer();
const operand = try f.resolveInst(un_op);
try reap(f, inst, &.{un_op});
- const operand_ty = f.air.typeOf(un_op);
+ const operand_ty = f.typeOf(un_op);
const local = try f.allocLocal(inst, Type.bool);
const err_union_ty = if (is_ptr) operand_ty.childType() else operand_ty;
const payload_ty = err_union_ty.errorUnionPayload();
@@ -5780,10 +5792,10 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
- const array_ty = f.air.typeOf(ty_op.operand).childType();
+ const array_ty = f.typeOf(ty_op.operand).childType();
try f.writeCValueMember(writer, local, .{ .identifier = "ptr" });
try writer.writeAll(" = ");
@@ -5812,10 +5824,10 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
- const operand_ty = f.air.typeOf(ty_op.operand);
+ const operand_ty = f.typeOf(ty_op.operand);
const target = f.object.dg.module.getTarget();
const operation = if (inst_ty.isRuntimeFloat() and operand_ty.isRuntimeFloat())
if (inst_ty.floatBits(target) < operand_ty.floatBits(target)) "trunc" else "extend"
@@ -5855,9 +5867,9 @@ fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue {
const un_op = f.air.instructions.items(.data)[inst].un_op;
const operand = try f.resolveInst(un_op);
- const operand_ty = f.air.typeOf(un_op);
+ const operand_ty = f.typeOf(un_op);
try reap(f, inst, &.{un_op});
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
try f.writeCValue(writer, local, .Other);
@@ -5885,9 +5897,9 @@ fn airUnBuiltinCall(
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const inst_scalar_ty = inst_ty.scalarType(mod);
- const operand_ty = f.air.typeOf(ty_op.operand);
+ const operand_ty = f.typeOf(ty_op.operand);
const scalar_ty = operand_ty.scalarType(mod);
const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);
@@ -5927,7 +5939,7 @@ fn airBinBuiltinCall(
const mod = f.object.dg.module;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
- const operand_ty = f.air.typeOf(bin_op.lhs);
+ const operand_ty = f.typeOf(bin_op.lhs);
const operand_cty = try f.typeToCType(operand_ty, .complete);
const is_big = operand_cty.tag() == .array;
@@ -5935,7 +5947,7 @@ fn airBinBuiltinCall(
const rhs = try f.resolveInst(bin_op.rhs);
if (!is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const inst_scalar_ty = inst_ty.scalarType(mod);
const scalar_ty = operand_ty.scalarType(mod);
@@ -5984,9 +5996,9 @@ fn airCmpBuiltinCall(
const rhs = try f.resolveInst(data.rhs);
try reap(f, inst, &.{ data.lhs, data.rhs });
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const inst_scalar_ty = inst_ty.scalarType(mod);
- const operand_ty = f.air.typeOf(data.lhs);
+ const operand_ty = f.typeOf(data.lhs);
const scalar_ty = operand_ty.scalarType(mod);
const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);
@@ -6032,11 +6044,11 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
const mod = f.object.dg.module;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const ptr = try f.resolveInst(extra.ptr);
const expected_value = try f.resolveInst(extra.expected_value);
const new_value = try f.resolveInst(extra.new_value);
- const ptr_ty = f.air.typeOf(extra.ptr);
+ const ptr_ty = f.typeOf(extra.ptr);
const ty = ptr_ty.childType();
const writer = f.object.writer();
@@ -6137,8 +6149,8 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data;
- const inst_ty = f.air.typeOfIndex(inst);
- const ptr_ty = f.air.typeOf(pl_op.operand);
+ const inst_ty = f.typeOfIndex(inst);
+ const ptr_ty = f.typeOf(pl_op.operand);
const ty = ptr_ty.childType();
const ptr = try f.resolveInst(pl_op.operand);
const operand = try f.resolveInst(extra.operand);
@@ -6193,7 +6205,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
const atomic_load = f.air.instructions.items(.data)[inst].atomic_load;
const ptr = try f.resolveInst(atomic_load.ptr);
try reap(f, inst, &.{atomic_load.ptr});
- const ptr_ty = f.air.typeOf(atomic_load.ptr);
+ const ptr_ty = f.typeOf(atomic_load.ptr);
const ty = ptr_ty.childType();
const repr_ty = if (ty.isRuntimeFloat())
@@ -6201,7 +6213,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
else
ty;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
@@ -6227,7 +6239,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue {
const mod = f.object.dg.module;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
- const ptr_ty = f.air.typeOf(bin_op.lhs);
+ const ptr_ty = f.typeOf(bin_op.lhs);
const ty = ptr_ty.childType();
const ptr = try f.resolveInst(bin_op.lhs);
const element = try f.resolveInst(bin_op.rhs);
@@ -6270,10 +6282,10 @@ fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !vo
fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
const mod = f.object.dg.module;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
- const dest_ty = f.air.typeOf(bin_op.lhs);
+ const dest_ty = f.typeOf(bin_op.lhs);
const dest_slice = try f.resolveInst(bin_op.lhs);
const value = try f.resolveInst(bin_op.rhs);
- const elem_ty = f.air.typeOf(bin_op.rhs);
+ const elem_ty = f.typeOf(bin_op.rhs);
const elem_abi_size = elem_ty.abiSize(mod);
const val_is_undef = if (f.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false;
const writer = f.object.writer();
@@ -6393,8 +6405,8 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
const dest_ptr = try f.resolveInst(bin_op.lhs);
const src_ptr = try f.resolveInst(bin_op.rhs);
- const dest_ty = f.air.typeOf(bin_op.lhs);
- const src_ty = f.air.typeOf(bin_op.rhs);
+ const dest_ty = f.typeOf(bin_op.lhs);
+ const src_ty = f.typeOf(bin_op.rhs);
const writer = f.object.writer();
try writer.writeAll("memcpy(");
@@ -6434,7 +6446,7 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
const new_tag = try f.resolveInst(bin_op.rhs);
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
- const union_ty = f.air.typeOf(bin_op.lhs).childType();
+ const union_ty = f.typeOf(bin_op.lhs).childType();
const layout = union_ty.unionGetLayout(mod);
if (layout.tag_size == 0) return .none;
const tag_ty = union_ty.unionTagTypeSafety().?;
@@ -6455,11 +6467,11 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
- const union_ty = f.air.typeOf(ty_op.operand);
+ const union_ty = f.typeOf(ty_op.operand);
const layout = union_ty.unionGetLayout(mod);
if (layout.tag_size == 0) return .none;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
const a = try Assignment.start(f, writer, inst_ty);
@@ -6473,8 +6485,8 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
const un_op = f.air.instructions.items(.data)[inst].un_op;
- const inst_ty = f.air.typeOfIndex(inst);
- const enum_ty = f.air.typeOf(un_op);
+ const inst_ty = f.typeOfIndex(inst);
+ const enum_ty = f.typeOf(un_op);
const operand = try f.resolveInst(un_op);
try reap(f, inst, &.{un_op});
@@ -6494,7 +6506,7 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
const un_op = f.air.instructions.items(.data)[inst].un_op;
const writer = f.object.writer();
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const operand = try f.resolveInst(un_op);
try reap(f, inst, &.{un_op});
const local = try f.allocLocal(inst, inst_ty);
@@ -6513,7 +6525,7 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const inst_scalar_ty = inst_ty.scalarType(mod);
const writer = f.object.writer();
@@ -6539,7 +6551,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
const rhs = try f.resolveInst(extra.rhs);
try reap(f, inst, &.{ pl_op.operand, extra.lhs, extra.rhs });
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
@@ -6570,7 +6582,7 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
const lhs = try f.resolveInst(extra.a);
const rhs = try f.resolveInst(extra.b);
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
@@ -6607,10 +6619,10 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
const reduce = f.air.instructions.items(.data)[inst].reduce;
const target = mod.getTarget();
- const scalar_ty = f.air.typeOfIndex(inst);
+ const scalar_ty = f.typeOfIndex(inst);
const operand = try f.resolveInst(reduce.operand);
try reap(f, inst, &.{reduce.operand});
- const operand_ty = f.air.typeOf(reduce.operand);
+ const operand_ty = f.typeOf(reduce.operand);
const writer = f.object.writer();
const use_operator = scalar_ty.bitSize(mod) <= 64;
@@ -6762,7 +6774,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const len = @intCast(usize, inst_ty.arrayLen());
const elements = @ptrCast([]const Air.Inst.Ref, f.air.extra[ty_pl.payload..][0..len]);
const gpa = f.object.dg.gpa;
@@ -6892,10 +6904,10 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;
- const union_ty = f.air.typeOfIndex(inst);
+ const union_ty = f.typeOfIndex(inst);
const union_obj = union_ty.cast(Type.Payload.Union).?.data;
const field_name = union_obj.fields.keys()[extra.field_index];
- const payload_ty = f.air.typeOf(extra.init);
+ const payload_ty = f.typeOf(extra.init);
const payload = try f.resolveInst(extra.init);
try reap(f, inst, &.{extra.init});
@@ -6965,7 +6977,7 @@ fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
const writer = f.object.writer();
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const local = try f.allocLocal(inst, inst_ty);
try f.writeCValue(writer, local, .Other);
@@ -6979,7 +6991,7 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
const writer = f.object.writer();
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const operand = try f.resolveInst(pl_op.operand);
try reap(f, inst, &.{pl_op.operand});
const local = try f.allocLocal(inst, inst_ty);
@@ -6999,7 +7011,7 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {
const operand = try f.resolveInst(un_op);
try reap(f, inst, &.{un_op});
- const operand_ty = f.air.typeOf(un_op);
+ const operand_ty = f.typeOf(un_op);
const scalar_ty = operand_ty.scalarType(mod);
const writer = f.object.writer();
@@ -7025,7 +7037,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal
const operand = try f.resolveInst(un_op);
try reap(f, inst, &.{un_op});
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const inst_scalar_ty = inst_ty.scalarType(mod);
const writer = f.object.writer();
@@ -7054,7 +7066,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa
const rhs = try f.resolveInst(bin_op.rhs);
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const inst_scalar_ty = inst_ty.scalarType(mod);
const writer = f.object.writer();
@@ -7088,7 +7100,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
const addend = try f.resolveInst(pl_op.operand);
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs, pl_op.operand });
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const inst_scalar_ty = inst_ty.scalarType(mod);
const writer = f.object.writer();
@@ -7114,7 +7126,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const fn_cty = try f.typeToCType(f.object.dg.decl.?.ty, .complete);
const param_len = fn_cty.castTag(.varargs_function).?.data.param_types.len;
@@ -7133,7 +7145,7 @@ fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
fn airCVaArg(f: *Function, inst: Air.Inst.Index) !CValue {
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const va_list = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
@@ -7164,7 +7176,7 @@ fn airCVaEnd(f: *Function, inst: Air.Inst.Index) !CValue {
fn airCVaCopy(f: *Function, inst: Air.Inst.Index) !CValue {
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
- const inst_ty = f.air.typeOfIndex(inst);
+ const inst_ty = f.typeOfIndex(inst);
const va_list = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
src/codegen/llvm.zig
@@ -4497,7 +4497,7 @@ pub const FuncGen = struct {
const mod = self.dg.module;
const llvm_val = try self.resolveValue(.{
- .ty = self.air.typeOf(inst),
+ .ty = self.typeOf(inst),
.val = self.air.value(inst, mod).?,
});
gop.value_ptr.* = llvm_val;
@@ -4528,11 +4528,12 @@ pub const FuncGen = struct {
}
fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {
+ const mod = self.dg.module;
+ 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)) {
+ if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
continue;
- }
const opt_value: ?*llvm.Value = switch (air_tags[inst]) {
// zig fmt: off
@@ -4751,6 +4752,8 @@ pub const FuncGen = struct {
.constant => unreachable,
.const_ty => unreachable,
+ .interned => unreachable,
+
.unreach => self.airUnreach(inst),
.dbg_stmt => self.airDbgStmt(inst),
.dbg_inline_begin => try self.airDbgInlineBegin(inst),
@@ -4781,7 +4784,7 @@ pub const FuncGen = struct {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const extra = self.air.extraData(Air.Call, pl_op.payload);
const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
- const callee_ty = self.air.typeOf(pl_op.operand);
+ const callee_ty = self.typeOf(pl_op.operand);
const mod = self.dg.module;
const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) {
.Fn => callee_ty,
@@ -4815,7 +4818,7 @@ pub const FuncGen = struct {
.no_bits => continue,
.byval => {
const arg = args[it.zig_index - 1];
- const param_ty = self.air.typeOf(arg);
+ const param_ty = self.typeOf(arg);
const llvm_arg = try self.resolveInst(arg);
const llvm_param_ty = try self.dg.lowerType(param_ty);
if (isByRef(param_ty, mod)) {
@@ -4829,7 +4832,7 @@ pub const FuncGen = struct {
},
.byref => {
const arg = args[it.zig_index - 1];
- const param_ty = self.air.typeOf(arg);
+ const param_ty = self.typeOf(arg);
const llvm_arg = try self.resolveInst(arg);
if (isByRef(param_ty, mod)) {
try llvm_args.append(llvm_arg);
@@ -4844,7 +4847,7 @@ pub const FuncGen = struct {
},
.byref_mut => {
const arg = args[it.zig_index - 1];
- const param_ty = self.air.typeOf(arg);
+ const param_ty = self.typeOf(arg);
const llvm_arg = try self.resolveInst(arg);
const alignment = param_ty.abiAlignment(mod);
@@ -4865,7 +4868,7 @@ pub const FuncGen = struct {
},
.abi_sized_int => {
const arg = args[it.zig_index - 1];
- const param_ty = self.air.typeOf(arg);
+ const param_ty = self.typeOf(arg);
const llvm_arg = try self.resolveInst(arg);
const abi_size = @intCast(c_uint, param_ty.abiSize(mod));
const int_llvm_ty = self.context.intType(abi_size * 8);
@@ -4901,7 +4904,7 @@ pub const FuncGen = struct {
},
.multiple_llvm_types => {
const arg = args[it.zig_index - 1];
- const param_ty = self.air.typeOf(arg);
+ const param_ty = self.typeOf(arg);
const llvm_types = it.llvm_types_buffer[0..it.llvm_types_len];
const llvm_arg = try self.resolveInst(arg);
const is_by_ref = isByRef(param_ty, mod);
@@ -4930,7 +4933,7 @@ pub const FuncGen = struct {
},
.float_array => |count| {
const arg = args[it.zig_index - 1];
- const arg_ty = self.air.typeOf(arg);
+ const arg_ty = self.typeOf(arg);
var llvm_arg = try self.resolveInst(arg);
if (!isByRef(arg_ty, mod)) {
const p = self.buildAlloca(llvm_arg.typeOf(), null);
@@ -4950,7 +4953,7 @@ pub const FuncGen = struct {
.i32_array, .i64_array => |arr_len| {
const elem_size: u8 = if (lowering == .i32_array) 32 else 64;
const arg = args[it.zig_index - 1];
- const arg_ty = self.air.typeOf(arg);
+ const arg_ty = self.typeOf(arg);
var llvm_arg = try self.resolveInst(arg);
if (!isByRef(arg_ty, mod)) {
const p = self.buildAlloca(llvm_arg.typeOf(), null);
@@ -5094,7 +5097,7 @@ pub const FuncGen = struct {
fn airRet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const mod = self.dg.module;
const un_op = self.air.instructions.items(.data)[inst].un_op;
- const ret_ty = self.air.typeOf(un_op);
+ const ret_ty = self.typeOf(un_op);
if (self.ret_ptr) |ret_ptr| {
const operand = try self.resolveInst(un_op);
var ptr_ty_payload: Type.Payload.ElemType = .{
@@ -5150,7 +5153,7 @@ pub const FuncGen = struct {
fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const un_op = self.air.instructions.items(.data)[inst].un_op;
- const ptr_ty = self.air.typeOf(un_op);
+ const ptr_ty = self.typeOf(un_op);
const ret_ty = ptr_ty.childType();
const fn_info = self.dg.decl.ty.fnInfo();
const mod = self.dg.module;
@@ -5236,7 +5239,7 @@ pub const FuncGen = struct {
fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const mod = self.dg.module;
- const va_list_ty = self.air.typeOfIndex(inst);
+ const va_list_ty = self.typeOfIndex(inst);
const llvm_va_list_ty = try self.dg.lowerType(va_list_ty);
const result_alignment = va_list_ty.abiAlignment(mod);
@@ -5266,7 +5269,7 @@ pub const FuncGen = struct {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const operand_ty = self.air.typeOf(bin_op.lhs);
+ const operand_ty = self.typeOf(bin_op.lhs);
return self.cmp(lhs, rhs, operand_ty, op);
}
@@ -5279,7 +5282,7 @@ pub const FuncGen = struct {
const lhs = try self.resolveInst(extra.lhs);
const rhs = try self.resolveInst(extra.rhs);
- const vec_ty = self.air.typeOf(extra.lhs);
+ const vec_ty = self.typeOf(extra.lhs);
const cmp_op = extra.compareOperator();
return self.cmp(lhs, rhs, vec_ty, cmp_op);
@@ -5396,12 +5399,12 @@ pub const FuncGen = struct {
}
fn airBlock(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
+ const mod = self.dg.module;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const extra = self.air.extraData(Air.Block, ty_pl.payload);
const body = self.air.extra[extra.end..][0..extra.data.body_len];
- const inst_ty = self.air.typeOfIndex(inst);
+ const inst_ty = self.typeOfIndex(inst);
const parent_bb = self.context.createBasicBlock("Block");
- const mod = self.dg.module;
if (inst_ty.isNoReturn()) {
try self.genBody(body);
@@ -5453,7 +5456,7 @@ pub const FuncGen = struct {
const block = self.blocks.get(branch.block_inst).?;
// Add the values to the lists only if the break provides a value.
- const operand_ty = self.air.typeOf(branch.operand);
+ const operand_ty = self.typeOf(branch.operand);
const mod = self.dg.module;
if (operand_ty.hasRuntimeBitsIgnoreComptime(mod) or operand_ty.zigTypeTag(mod) == .Fn) {
const val = try self.resolveInst(branch.operand);
@@ -5497,8 +5500,8 @@ pub const FuncGen = struct {
const err_union = try self.resolveInst(pl_op.operand);
const extra = self.air.extraData(Air.Try, pl_op.payload);
const body = self.air.extra[extra.end..][0..extra.data.body_len];
- const err_union_ty = self.air.typeOf(pl_op.operand);
- const payload_ty = self.air.typeOfIndex(inst);
+ const err_union_ty = self.typeOf(pl_op.operand);
+ const payload_ty = self.typeOfIndex(inst);
const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false;
const is_unused = self.liveness.isUnused(inst);
return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused);
@@ -5509,7 +5512,7 @@ pub const FuncGen = struct {
const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);
const err_union_ptr = try self.resolveInst(extra.data.ptr);
const body = self.air.extra[extra.end..][0..extra.data.body_len];
- const err_union_ty = self.air.typeOf(extra.data.ptr).childType();
+ const err_union_ty = self.typeOf(extra.data.ptr).childType();
const is_unused = self.liveness.isUnused(inst);
return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused);
}
@@ -5650,7 +5653,7 @@ pub const FuncGen = struct {
// would have been emitted already. Also the main loop in genBody can
// be while(true) instead of for(body), which will eliminate 1 branch on
// a hot path.
- if (body.len == 0 or !self.air.typeOfIndex(body[body.len - 1]).isNoReturn()) {
+ if (body.len == 0 or !self.typeOfIndex(body[body.len - 1]).isNoReturn()) {
_ = self.builder.buildBr(loop_block);
}
return null;
@@ -5659,11 +5662,11 @@ pub const FuncGen = struct {
fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const mod = self.dg.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const operand_ty = self.air.typeOf(ty_op.operand);
+ const operand_ty = self.typeOf(ty_op.operand);
const array_ty = operand_ty.childType();
const llvm_usize = try self.dg.lowerType(Type.usize);
const len = llvm_usize.constInt(array_ty.arrayLen(), .False);
- const slice_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst));
+ const slice_llvm_ty = try self.dg.lowerType(self.typeOfIndex(inst));
const operand = try self.resolveInst(ty_op.operand);
if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), operand, 0, "");
@@ -5683,10 +5686,10 @@ pub const FuncGen = struct {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand = try self.resolveInst(ty_op.operand);
- const operand_ty = self.air.typeOf(ty_op.operand);
+ const operand_ty = self.typeOf(ty_op.operand);
const operand_scalar_ty = operand_ty.scalarType(mod);
- const dest_ty = self.air.typeOfIndex(inst);
+ const dest_ty = self.typeOfIndex(inst);
const dest_scalar_ty = dest_ty.scalarType(mod);
const dest_llvm_ty = try self.dg.lowerType(dest_ty);
const target = mod.getTarget();
@@ -5743,10 +5746,10 @@ pub const FuncGen = struct {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand = try self.resolveInst(ty_op.operand);
- const operand_ty = self.air.typeOf(ty_op.operand);
+ const operand_ty = self.typeOf(ty_op.operand);
const operand_scalar_ty = operand_ty.scalarType(mod);
- const dest_ty = self.air.typeOfIndex(inst);
+ const dest_ty = self.typeOfIndex(inst);
const dest_scalar_ty = dest_ty.scalarType(mod);
const dest_llvm_ty = try self.dg.lowerType(dest_ty);
@@ -5832,7 +5835,7 @@ pub const FuncGen = struct {
fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*llvm.Value {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const slice_ptr = try self.resolveInst(ty_op.operand);
- const slice_ptr_ty = self.air.typeOf(ty_op.operand);
+ const slice_ptr_ty = self.typeOf(ty_op.operand);
const slice_llvm_ty = try self.dg.lowerPtrElemTy(slice_ptr_ty.childType());
return self.builder.buildStructGEP(slice_llvm_ty, slice_ptr, index, "");
@@ -5842,7 +5845,7 @@ pub const FuncGen = struct {
const mod = self.dg.module;
const inst = body_tail[0];
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const slice_ty = self.air.typeOf(bin_op.lhs);
+ const slice_ty = self.typeOf(bin_op.lhs);
const slice = try self.resolveInst(bin_op.lhs);
const index = try self.resolveInst(bin_op.rhs);
const elem_ty = slice_ty.childType();
@@ -5863,7 +5866,7 @@ pub const FuncGen = struct {
fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
- const slice_ty = self.air.typeOf(bin_op.lhs);
+ const slice_ty = self.typeOf(bin_op.lhs);
const slice = try self.resolveInst(bin_op.lhs);
const index = try self.resolveInst(bin_op.rhs);
@@ -5878,7 +5881,7 @@ pub const FuncGen = struct {
const inst = body_tail[0];
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const array_ty = self.air.typeOf(bin_op.lhs);
+ const array_ty = self.typeOf(bin_op.lhs);
const array_llvm_val = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
const array_llvm_ty = try self.dg.lowerType(array_ty);
@@ -5920,7 +5923,7 @@ pub const FuncGen = struct {
const mod = self.dg.module;
const inst = body_tail[0];
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const elem_ty = ptr_ty.childType();
const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);
const base_ptr = try self.resolveInst(bin_op.lhs);
@@ -5948,7 +5951,7 @@ pub const FuncGen = struct {
const mod = self.dg.module;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const elem_ty = ptr_ty.childType();
if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty);
@@ -5973,7 +5976,7 @@ pub const FuncGen = struct {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
const struct_ptr = try self.resolveInst(struct_field.struct_operand);
- const struct_ptr_ty = self.air.typeOf(struct_field.struct_operand);
+ const struct_ptr_ty = self.typeOf(struct_field.struct_operand);
return self.fieldPtr(inst, struct_ptr, struct_ptr_ty, struct_field.field_index);
}
@@ -5984,7 +5987,7 @@ pub const FuncGen = struct {
) !?*llvm.Value {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const struct_ptr = try self.resolveInst(ty_op.operand);
- const struct_ptr_ty = self.air.typeOf(ty_op.operand);
+ const struct_ptr_ty = self.typeOf(ty_op.operand);
return self.fieldPtr(inst, struct_ptr, struct_ptr_ty, field_index);
}
@@ -5993,7 +5996,7 @@ pub const FuncGen = struct {
const inst = body_tail[0];
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
- const struct_ty = self.air.typeOf(struct_field.struct_operand);
+ const struct_ty = self.typeOf(struct_field.struct_operand);
const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);
const field_index = struct_field.field_index;
const field_ty = struct_ty.structFieldType(field_index);
@@ -6234,7 +6237,7 @@ pub const FuncGen = struct {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const operand = try self.resolveInst(pl_op.operand);
const name = self.air.nullTerminatedString(pl_op.payload);
- const ptr_ty = self.air.typeOf(pl_op.operand);
+ const ptr_ty = self.typeOf(pl_op.operand);
const di_local_var = dib.createAutoVariable(
self.di_scope.?,
@@ -6259,7 +6262,7 @@ pub const FuncGen = struct {
const dib = self.dg.object.di_builder orelse return null;
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const operand = try self.resolveInst(pl_op.operand);
- const operand_ty = self.air.typeOf(pl_op.operand);
+ const operand_ty = self.typeOf(pl_op.operand);
const name = self.air.nullTerminatedString(pl_op.payload);
if (needDbgVarWorkaround(self.dg)) {
@@ -6361,7 +6364,7 @@ pub const FuncGen = struct {
llvm_ret_indirect[i] = (output != .none) and constraintAllowsMemory(constraint);
if (output != .none) {
const output_inst = try self.resolveInst(output);
- const output_ty = self.air.typeOf(output);
+ const output_ty = self.typeOf(output);
assert(output_ty.zigTypeTag(mod) == .Pointer);
const elem_llvm_ty = try self.dg.lowerPtrElemTy(output_ty.childType());
@@ -6379,7 +6382,7 @@ pub const FuncGen = struct {
llvm_ret_i += 1;
}
} else {
- const ret_ty = self.air.typeOfIndex(inst);
+ const ret_ty = self.typeOfIndex(inst);
llvm_ret_types[llvm_ret_i] = try self.dg.lowerType(ret_ty);
llvm_ret_i += 1;
}
@@ -6414,7 +6417,7 @@ pub const FuncGen = struct {
extra_i += (constraint.len + name.len + (2 + 3)) / 4;
const arg_llvm_value = try self.resolveInst(input);
- const arg_ty = self.air.typeOf(input);
+ const arg_ty = self.typeOf(input);
var llvm_elem_ty: ?*llvm.Type = null;
if (isByRef(arg_ty, mod)) {
llvm_elem_ty = try self.dg.lowerPtrElemTy(arg_ty);
@@ -6636,7 +6639,7 @@ pub const FuncGen = struct {
if (output != .none) {
const output_ptr = try self.resolveInst(output);
- const output_ptr_ty = self.air.typeOf(output);
+ const output_ptr_ty = self.typeOf(output);
const store_inst = self.builder.buildStore(output_value, output_ptr);
store_inst.setAlignment(output_ptr_ty.ptrAlignment(mod));
@@ -6657,7 +6660,7 @@ pub const FuncGen = struct {
) !?*llvm.Value {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const operand = try self.resolveInst(un_op);
- const operand_ty = self.air.typeOf(un_op);
+ const operand_ty = self.typeOf(un_op);
const optional_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
const optional_llvm_ty = try self.dg.lowerType(optional_ty);
var buf: Type.Payload.ElemType = undefined;
@@ -6706,7 +6709,7 @@ pub const FuncGen = struct {
const mod = self.dg.module;
const un_op = self.air.instructions.items(.data)[inst].un_op;
const operand = try self.resolveInst(un_op);
- const operand_ty = self.air.typeOf(un_op);
+ const operand_ty = self.typeOf(un_op);
const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
const payload_ty = err_union_ty.errorUnionPayload();
const err_set_ty = try self.dg.lowerType(Type.anyerror);
@@ -6746,7 +6749,7 @@ pub const FuncGen = struct {
const mod = self.dg.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand = try self.resolveInst(ty_op.operand);
- const optional_ty = self.air.typeOf(ty_op.operand).childType();
+ const optional_ty = self.typeOf(ty_op.operand).childType();
var buf: Type.Payload.ElemType = undefined;
const payload_ty = optional_ty.optionalChild(&buf);
if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
@@ -6768,7 +6771,7 @@ pub const FuncGen = struct {
const mod = self.dg.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand = try self.resolveInst(ty_op.operand);
- const optional_ty = self.air.typeOf(ty_op.operand).childType();
+ const optional_ty = self.typeOf(ty_op.operand).childType();
var buf: Type.Payload.ElemType = undefined;
const payload_ty = optional_ty.optionalChild(&buf);
const non_null_bit = self.context.intType(8).constInt(1, .False);
@@ -6801,8 +6804,8 @@ pub const FuncGen = struct {
const inst = body_tail[0];
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand = try self.resolveInst(ty_op.operand);
- const optional_ty = self.air.typeOf(ty_op.operand);
- const payload_ty = self.air.typeOfIndex(inst);
+ const optional_ty = self.typeOf(ty_op.operand);
+ const payload_ty = self.typeOfIndex(inst);
if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
if (optional_ty.optionalReprIsPayload(mod)) {
@@ -6824,9 +6827,9 @@ pub const FuncGen = struct {
const inst = body_tail[0];
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand = try self.resolveInst(ty_op.operand);
- const operand_ty = self.air.typeOf(ty_op.operand);
+ const operand_ty = self.typeOf(ty_op.operand);
const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
- const result_ty = self.air.typeOfIndex(inst);
+ const result_ty = self.typeOfIndex(inst);
const payload_ty = if (operand_is_ptr) result_ty.childType() else result_ty;
if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
@@ -6859,7 +6862,7 @@ pub const FuncGen = struct {
const mod = self.dg.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand = try self.resolveInst(ty_op.operand);
- const operand_ty = self.air.typeOf(ty_op.operand);
+ const operand_ty = self.typeOf(ty_op.operand);
const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
const err_llvm_ty = try self.dg.lowerType(Type.anyerror);
@@ -6893,7 +6896,7 @@ pub const FuncGen = struct {
const mod = self.dg.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand = try self.resolveInst(ty_op.operand);
- const err_union_ty = self.air.typeOf(ty_op.operand).childType();
+ const err_union_ty = self.typeOf(ty_op.operand).childType();
const payload_ty = err_union_ty.errorUnionPayload();
const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = Value.zero });
@@ -6946,12 +6949,12 @@ pub const FuncGen = struct {
fn airWrapOptional(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const mod = self.dg.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const payload_ty = self.air.typeOf(ty_op.operand);
+ const payload_ty = self.typeOf(ty_op.operand);
const non_null_bit = self.context.intType(8).constInt(1, .False);
comptime assert(optional_layout_version == 3);
if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return non_null_bit;
const operand = try self.resolveInst(ty_op.operand);
- const optional_ty = self.air.typeOfIndex(inst);
+ const optional_ty = self.typeOfIndex(inst);
if (optional_ty.optionalReprIsPayload(mod)) {
return operand;
}
@@ -6976,9 +6979,9 @@ pub const FuncGen = struct {
fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const mod = self.dg.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const err_un_ty = self.air.typeOfIndex(inst);
+ const err_un_ty = self.typeOfIndex(inst);
const operand = try self.resolveInst(ty_op.operand);
- const payload_ty = self.air.typeOf(ty_op.operand);
+ const payload_ty = self.typeOf(ty_op.operand);
if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
return operand;
}
@@ -7009,7 +7012,7 @@ pub const FuncGen = struct {
fn airWrapErrUnionErr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const mod = self.dg.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const err_un_ty = self.air.typeOfIndex(inst);
+ const err_un_ty = self.typeOfIndex(inst);
const payload_ty = err_un_ty.errorUnionPayload();
const operand = try self.resolveInst(ty_op.operand);
if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
@@ -7069,7 +7072,7 @@ pub const FuncGen = struct {
const extra = self.air.extraData(Air.Bin, data.payload).data;
const vector_ptr = try self.resolveInst(data.vector_ptr);
- const vector_ptr_ty = self.air.typeOf(data.vector_ptr);
+ const vector_ptr_ty = self.typeOf(data.vector_ptr);
const index = try self.resolveInst(extra.lhs);
const operand = try self.resolveInst(extra.rhs);
@@ -7090,7 +7093,7 @@ pub const FuncGen = struct {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const scalar_ty = self.air.typeOfIndex(inst).scalarType(mod);
+ const scalar_ty = self.typeOfIndex(inst).scalarType(mod);
if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmin, scalar_ty, 2, .{ lhs, rhs });
if (scalar_ty.isSignedInt(mod)) return self.builder.buildSMin(lhs, rhs, "");
@@ -7102,7 +7105,7 @@ pub const FuncGen = struct {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const scalar_ty = self.air.typeOfIndex(inst).scalarType(mod);
+ const scalar_ty = self.typeOfIndex(inst).scalarType(mod);
if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmax, scalar_ty, 2, .{ lhs, rhs });
if (scalar_ty.isSignedInt(mod)) return self.builder.buildSMax(lhs, rhs, "");
@@ -7114,7 +7117,7 @@ pub const FuncGen = struct {
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const ptr = try self.resolveInst(bin_op.lhs);
const len = try self.resolveInst(bin_op.rhs);
- const inst_ty = self.air.typeOfIndex(inst);
+ const inst_ty = self.typeOfIndex(inst);
const llvm_slice_ty = try self.dg.lowerType(inst_ty);
// In case of slicing a global, the result type looks something like `{ i8*, i64 }`
@@ -7130,7 +7133,7 @@ pub const FuncGen = struct {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const inst_ty = self.air.typeOfIndex(inst);
+ const inst_ty = self.typeOfIndex(inst);
const scalar_ty = inst_ty.scalarType(mod);
if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.add, inst_ty, 2, .{ lhs, rhs });
@@ -7153,7 +7156,7 @@ pub const FuncGen = struct {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const inst_ty = self.air.typeOfIndex(inst);
+ const inst_ty = self.typeOfIndex(inst);
const scalar_ty = inst_ty.scalarType(mod);
if (scalar_ty.isAnyFloat()) return self.todo("saturating float add", .{});
@@ -7169,7 +7172,7 @@ pub const FuncGen = struct {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const inst_ty = self.air.typeOfIndex(inst);
+ const inst_ty = self.typeOfIndex(inst);
const scalar_ty = inst_ty.scalarType(mod);
if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.sub, inst_ty, 2, .{ lhs, rhs });
@@ -7192,7 +7195,7 @@ pub const FuncGen = struct {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const inst_ty = self.air.typeOfIndex(inst);
+ const inst_ty = self.typeOfIndex(inst);
const scalar_ty = inst_ty.scalarType(mod);
if (scalar_ty.isAnyFloat()) return self.todo("saturating float sub", .{});
@@ -7207,7 +7210,7 @@ pub const FuncGen = struct {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const inst_ty = self.air.typeOfIndex(inst);
+ const inst_ty = self.typeOfIndex(inst);
const scalar_ty = inst_ty.scalarType(mod);
if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.mul, inst_ty, 2, .{ lhs, rhs });
@@ -7230,7 +7233,7 @@ pub const FuncGen = struct {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const inst_ty = self.air.typeOfIndex(inst);
+ const inst_ty = self.typeOfIndex(inst);
const scalar_ty = inst_ty.scalarType(mod);
if (scalar_ty.isAnyFloat()) return self.todo("saturating float mul", .{});
@@ -7244,7 +7247,7 @@ pub const FuncGen = struct {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const inst_ty = self.air.typeOfIndex(inst);
+ const inst_ty = self.typeOfIndex(inst);
return self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs });
}
@@ -7256,7 +7259,7 @@ pub const FuncGen = struct {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const inst_ty = self.air.typeOfIndex(inst);
+ const inst_ty = self.typeOfIndex(inst);
const scalar_ty = inst_ty.scalarType(mod);
if (scalar_ty.isRuntimeFloat()) {
@@ -7274,7 +7277,7 @@ pub const FuncGen = struct {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const inst_ty = self.air.typeOfIndex(inst);
+ const inst_ty = self.typeOfIndex(inst);
const scalar_ty = inst_ty.scalarType(mod);
if (scalar_ty.isRuntimeFloat()) {
@@ -7314,7 +7317,7 @@ pub const FuncGen = struct {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const inst_ty = self.air.typeOfIndex(inst);
+ const inst_ty = self.typeOfIndex(inst);
const scalar_ty = inst_ty.scalarType(mod);
if (scalar_ty.isRuntimeFloat()) return self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs });
@@ -7329,7 +7332,7 @@ pub const FuncGen = struct {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const inst_ty = self.air.typeOfIndex(inst);
+ const inst_ty = self.typeOfIndex(inst);
const scalar_ty = inst_ty.scalarType(mod);
if (scalar_ty.isRuntimeFloat()) return self.buildFloatOp(.fmod, inst_ty, 2, .{ lhs, rhs });
@@ -7344,7 +7347,7 @@ pub const FuncGen = struct {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const inst_ty = self.air.typeOfIndex(inst);
+ const inst_ty = self.typeOfIndex(inst);
const inst_llvm_ty = try self.dg.lowerType(inst_ty);
const scalar_ty = inst_ty.scalarType(mod);
@@ -7386,7 +7389,7 @@ pub const FuncGen = struct {
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const ptr = try self.resolveInst(bin_op.lhs);
const offset = try self.resolveInst(bin_op.rhs);
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType());
switch (ptr_ty.ptrSize()) {
.One => {
@@ -7412,7 +7415,7 @@ pub const FuncGen = struct {
const ptr = try self.resolveInst(bin_op.lhs);
const offset = try self.resolveInst(bin_op.rhs);
const negative_offset = self.builder.buildNeg(offset, "");
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType());
switch (ptr_ty.ptrSize()) {
.One => {
@@ -7447,9 +7450,9 @@ pub const FuncGen = struct {
const lhs = try self.resolveInst(extra.lhs);
const rhs = try self.resolveInst(extra.rhs);
- const lhs_ty = self.air.typeOf(extra.lhs);
+ const lhs_ty = self.typeOf(extra.lhs);
const scalar_ty = lhs_ty.scalarType(mod);
- const dest_ty = self.air.typeOfIndex(inst);
+ const dest_ty = self.typeOfIndex(inst);
const intrinsic_name = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic;
@@ -7735,7 +7738,7 @@ pub const FuncGen = struct {
const mulend2 = try self.resolveInst(extra.rhs);
const addend = try self.resolveInst(pl_op.operand);
- const ty = self.air.typeOfIndex(inst);
+ const ty = self.typeOfIndex(inst);
return self.buildFloatOp(.fma, ty, 3, .{ mulend1, mulend2, addend });
}
@@ -7747,12 +7750,12 @@ pub const FuncGen = struct {
const lhs = try self.resolveInst(extra.lhs);
const rhs = try self.resolveInst(extra.rhs);
- const lhs_ty = self.air.typeOf(extra.lhs);
- const rhs_ty = self.air.typeOf(extra.rhs);
+ const lhs_ty = self.typeOf(extra.lhs);
+ const rhs_ty = self.typeOf(extra.rhs);
const lhs_scalar_ty = lhs_ty.scalarType(mod);
const rhs_scalar_ty = rhs_ty.scalarType(mod);
- const dest_ty = self.air.typeOfIndex(inst);
+ const dest_ty = self.typeOfIndex(inst);
const llvm_dest_ty = try self.dg.lowerType(dest_ty);
const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))
@@ -7821,8 +7824,8 @@ pub const FuncGen = struct {
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
const lhs_scalar_ty = lhs_ty.scalarType(mod);
const rhs_scalar_ty = rhs_ty.scalarType(mod);
@@ -7841,8 +7844,8 @@ pub const FuncGen = struct {
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const lhs_type = self.air.typeOf(bin_op.lhs);
- const rhs_type = self.air.typeOf(bin_op.rhs);
+ const lhs_type = self.typeOf(bin_op.lhs);
+ const rhs_type = self.typeOf(bin_op.rhs);
const lhs_scalar_ty = lhs_type.scalarType(mod);
const rhs_scalar_ty = rhs_type.scalarType(mod);
@@ -7860,8 +7863,8 @@ pub const FuncGen = struct {
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
const lhs_scalar_ty = lhs_ty.scalarType(mod);
const rhs_scalar_ty = rhs_ty.scalarType(mod);
const lhs_bits = lhs_scalar_ty.bitSize(mod);
@@ -7903,8 +7906,8 @@ pub const FuncGen = struct {
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- const lhs_ty = self.air.typeOf(bin_op.lhs);
- const rhs_ty = self.air.typeOf(bin_op.rhs);
+ const lhs_ty = self.typeOf(bin_op.lhs);
+ const rhs_ty = self.typeOf(bin_op.rhs);
const lhs_scalar_ty = lhs_ty.scalarType(mod);
const rhs_scalar_ty = rhs_ty.scalarType(mod);
@@ -7932,11 +7935,11 @@ pub const FuncGen = struct {
fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const mod = self.dg.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const dest_ty = self.air.typeOfIndex(inst);
+ const dest_ty = self.typeOfIndex(inst);
const dest_info = dest_ty.intInfo(mod);
const dest_llvm_ty = try self.dg.lowerType(dest_ty);
const operand = try self.resolveInst(ty_op.operand);
- const operand_ty = self.air.typeOf(ty_op.operand);
+ const operand_ty = self.typeOf(ty_op.operand);
const operand_info = operand_ty.intInfo(mod);
if (operand_info.bits < dest_info.bits) {
@@ -7954,7 +7957,7 @@ pub const FuncGen = struct {
fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand = try self.resolveInst(ty_op.operand);
- const dest_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst));
+ const dest_llvm_ty = try self.dg.lowerType(self.typeOfIndex(inst));
return self.builder.buildTrunc(operand, dest_llvm_ty, "");
}
@@ -7962,8 +7965,8 @@ pub const FuncGen = struct {
const mod = self.dg.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand = try self.resolveInst(ty_op.operand);
- const operand_ty = self.air.typeOf(ty_op.operand);
- const dest_ty = self.air.typeOfIndex(inst);
+ const operand_ty = self.typeOf(ty_op.operand);
+ const dest_ty = self.typeOfIndex(inst);
const target = mod.getTarget();
const dest_bits = dest_ty.floatBits(target);
const src_bits = operand_ty.floatBits(target);
@@ -7992,8 +7995,8 @@ pub const FuncGen = struct {
const mod = self.dg.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand = try self.resolveInst(ty_op.operand);
- const operand_ty = self.air.typeOf(ty_op.operand);
- const dest_ty = self.air.typeOfIndex(inst);
+ const operand_ty = self.typeOf(ty_op.operand);
+ const dest_ty = self.typeOfIndex(inst);
const target = mod.getTarget();
const dest_bits = dest_ty.floatBits(target);
const src_bits = operand_ty.floatBits(target);
@@ -8021,16 +8024,16 @@ pub const FuncGen = struct {
fn airPtrToInt(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const operand = try self.resolveInst(un_op);
- const ptr_ty = self.air.typeOf(un_op);
+ const ptr_ty = self.typeOf(un_op);
const operand_ptr = self.sliceOrArrayPtr(operand, ptr_ty);
- const dest_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst));
+ const dest_llvm_ty = try self.dg.lowerType(self.typeOfIndex(inst));
return self.builder.buildPtrToInt(operand_ptr, dest_llvm_ty, "");
}
fn airBitCast(self: *FuncGen, inst: Air.Inst.Index) !*llvm.Value {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const operand_ty = self.air.typeOf(ty_op.operand);
- const inst_ty = self.air.typeOfIndex(inst);
+ const operand_ty = self.typeOf(ty_op.operand);
+ const inst_ty = self.typeOfIndex(inst);
const operand = try self.resolveInst(ty_op.operand);
return self.bitCast(operand, operand_ty, inst_ty);
}
@@ -8159,17 +8162,17 @@ pub const FuncGen = struct {
}
fn airArg(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
+ const mod = self.dg.module;
const arg_val = self.args[self.arg_index];
self.arg_index += 1;
- const inst_ty = self.air.typeOfIndex(inst);
+ const inst_ty = self.typeOfIndex(inst);
if (self.dg.object.di_builder) |dib| {
if (needDbgVarWorkaround(self.dg)) {
return arg_val;
}
const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
- const mod = self.dg.module;
const func = self.dg.decl.getFunction().?;
const lbrace_line = mod.declPtr(func.owner_decl).src_line + func.lbrace_line + 1;
const lbrace_col = func.lbrace_column + 1;
@@ -8203,9 +8206,9 @@ pub const FuncGen = struct {
}
fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
- const ptr_ty = self.air.typeOfIndex(inst);
- const pointee_type = ptr_ty.childType();
const mod = self.dg.module;
+ const ptr_ty = self.typeOfIndex(inst);
+ const pointee_type = ptr_ty.childType();
if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty);
const pointee_llvm_ty = try self.dg.lowerType(pointee_type);
@@ -8214,9 +8217,9 @@ pub const FuncGen = struct {
}
fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
- const ptr_ty = self.air.typeOfIndex(inst);
- const ret_ty = ptr_ty.childType();
const mod = self.dg.module;
+ const ptr_ty = self.typeOfIndex(inst);
+ const ret_ty = ptr_ty.childType();
if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty);
if (self.ret_ptr) |ret_ptr| return ret_ptr;
const ret_llvm_ty = try self.dg.lowerType(ret_ty);
@@ -8232,7 +8235,7 @@ pub const FuncGen = struct {
fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !?*llvm.Value {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const dest_ptr = try self.resolveInst(bin_op.lhs);
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const operand_ty = ptr_ty.childType();
const mod = self.dg.module;
@@ -8285,7 +8288,7 @@ pub const FuncGen = struct {
const mod = fg.dg.module;
const inst = body_tail[0];
const ty_op = fg.air.instructions.items(.data)[inst].ty_op;
- const ptr_ty = fg.air.typeOf(ty_op.operand);
+ const ptr_ty = fg.typeOf(ty_op.operand);
const ptr_info = ptr_ty.ptrInfo().data;
const ptr = try fg.resolveInst(ty_op.operand);
@@ -8361,7 +8364,7 @@ pub const FuncGen = struct {
const ptr = try self.resolveInst(extra.ptr);
var expected_value = try self.resolveInst(extra.expected_value);
var new_value = try self.resolveInst(extra.new_value);
- const operand_ty = self.air.typeOf(extra.ptr).elemType();
+ const operand_ty = self.typeOf(extra.ptr).elemType();
const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
if (opt_abi_ty) |abi_ty| {
// operand needs widening and truncating
@@ -8383,7 +8386,7 @@ pub const FuncGen = struct {
);
result.setWeak(llvm.Bool.fromBool(is_weak));
- const optional_ty = self.air.typeOfIndex(inst);
+ const optional_ty = self.typeOfIndex(inst);
var payload = self.builder.buildExtractValue(result, 0, "");
if (opt_abi_ty != null) {
@@ -8406,7 +8409,7 @@ pub const FuncGen = struct {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;
const ptr = try self.resolveInst(pl_op.operand);
- const ptr_ty = self.air.typeOf(pl_op.operand);
+ const ptr_ty = self.typeOf(pl_op.operand);
const operand_ty = ptr_ty.elemType();
const operand = try self.resolveInst(extra.operand);
const is_signed_int = operand_ty.isSignedInt(mod);
@@ -8461,7 +8464,7 @@ pub const FuncGen = struct {
const mod = self.dg.module;
const atomic_load = self.air.instructions.items(.data)[inst].atomic_load;
const ptr = try self.resolveInst(atomic_load.ptr);
- const ptr_ty = self.air.typeOf(atomic_load.ptr);
+ const ptr_ty = self.typeOf(atomic_load.ptr);
const ptr_info = ptr_ty.ptrInfo().data;
const elem_ty = ptr_info.pointee_type;
if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod))
@@ -8494,7 +8497,7 @@ pub const FuncGen = struct {
) !?*llvm.Value {
const mod = self.dg.module;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const operand_ty = ptr_ty.childType();
if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return null;
const ptr = try self.resolveInst(bin_op.lhs);
@@ -8517,8 +8520,8 @@ pub const FuncGen = struct {
const mod = self.dg.module;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const dest_slice = try self.resolveInst(bin_op.lhs);
- const ptr_ty = self.air.typeOf(bin_op.lhs);
- const elem_ty = self.air.typeOf(bin_op.rhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
+ const elem_ty = self.typeOf(bin_op.rhs);
const module = self.dg.module;
const target = module.getTarget();
const dest_ptr_align = ptr_ty.ptrAlignment(mod);
@@ -8641,9 +8644,9 @@ pub const FuncGen = struct {
fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const dest_slice = try self.resolveInst(bin_op.lhs);
- const dest_ptr_ty = self.air.typeOf(bin_op.lhs);
+ const dest_ptr_ty = self.typeOf(bin_op.lhs);
const src_slice = try self.resolveInst(bin_op.rhs);
- const src_ptr_ty = self.air.typeOf(bin_op.rhs);
+ const src_ptr_ty = self.typeOf(bin_op.rhs);
const src_ptr = self.sliceOrArrayPtr(src_slice, src_ptr_ty);
const len = self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty);
const dest_ptr = self.sliceOrArrayPtr(dest_slice, dest_ptr_ty);
@@ -8663,7 +8666,7 @@ pub const FuncGen = struct {
fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const mod = self.dg.module;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const un_ty = self.air.typeOf(bin_op.lhs).childType();
+ const un_ty = self.typeOf(bin_op.lhs).childType();
const layout = un_ty.unionGetLayout(mod);
if (layout.tag_size == 0) return null;
const union_ptr = try self.resolveInst(bin_op.lhs);
@@ -8684,7 +8687,7 @@ pub const FuncGen = struct {
fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const mod = self.dg.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const un_ty = self.air.typeOf(ty_op.operand);
+ const un_ty = self.typeOf(ty_op.operand);
const layout = un_ty.unionGetLayout(mod);
if (layout.tag_size == 0) return null;
const union_handle = try self.resolveInst(ty_op.operand);
@@ -8708,7 +8711,7 @@ pub const FuncGen = struct {
fn airUnaryOp(self: *FuncGen, inst: Air.Inst.Index, comptime op: FloatOp) !?*llvm.Value {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const operand = try self.resolveInst(un_op);
- const operand_ty = self.air.typeOf(un_op);
+ const operand_ty = self.typeOf(un_op);
return self.buildFloatOp(op, operand_ty, 1, .{operand});
}
@@ -8718,7 +8721,7 @@ pub const FuncGen = struct {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const operand = try self.resolveInst(un_op);
- const operand_ty = self.air.typeOf(un_op);
+ const operand_ty = self.typeOf(un_op);
return self.buildFloatOp(.neg, operand_ty, 1, .{operand});
}
@@ -8726,7 +8729,7 @@ pub const FuncGen = struct {
fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {
const mod = self.dg.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const operand_ty = self.air.typeOf(ty_op.operand);
+ const operand_ty = self.typeOf(ty_op.operand);
const operand = try self.resolveInst(ty_op.operand);
const llvm_i1 = self.context.intType(1);
@@ -8735,7 +8738,7 @@ pub const FuncGen = struct {
const params = [_]*llvm.Value{ operand, llvm_i1.constNull() };
const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, ¶ms, params.len, .C, .Auto, "");
- const result_ty = self.air.typeOfIndex(inst);
+ const result_ty = self.typeOfIndex(inst);
const result_llvm_ty = try self.dg.lowerType(result_ty);
const bits = operand_ty.intInfo(mod).bits;
@@ -8752,7 +8755,7 @@ pub const FuncGen = struct {
fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {
const mod = self.dg.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const operand_ty = self.air.typeOf(ty_op.operand);
+ const operand_ty = self.typeOf(ty_op.operand);
const operand = try self.resolveInst(ty_op.operand);
const params = [_]*llvm.Value{operand};
@@ -8760,7 +8763,7 @@ pub const FuncGen = struct {
const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, ¶ms, params.len, .C, .Auto, "");
- const result_ty = self.air.typeOfIndex(inst);
+ const result_ty = self.typeOfIndex(inst);
const result_llvm_ty = try self.dg.lowerType(result_ty);
const bits = operand_ty.intInfo(mod).bits;
@@ -8777,7 +8780,7 @@ pub const FuncGen = struct {
fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {
const mod = self.dg.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const operand_ty = self.air.typeOf(ty_op.operand);
+ const operand_ty = self.typeOf(ty_op.operand);
var bits = operand_ty.intInfo(mod).bits;
assert(bits % 8 == 0);
@@ -8815,7 +8818,7 @@ pub const FuncGen = struct {
const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, ¶ms, params.len, .C, .Auto, "");
- const result_ty = self.air.typeOfIndex(inst);
+ const result_ty = self.typeOfIndex(inst);
const result_llvm_ty = try self.dg.lowerType(result_ty);
const result_bits = result_ty.intInfo(mod).bits;
if (bits > result_bits) {
@@ -8876,7 +8879,7 @@ pub const FuncGen = struct {
fn airIsNamedEnumValue(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const operand = try self.resolveInst(un_op);
- const enum_ty = self.air.typeOf(un_op);
+ const enum_ty = self.typeOf(un_op);
const llvm_fn = try self.getIsNamedEnumValueFunction(enum_ty);
const params = [_]*llvm.Value{operand};
@@ -8954,7 +8957,7 @@ pub const FuncGen = struct {
fn airTagName(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const operand = try self.resolveInst(un_op);
- const enum_ty = self.air.typeOf(un_op);
+ const enum_ty = self.typeOf(un_op);
const llvm_fn = try self.getEnumTagNameFunction(enum_ty);
const params = [_]*llvm.Value{operand};
@@ -9083,7 +9086,7 @@ pub const FuncGen = struct {
fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const operand = try self.resolveInst(un_op);
- const slice_ty = self.air.typeOfIndex(inst);
+ const slice_ty = self.typeOfIndex(inst);
const slice_llvm_ty = try self.dg.lowerType(slice_ty);
const error_name_table_ptr = try self.getErrorNameTable();
@@ -9097,7 +9100,7 @@ pub const FuncGen = struct {
fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const scalar = try self.resolveInst(ty_op.operand);
- const vector_ty = self.air.typeOfIndex(inst);
+ const vector_ty = self.typeOfIndex(inst);
const len = vector_ty.vectorLen();
return self.builder.buildVectorSplat(len, scalar, "");
}
@@ -9120,7 +9123,7 @@ pub const FuncGen = struct {
const b = try self.resolveInst(extra.b);
const mask = self.air.values[extra.mask];
const mask_len = extra.mask_len;
- const a_len = self.air.typeOf(extra.a).vectorLen();
+ const a_len = self.typeOf(extra.a).vectorLen();
// LLVM uses integers larger than the length of the first array to
// index into the second array. This was deemed unnecessarily fragile
@@ -9219,8 +9222,8 @@ pub const FuncGen = struct {
const reduce = self.air.instructions.items(.data)[inst].reduce;
const operand = try self.resolveInst(reduce.operand);
- const operand_ty = self.air.typeOf(reduce.operand);
- const scalar_ty = self.air.typeOfIndex(inst);
+ const operand_ty = self.typeOf(reduce.operand);
+ const scalar_ty = self.typeOfIndex(inst);
switch (reduce.operation) {
.And => return self.builder.buildAndReduce(operand),
@@ -9300,12 +9303,12 @@ pub const FuncGen = struct {
}
fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
+ const mod = self.dg.module;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
- const result_ty = self.air.typeOfIndex(inst);
+ const result_ty = self.typeOfIndex(inst);
const len = @intCast(usize, result_ty.arrayLen());
const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
const llvm_result_ty = try self.dg.lowerType(result_ty);
- const mod = self.dg.module;
switch (result_ty.zigTypeTag(mod)) {
.Vector => {
@@ -9370,7 +9373,7 @@ pub const FuncGen = struct {
const field_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");
var field_ptr_payload: Type.Payload.Pointer = .{
.data = .{
- .pointee_type = self.air.typeOf(elem),
+ .pointee_type = self.typeOf(elem),
.@"align" = result_ty.structFieldAlign(i, mod),
.@"addrspace" = .generic,
},
@@ -9440,7 +9443,7 @@ pub const FuncGen = struct {
const mod = self.dg.module;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
- const union_ty = self.air.typeOfIndex(inst);
+ const union_ty = self.typeOfIndex(inst);
const union_llvm_ty = try self.dg.lowerType(union_ty);
const layout = union_ty.unionGetLayout(mod);
const union_obj = union_ty.cast(Type.Payload.Union).?.data;
@@ -9643,7 +9646,7 @@ pub const FuncGen = struct {
fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const inst_ty = self.air.typeOfIndex(inst);
+ const inst_ty = self.typeOfIndex(inst);
const operand = try self.resolveInst(ty_op.operand);
const llvm_dest_ty = try self.dg.lowerType(inst_ty);
@@ -9830,7 +9833,7 @@ pub const FuncGen = struct {
switch (struct_ty.zigTypeTag(mod)) {
.Struct => switch (struct_ty.containerLayout()) {
.Packed => {
- const result_ty = self.air.typeOfIndex(inst);
+ const result_ty = self.typeOfIndex(inst);
const result_ty_info = result_ty.ptrInfo().data;
if (result_ty_info.host_size != 0) {
@@ -10172,6 +10175,16 @@ pub const FuncGen = struct {
);
return call;
}
+
+ fn typeOf(fg: *FuncGen, inst: Air.Inst.Ref) Type {
+ const mod = fg.dg.module;
+ 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);
+ }
};
fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
@@ -10833,7 +10846,7 @@ const ParamTypeIterator = struct {
if (it.zig_index >= args.len) {
return null;
} else {
- return nextInner(it, fg.air.typeOf(args[it.zig_index]));
+ return nextInner(it, fg.typeOf(args[it.zig_index]));
}
} else {
return nextInner(it, it.fn_info.param_types[it.zig_index]);
src/codegen/spirv.zig
@@ -233,7 +233,7 @@ pub const DeclGen = struct {
fn resolve(self: *DeclGen, inst: Air.Inst.Ref) !IdRef {
const mod = self.module;
if (self.air.value(inst, mod)) |val| {
- const ty = self.air.typeOf(inst);
+ const ty = self.typeOf(inst);
if (ty.zigTypeTag(mod) == .Fn) {
const fn_decl_index = switch (val.tag()) {
.extern_fn => val.castTag(.extern_fn).?.data.owner_decl,
@@ -1720,10 +1720,11 @@ pub const DeclGen = struct {
}
fn genInst(self: *DeclGen, inst: Air.Inst.Index) !void {
+ 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)) {
+ if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
return;
- }
const air_tags = self.air.instructions.items(.tag);
const maybe_result_id: ?IdRef = switch (air_tags[inst]) {
@@ -1847,7 +1848,7 @@ pub const DeclGen = struct {
const lhs_id = try self.resolve(bin_op.lhs);
const rhs_id = try self.resolve(bin_op.rhs);
const result_id = self.spv.allocId();
- const result_type_id = try self.resolveTypeId(self.air.typeOfIndex(inst));
+ const result_type_id = try self.resolveTypeId(self.typeOfIndex(inst));
try self.func.body.emit(self.spv.gpa, opcode, .{
.id_result_type = result_type_id,
.id_result = result_id,
@@ -1862,7 +1863,7 @@ pub const DeclGen = struct {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs_id = try self.resolve(bin_op.lhs);
const rhs_id = try self.resolve(bin_op.rhs);
- const result_type_id = try self.resolveTypeId(self.air.typeOfIndex(inst));
+ const result_type_id = try self.resolveTypeId(self.typeOfIndex(inst));
// the shift and the base must be the same type in SPIR-V, but in Zig the shift is a smaller int.
const shift_id = self.spv.allocId();
@@ -1907,15 +1908,15 @@ pub const DeclGen = struct {
if (self.liveness.isUnused(inst)) return null;
// LHS and RHS are guaranteed to have the same type, and AIR guarantees
// the result to be the same as the LHS and RHS, which matches SPIR-V.
- const ty = self.air.typeOfIndex(inst);
+ const ty = self.typeOfIndex(inst);
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
var lhs_id = try self.resolve(bin_op.lhs);
var rhs_id = try self.resolve(bin_op.rhs);
const result_ty_ref = try self.resolveType(ty, .direct);
- assert(self.air.typeOf(bin_op.lhs).eql(ty, self.module));
- assert(self.air.typeOf(bin_op.rhs).eql(ty, self.module));
+ assert(self.typeOf(bin_op.lhs).eql(ty, self.module));
+ assert(self.typeOf(bin_op.rhs).eql(ty, self.module));
// Binary operations are generally applicable to both scalar and vector operations
// in SPIR-V, but int and float versions of operations require different opcodes.
@@ -1971,8 +1972,8 @@ pub const DeclGen = struct {
const lhs = try self.resolve(extra.lhs);
const rhs = try self.resolve(extra.rhs);
- const operand_ty = self.air.typeOf(extra.lhs);
- const result_ty = self.air.typeOfIndex(inst);
+ const operand_ty = self.typeOf(extra.lhs);
+ const result_ty = self.typeOfIndex(inst);
const info = try self.arithmeticTypeInfo(operand_ty);
switch (info.class) {
@@ -2064,14 +2065,14 @@ pub const DeclGen = struct {
fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
const mod = self.module;
if (self.liveness.isUnused(inst)) return null;
- const ty = self.air.typeOfIndex(inst);
+ const ty = self.typeOfIndex(inst);
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
const a = try self.resolve(extra.a);
const b = try self.resolve(extra.b);
const mask = self.air.values[extra.mask];
const mask_len = extra.mask_len;
- const a_len = self.air.typeOf(extra.a).vectorLen();
+ const a_len = self.typeOf(extra.a).vectorLen();
const result_id = self.spv.allocId();
const result_type_id = try self.resolveTypeId(ty);
@@ -2162,8 +2163,8 @@ pub const DeclGen = struct {
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const ptr_id = try self.resolve(bin_op.lhs);
const offset_id = try self.resolve(bin_op.rhs);
- const ptr_ty = self.air.typeOf(bin_op.lhs);
- const result_ty = self.air.typeOfIndex(inst);
+ const ptr_ty = self.typeOf(bin_op.lhs);
+ const result_ty = self.typeOfIndex(inst);
return try self.ptrAdd(result_ty, ptr_ty, ptr_id, offset_id);
}
@@ -2173,11 +2174,11 @@ pub const DeclGen = struct {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const ptr_id = try self.resolve(bin_op.lhs);
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const offset_id = try self.resolve(bin_op.rhs);
- const offset_ty = self.air.typeOf(bin_op.rhs);
+ const offset_ty = self.typeOf(bin_op.rhs);
const offset_ty_ref = try self.resolveType(offset_ty, .direct);
- const result_ty = self.air.typeOfIndex(inst);
+ const result_ty = self.typeOfIndex(inst);
const negative_offset_id = self.spv.allocId();
try self.func.body.emit(self.spv.gpa, .OpSNegate, .{
@@ -2298,8 +2299,8 @@ pub const DeclGen = struct {
const lhs_id = try self.resolve(bin_op.lhs);
const rhs_id = try self.resolve(bin_op.rhs);
const bool_ty_id = try self.resolveTypeId(Type.bool);
- const ty = self.air.typeOf(bin_op.lhs);
- assert(ty.eql(self.air.typeOf(bin_op.rhs), self.module));
+ const ty = self.typeOf(bin_op.lhs);
+ assert(ty.eql(self.typeOf(bin_op.rhs), self.module));
return try self.cmp(op, bool_ty_id, ty, lhs_id, rhs_id);
}
@@ -2337,8 +2338,8 @@ pub const DeclGen = struct {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand_id = try self.resolve(ty_op.operand);
- const operand_ty = self.air.typeOf(ty_op.operand);
- const result_ty = self.air.typeOfIndex(inst);
+ const operand_ty = self.typeOf(ty_op.operand);
+ const result_ty = self.typeOfIndex(inst);
return try self.bitCast(result_ty, operand_ty, operand_id);
}
@@ -2347,7 +2348,7 @@ pub const DeclGen = struct {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand_id = try self.resolve(ty_op.operand);
- const dest_ty = self.air.typeOfIndex(inst);
+ const dest_ty = self.typeOfIndex(inst);
const dest_ty_id = try self.resolveTypeId(dest_ty);
const mod = self.module;
@@ -2391,10 +2392,10 @@ pub const DeclGen = struct {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const operand_ty = self.air.typeOf(ty_op.operand);
+ const operand_ty = self.typeOf(ty_op.operand);
const operand_id = try self.resolve(ty_op.operand);
const operand_info = try self.arithmeticTypeInfo(operand_ty);
- const dest_ty = self.air.typeOfIndex(inst);
+ const dest_ty = self.typeOfIndex(inst);
const dest_ty_id = try self.resolveTypeId(dest_ty);
const result_id = self.spv.allocId();
@@ -2418,7 +2419,7 @@ pub const DeclGen = struct {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand_id = try self.resolve(ty_op.operand);
- const dest_ty = self.air.typeOfIndex(inst);
+ const dest_ty = self.typeOfIndex(inst);
const dest_info = try self.arithmeticTypeInfo(dest_ty);
const dest_ty_id = try self.resolveTypeId(dest_ty);
@@ -2455,20 +2456,20 @@ pub const DeclGen = struct {
fn airSliceField(self: *DeclGen, inst: Air.Inst.Index, field: u32) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const field_ty = self.air.typeOfIndex(inst);
+ const field_ty = self.typeOfIndex(inst);
const operand_id = try self.resolve(ty_op.operand);
return try self.extractField(field_ty, operand_id, field);
}
fn airSliceElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const slice_ty = self.air.typeOf(bin_op.lhs);
+ const slice_ty = self.typeOf(bin_op.lhs);
if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
const slice_id = try self.resolve(bin_op.lhs);
const index_id = try self.resolve(bin_op.rhs);
- const ptr_ty = self.air.typeOfIndex(inst);
+ const ptr_ty = self.typeOfIndex(inst);
const ptr_ty_ref = try self.resolveType(ptr_ty, .direct);
const slice_ptr = try self.extractField(ptr_ty, slice_id, 0);
@@ -2477,7 +2478,7 @@ pub const DeclGen = struct {
fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const slice_ty = self.air.typeOf(bin_op.lhs);
+ const slice_ty = self.typeOf(bin_op.lhs);
if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
const slice_id = try self.resolve(bin_op.lhs);
@@ -2514,7 +2515,7 @@ pub const DeclGen = struct {
const mod = self.module;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const elem_ty = ptr_ty.childType();
// TODO: Make this return a null ptr or something
if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
@@ -2526,7 +2527,7 @@ pub const DeclGen = struct {
fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const ptr_id = try self.resolve(bin_op.lhs);
const index_id = try self.resolve(bin_op.rhs);
@@ -2544,7 +2545,7 @@ pub const DeclGen = struct {
fn airGetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const un_ty = self.air.typeOf(ty_op.operand);
+ const un_ty = self.typeOf(ty_op.operand);
const mod = self.module;
const layout = un_ty.unionGetLayout(mod);
@@ -2565,7 +2566,7 @@ pub const DeclGen = struct {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
- const struct_ty = self.air.typeOf(struct_field.struct_operand);
+ const struct_ty = self.typeOf(struct_field.struct_operand);
const object_id = try self.resolve(struct_field.struct_operand);
const field_index = struct_field.field_index;
const field_ty = struct_ty.structFieldType(field_index);
@@ -2604,8 +2605,8 @@ pub const DeclGen = struct {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const struct_ptr = try self.resolve(ty_op.operand);
- const struct_ptr_ty = self.air.typeOf(ty_op.operand);
- const result_ptr_ty = self.air.typeOfIndex(inst);
+ const struct_ptr_ty = self.typeOf(ty_op.operand);
+ const result_ptr_ty = self.typeOfIndex(inst);
return try self.structFieldPtr(result_ptr_ty, struct_ptr_ty, struct_ptr, field_index);
}
@@ -2661,7 +2662,7 @@ pub const DeclGen = struct {
fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
- const ptr_ty = self.air.typeOfIndex(inst);
+ const ptr_ty = self.typeOfIndex(inst);
assert(ptr_ty.ptrAddressSpace() == .generic);
const child_ty = ptr_ty.childType();
const child_ty_ref = try self.resolveType(child_ty, .indirect);
@@ -2694,7 +2695,7 @@ pub const DeclGen = struct {
incoming_blocks.deinit(self.gpa);
}
- const ty = self.air.typeOfIndex(inst);
+ const ty = self.typeOfIndex(inst);
const inst_datas = self.air.instructions.items(.data);
const extra = self.air.extraData(Air.Block, inst_datas[inst].ty_pl.payload);
const body = self.air.extra[extra.end..][0..extra.data.body_len];
@@ -2727,7 +2728,7 @@ pub const DeclGen = struct {
fn airBr(self: *DeclGen, inst: Air.Inst.Index) !void {
const br = self.air.instructions.items(.data)[inst].br;
const block = self.blocks.get(br.block_inst).?;
- const operand_ty = self.air.typeOf(br.operand);
+ const operand_ty = self.typeOf(br.operand);
const mod = self.module;
if (operand_ty.hasRuntimeBits(mod)) {
@@ -2777,7 +2778,7 @@ pub const DeclGen = struct {
fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const ptr_ty = self.air.typeOf(ty_op.operand);
+ const ptr_ty = self.typeOf(ty_op.operand);
const operand = try self.resolve(ty_op.operand);
if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
@@ -2787,7 +2788,7 @@ pub const DeclGen = struct {
fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {
const mod = self.module;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
- const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const ptr_ty = self.typeOf(bin_op.lhs);
const ptr = try self.resolve(bin_op.lhs);
const value = try self.resolve(bin_op.rhs);
const ptr_ty_ref = try self.resolveType(ptr_ty, .direct);
@@ -2819,7 +2820,7 @@ pub const DeclGen = struct {
fn airRet(self: *DeclGen, inst: Air.Inst.Index) !void {
const operand = self.air.instructions.items(.data)[inst].un_op;
- const operand_ty = self.air.typeOf(operand);
+ const operand_ty = self.typeOf(operand);
const mod = self.module;
if (operand_ty.hasRuntimeBits(mod)) {
const operand_id = try self.resolve(operand);
@@ -2832,7 +2833,7 @@ pub const DeclGen = struct {
fn airRetLoad(self: *DeclGen, inst: Air.Inst.Index) !void {
const mod = self.module;
const un_op = self.air.instructions.items(.data)[inst].un_op;
- const ptr_ty = self.air.typeOf(un_op);
+ const ptr_ty = self.typeOf(un_op);
const ret_ty = ptr_ty.childType();
if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
@@ -2853,8 +2854,8 @@ pub const DeclGen = struct {
const extra = self.air.extraData(Air.Try, pl_op.payload);
const body = self.air.extra[extra.end..][0..extra.data.body_len];
- const err_union_ty = self.air.typeOf(pl_op.operand);
- const payload_ty = self.air.typeOfIndex(inst);
+ const err_union_ty = self.typeOf(pl_op.operand);
+ const payload_ty = self.typeOfIndex(inst);
const err_ty_ref = try self.resolveType(Type.anyerror, .direct);
const bool_ty_ref = try self.resolveType(Type.bool, .direct);
@@ -2911,7 +2912,7 @@ pub const DeclGen = struct {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand_id = try self.resolve(ty_op.operand);
- const err_union_ty = self.air.typeOf(ty_op.operand);
+ const err_union_ty = self.typeOf(ty_op.operand);
const err_ty_ref = try self.resolveType(Type.anyerror, .direct);
if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
@@ -2934,7 +2935,7 @@ pub const DeclGen = struct {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const err_union_ty = self.air.typeOfIndex(inst);
+ const err_union_ty = self.typeOfIndex(inst);
const payload_ty = err_union_ty.errorUnionPayload();
const operand_id = try self.resolve(ty_op.operand);
const eu_layout = self.errorUnionLayout(payload_ty);
@@ -2966,7 +2967,7 @@ pub const DeclGen = struct {
const mod = self.module;
const un_op = self.air.instructions.items(.data)[inst].un_op;
const operand_id = try self.resolve(un_op);
- const optional_ty = self.air.typeOf(un_op);
+ const optional_ty = self.typeOf(un_op);
var buf: Type.Payload.ElemType = undefined;
const payload_ty = optional_ty.optionalChild(&buf);
@@ -3030,8 +3031,8 @@ pub const DeclGen = struct {
const mod = self.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand_id = try self.resolve(ty_op.operand);
- const optional_ty = self.air.typeOf(ty_op.operand);
- const payload_ty = self.air.typeOfIndex(inst);
+ const optional_ty = self.typeOf(ty_op.operand);
+ const payload_ty = self.typeOfIndex(inst);
if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
@@ -3047,14 +3048,14 @@ pub const DeclGen = struct {
const mod = self.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const payload_ty = self.air.typeOf(ty_op.operand);
+ const payload_ty = self.typeOf(ty_op.operand);
if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
return try self.constBool(true, .direct);
}
const operand_id = try self.resolve(ty_op.operand);
- const optional_ty = self.air.typeOfIndex(inst);
+ const optional_ty = self.typeOfIndex(inst);
if (optional_ty.optionalReprIsPayload(mod)) {
return operand_id;
}
@@ -3068,7 +3069,7 @@ pub const DeclGen = struct {
const mod = self.module;
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const cond = try self.resolve(pl_op.operand);
- const cond_ty = self.air.typeOf(pl_op.operand);
+ const cond_ty = self.typeOf(pl_op.operand);
const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
const cond_words: u32 = switch (cond_ty.zigTypeTag(mod)) {
@@ -3317,7 +3318,7 @@ pub const DeclGen = struct {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const extra = self.air.extraData(Air.Call, pl_op.payload);
const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
- const callee_ty = self.air.typeOf(pl_op.operand);
+ const callee_ty = self.typeOf(pl_op.operand);
const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) {
.Fn => callee_ty,
.Pointer => return self.fail("cannot call function pointers", .{}),
@@ -3339,7 +3340,7 @@ pub const DeclGen = struct {
// before starting to emit OpFunctionCall instructions. Hence the
// temporary params buffer.
const arg_id = try self.resolve(arg);
- const arg_ty = self.air.typeOf(arg);
+ const arg_ty = self.typeOf(arg);
if (!arg_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
params[n_params] = arg_id;
@@ -3363,4 +3364,14 @@ pub const DeclGen = struct {
return result_id;
}
+
+ fn typeOf(self: *DeclGen, inst: Air.Inst.Ref) Type {
+ const mod = self.module;
+ 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);
+ }
};
src/Liveness/Verify.zig
@@ -5,6 +5,7 @@ air: Air,
liveness: Liveness,
live: LiveMap = .{},
blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, LiveMap) = .{},
+intern_pool: *const InternPool,
pub const Error = error{ LivenessInvalid, OutOfMemory };
@@ -27,10 +28,11 @@ pub fn verify(self: *Verify) Error!void {
const LiveMap = std.AutoHashMapUnmanaged(Air.Inst.Index, void);
fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
+ const ip = self.intern_pool;
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)) {
+ if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*)) {
// This instruction will not be lowered and should be ignored.
continue;
}
@@ -42,6 +44,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
.ret_ptr,
.constant,
.const_ty,
+ .interned,
.breakpoint,
.dbg_stmt,
.dbg_inline_begin,
@@ -554,7 +557,7 @@ fn verifyDeath(self: *Verify, inst: Air.Inst.Index, operand: Air.Inst.Index) Err
fn verifyOperand(self: *Verify, inst: Air.Inst.Index, op_ref: Air.Inst.Ref, dies: bool) Error!void {
const operand = Air.refToIndex(op_ref) orelse return;
switch (self.air.instructions.items(.tag)[operand]) {
- .constant, .const_ty => {},
+ .constant, .const_ty, .interned => {},
else => {
if (dies) {
if (!self.live.remove(operand)) return invalid("%{}: dead operand %{} reused and killed again", .{ inst, operand });
@@ -576,7 +579,7 @@ fn verifyInst(
}
const tag = self.air.instructions.items(.tag);
switch (tag[inst]) {
- .constant, .const_ty => unreachable,
+ .constant, .const_ty, .interned => unreachable,
else => {
if (self.liveness.isUnused(inst)) {
assert(!self.live.contains(inst));
@@ -604,4 +607,5 @@ const log = std.log.scoped(.liveness_verify);
const Air = @import("../Air.zig");
const Liveness = @import("../Liveness.zig");
+const InternPool = @import("../InternPool.zig");
const Verify = @This();
src/Air.zig
@@ -11,6 +11,7 @@ const Air = @This();
const Value = @import("value.zig").Value;
const Type = @import("type.zig").Type;
const InternPool = @import("InternPool.zig");
+const Module = @import("Module.zig");
instructions: std.MultiArrayList(Inst).Slice,
/// The meaning of this data is determined by `Inst.Tag` value.
@@ -401,6 +402,9 @@ pub const Inst = struct {
constant,
/// A comptime-known type. Uses the `ty` field.
const_ty,
+ /// A comptime-known value via an index into the InternPool.
+ /// Uses the `interned` field.
+ interned,
/// Notes the beginning of a source code statement and marks the line and column.
/// Result type is always void.
/// Uses the `dbg_stmt` field.
@@ -928,6 +932,7 @@ pub const Inst = struct {
pub const Data = union {
no_op: void,
un_op: Ref,
+ interned: InternPool.Index,
bin_op: struct {
lhs: Ref,
@@ -1147,18 +1152,15 @@ 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) Type {
+pub fn typeOf(air: Air, inst: Air.Inst.Ref, ip: InternPool) Type {
const ref_int = @enumToInt(inst);
if (ref_int < InternPool.static_keys.len) {
- return .{
- .ip_index = InternPool.static_keys[ref_int].typeOf(),
- .legacy = undefined,
- };
+ return InternPool.static_keys[ref_int].typeOf().toType();
}
- return air.typeOfIndex(ref_int - ref_start_index);
+ return air.typeOfIndex(ref_int - ref_start_index, ip);
}
-pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
+pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: InternPool) Type {
const datas = air.instructions.items(.data);
switch (air.instructions.items(.tag)[inst]) {
.add,
@@ -1200,7 +1202,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
.div_exact_optimized,
.rem_optimized,
.mod_optimized,
- => return air.typeOf(datas[inst].bin_op.lhs),
+ => return air.typeOf(datas[inst].bin_op.lhs, ip),
.sqrt,
.sin,
@@ -1218,7 +1220,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
.trunc_float,
.neg,
.neg_optimized,
- => return air.typeOf(datas[inst].un_op),
+ => return air.typeOf(datas[inst].un_op, ip),
.cmp_lt,
.cmp_lte,
@@ -1280,6 +1282,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
.try_ptr,
=> return air.getRefType(datas[inst].ty_pl.ty),
+ .interned => return ip.indexToKey(datas[inst].interned).typeOf().toType(),
+
.not,
.bitcast,
.load,
@@ -1371,33 +1375,33 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
.tag_name, .error_name => return Type.initTag(.const_slice_u8_sentinel_0),
.call, .call_always_tail, .call_never_tail, .call_never_inline => {
- const callee_ty = air.typeOf(datas[inst].pl_op.operand);
+ const callee_ty = air.typeOf(datas[inst].pl_op.operand, ip);
return callee_ty.fnReturnType();
},
.slice_elem_val, .ptr_elem_val, .array_elem_val => {
- const ptr_ty = air.typeOf(datas[inst].bin_op.lhs);
+ const ptr_ty = air.typeOf(datas[inst].bin_op.lhs, ip);
return ptr_ty.elemType();
},
.atomic_load => {
- const ptr_ty = air.typeOf(datas[inst].atomic_load.ptr);
+ const ptr_ty = air.typeOf(datas[inst].atomic_load.ptr, ip);
return ptr_ty.elemType();
},
.atomic_rmw => {
- const ptr_ty = air.typeOf(datas[inst].pl_op.operand);
+ const ptr_ty = air.typeOf(datas[inst].pl_op.operand, ip);
return ptr_ty.elemType();
},
- .reduce, .reduce_optimized => return air.typeOf(datas[inst].reduce.operand).childType(),
+ .reduce, .reduce_optimized => return air.typeOf(datas[inst].reduce.operand, ip).childType(),
- .mul_add => return air.typeOf(datas[inst].pl_op.operand),
+ .mul_add => return air.typeOf(datas[inst].pl_op.operand, ip),
.select => {
const extra = air.extraData(Air.Bin, datas[inst].pl_op.payload).data;
- return air.typeOf(extra.lhs);
+ return air.typeOf(extra.lhs, ip);
},
.@"try" => {
- const err_union_ty = air.typeOf(datas[inst].pl_op.operand);
+ const err_union_ty = air.typeOf(datas[inst].pl_op.operand, ip);
return err_union_ty.errorUnionPayload();
},
@@ -1465,7 +1469,7 @@ pub fn refToIndex(inst: Air.Inst.Ref) ?Air.Inst.Index {
}
/// Returns `null` if runtime-known.
-pub fn value(air: Air, inst: Air.Inst.Ref, mod: *const @import("Module.zig")) ?Value {
+pub fn value(air: Air, inst: Air.Inst.Ref, mod: *const Module) ?Value {
const ref_int = @enumToInt(inst);
if (ref_int < ref_start_index) {
const ip_index = @intToEnum(InternPool.Index, ref_int);
@@ -1476,7 +1480,7 @@ pub fn value(air: Air, inst: Air.Inst.Ref, mod: *const @import("Module.zig")) ?V
switch (air.instructions.items(.tag)[inst_index]) {
.constant => return air.values[air_datas[inst_index].ty_pl.payload],
.const_ty => unreachable,
- else => return air.typeOfIndex(inst_index).onePossibleValue(mod),
+ else => return air.typeOfIndex(inst_index, mod.intern_pool).onePossibleValue(mod),
}
}
@@ -1489,10 +1493,11 @@ pub fn nullTerminatedString(air: Air, index: usize) [:0]const u8 {
return bytes[0..end :0];
}
-/// Returns whether the given instruction must always be lowered, for instance 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) bool {
+/// Returns whether the given instruction must always be lowered, for instance
+/// 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 {
const data = air.instructions.items(.data)[inst];
return switch (air.instructions.items(.tag)[inst]) {
.arg,
@@ -1631,6 +1636,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index) bool {
.cmp_vector_optimized,
.constant,
.const_ty,
+ .interned,
.is_null,
.is_non_null,
.is_null_ptr,
@@ -1699,8 +1705,8 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index) bool {
=> false,
.assembly => @truncate(u1, air.extraData(Air.Asm, data.ty_pl.payload).data.flags >> 31) != 0,
- .load => air.typeOf(data.ty_op.operand).isVolatilePtr(),
- .slice_elem_val, .ptr_elem_val => air.typeOf(data.bin_op.lhs).isVolatilePtr(),
- .atomic_load => air.typeOf(data.atomic_load.ptr).isVolatilePtr(),
+ .load => air.typeOf(data.ty_op.operand, ip).isVolatilePtr(),
+ .slice_elem_val, .ptr_elem_val => air.typeOf(data.bin_op.lhs, ip).isVolatilePtr(),
+ .atomic_load => air.typeOf(data.atomic_load.ptr, ip).isVolatilePtr(),
};
}
src/InternPool.zig
@@ -241,6 +241,11 @@ pub const Item = struct {
/// When adding a tag to this enum, consider adding a corresponding entry to
/// `primitives` in AstGen.zig.
pub const Index = enum(u32) {
+ pub const first_type: Index = .u1_type;
+ pub const last_type: Index = .empty_struct_type;
+ pub const first_value: Index = .undef;
+ pub const last_value: Index = .empty_struct;
+
u1_type,
u8_type,
i8_type,
@@ -329,6 +334,7 @@ pub const Index = enum(u32) {
bool_false,
/// `.{}` (untyped)
empty_struct,
+
/// Used for generic parameters where the type and value
/// is not known until generic function instantiation.
generic_poison,
src/Liveness.zig
@@ -131,7 +131,7 @@ fn LivenessPassData(comptime pass: LivenessPass) type {
};
}
-pub fn analyze(gpa: Allocator, air: Air) Allocator.Error!Liveness {
+pub fn analyze(gpa: Allocator, air: Air, intern_pool: *const InternPool) Allocator.Error!Liveness {
const tracy = trace(@src());
defer tracy.end();
@@ -144,6 +144,7 @@ pub fn analyze(gpa: Allocator, air: Air) Allocator.Error!Liveness {
),
.extra = .{},
.special = .{},
+ .intern_pool = intern_pool,
};
errdefer gpa.free(a.tomb_bits);
errdefer a.special.deinit(gpa);
@@ -322,6 +323,7 @@ pub fn categorizeOperand(
.ret_ptr,
.constant,
.const_ty,
+ .interned,
.trap,
.breakpoint,
.dbg_stmt,
@@ -820,6 +822,7 @@ pub const BigTomb = struct {
const Analysis = struct {
gpa: Allocator,
air: Air,
+ intern_pool: *const InternPool,
tomb_bits: []usize,
special: std.AutoHashMapUnmanaged(Air.Inst.Index, u32),
extra: std.ArrayListUnmanaged(u32),
@@ -971,6 +974,7 @@ fn analyzeInst(
.constant,
.const_ty,
+ .interned,
=> unreachable,
.trap,
@@ -1255,6 +1259,7 @@ fn analyzeOperands(
) Allocator.Error!void {
const gpa = a.gpa;
const inst_tags = a.air.instructions.items(.tag);
+ const ip = a.intern_pool;
switch (pass) {
.loop_analysis => {
@@ -1265,7 +1270,7 @@ fn analyzeOperands(
// Don't compute any liveness for constants
switch (inst_tags[operand]) {
- .constant, .const_ty => continue,
+ .constant, .const_ty, .interned => continue,
else => {},
}
@@ -1290,7 +1295,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)) {
+ 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;
@@ -1301,7 +1306,7 @@ fn analyzeOperands(
// Don't compute any liveness for constants
switch (inst_tags[operand]) {
- .constant, .const_ty => continue,
+ .constant, .const_ty, .interned => continue,
else => {},
}
@@ -1821,6 +1826,7 @@ fn AnalyzeBigOperands(comptime pass: LivenessPass) type {
/// Must be called with operands in reverse order.
fn feed(big: *Self, op_ref: Air.Inst.Ref) !void {
+ const ip = big.a.intern_pool;
// Note that after this, `operands_remaining` becomes the index of the current operand
big.operands_remaining -= 1;
@@ -1834,14 +1840,14 @@ fn AnalyzeBigOperands(comptime pass: LivenessPass) type {
// Don't compute any liveness for constants
const inst_tags = big.a.air.instructions.items(.tag);
switch (inst_tags[operand]) {
- .constant, .const_ty => return,
+ .constant, .const_ty, .interned => return,
else => {},
}
// 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)) 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);
src/Module.zig
@@ -4397,7 +4397,7 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {
if (no_bin_file and !dump_air and !dump_llvm_ir) return;
log.debug("analyze liveness of {s}", .{decl.name});
- var liveness = try Liveness.analyze(gpa, air);
+ var liveness = try Liveness.analyze(gpa, air, &mod.intern_pool);
defer liveness.deinit(gpa);
if (dump_air) {
@@ -4414,6 +4414,7 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {
.gpa = gpa,
.air = air,
.liveness = liveness,
+ .intern_pool = &mod.intern_pool,
};
defer verify.deinit();
src/print_air.zig
@@ -306,6 +306,7 @@ const Writer = struct {
.struct_field_ptr => try w.writeStructField(s, inst),
.struct_field_val => try w.writeStructField(s, inst),
.constant => try w.writeConstant(s, inst),
+ .interned => try w.writeInterned(s, inst),
.assembly => try w.writeAssembly(s, inst),
.dbg_stmt => try w.writeDbgStmt(s, inst),
@@ -515,7 +516,7 @@ const Writer = struct {
const pl_op = w.air.instructions.items(.data)[inst].pl_op;
const extra = w.air.extraData(Air.Bin, pl_op.payload).data;
- const elem_ty = w.air.typeOfIndex(inst).childType();
+ const elem_ty = w.typeOfIndex(inst).childType();
try w.writeType(s, elem_ty);
try s.writeAll(", ");
try w.writeOperand(s, inst, 0, pl_op.operand);
@@ -614,6 +615,14 @@ const Writer = struct {
try s.print(", {}", .{val.fmtValue(ty, w.module)});
}
+ fn writeInterned(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
+ const mod = w.module;
+ const ip_index = w.air.instructions.items(.data)[inst].interned;
+ const ty = ip_index.toType();
+ try w.writeType(s, ty);
+ try s.print(", {}", .{ip_index.toValue().fmtValue(ty, mod)});
+ }
+
fn writeAssembly(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
const extra = w.air.extraData(Air.Asm, ty_pl.payload);
@@ -622,7 +631,7 @@ const Writer = struct {
var extra_i: usize = extra.end;
var op_index: usize = 0;
- const ret_ty = w.air.typeOfIndex(inst);
+ const ret_ty = w.typeOfIndex(inst);
try w.writeType(s, ret_ty);
if (is_volatile) {
@@ -985,4 +994,9 @@ const Writer = struct {
try s.print("%{d}", .{inst});
if (dies) try s.writeByte('!');
}
+
+ fn typeOfIndex(w: *Writer, inst: Air.Inst.Index) Type {
+ const mod = w.module;
+ return w.air.typeOfIndex(inst, mod.intern_pool);
+ }
};
src/Sema.zig
@@ -33007,7 +33007,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);
+ return sema.getTmpAir().typeOf(inst, sema.mod.intern_pool);
}
pub fn getTmpAir(sema: Sema) Air {
@@ -33019,88 +33019,14 @@ pub fn getTmpAir(sema: Sema) Air {
}
pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
- switch (ty.ip_index) {
- .u1_type => return .u1_type,
- .u8_type => return .u8_type,
- .i8_type => return .i8_type,
- .u16_type => return .u16_type,
- .i16_type => return .i16_type,
- .u29_type => return .u29_type,
- .u32_type => return .u32_type,
- .i32_type => return .i32_type,
- .u64_type => return .u64_type,
- .i64_type => return .i64_type,
- .u80_type => return .u80_type,
- .u128_type => return .u128_type,
- .i128_type => return .i128_type,
- .usize_type => return .usize_type,
- .isize_type => return .isize_type,
- .c_char_type => return .c_char_type,
- .c_short_type => return .c_short_type,
- .c_ushort_type => return .c_ushort_type,
- .c_int_type => return .c_int_type,
- .c_uint_type => return .c_uint_type,
- .c_long_type => return .c_long_type,
- .c_ulong_type => return .c_ulong_type,
- .c_longlong_type => return .c_longlong_type,
- .c_ulonglong_type => return .c_ulonglong_type,
- .c_longdouble_type => return .c_longdouble_type,
- .f16_type => return .f16_type,
- .f32_type => return .f32_type,
- .f64_type => return .f64_type,
- .f80_type => return .f80_type,
- .f128_type => return .f128_type,
- .anyopaque_type => return .anyopaque_type,
- .bool_type => return .bool_type,
- .void_type => return .void_type,
- .type_type => return .type_type,
- .anyerror_type => return .anyerror_type,
- .comptime_int_type => return .comptime_int_type,
- .comptime_float_type => return .comptime_float_type,
- .noreturn_type => return .noreturn_type,
- .anyframe_type => return .anyframe_type,
- .null_type => return .null_type,
- .undefined_type => return .undefined_type,
- .enum_literal_type => return .enum_literal_type,
- .atomic_order_type => return .atomic_order_type,
- .atomic_rmw_op_type => return .atomic_rmw_op_type,
- .calling_convention_type => return .calling_convention_type,
- .address_space_type => return .address_space_type,
- .float_mode_type => return .float_mode_type,
- .reduce_op_type => return .reduce_op_type,
- .call_modifier_type => return .call_modifier_type,
- .prefetch_options_type => return .prefetch_options_type,
- .export_options_type => return .export_options_type,
- .extern_options_type => return .extern_options_type,
- .type_info_type => return .type_info_type,
- .manyptr_u8_type => return .manyptr_u8_type,
- .manyptr_const_u8_type => return .manyptr_const_u8_type,
- .single_const_pointer_to_comptime_int_type => return .single_const_pointer_to_comptime_int_type,
- .const_slice_u8_type => return .const_slice_u8_type,
- .anyerror_void_error_union_type => return .anyerror_void_error_union_type,
- .generic_poison_type => return .generic_poison_type,
- .var_args_param_type => return .var_args_param_type,
- .empty_struct_type => return .empty_struct_type,
-
- // values
- .undef => unreachable,
- .zero => unreachable,
- .zero_usize => unreachable,
- .one => unreachable,
- .one_usize => unreachable,
- .calling_convention_c => unreachable,
- .calling_convention_inline => unreachable,
- .void_value => unreachable,
- .unreachable_value => unreachable,
- .null_value => unreachable,
- .bool_true => unreachable,
- .bool_false => unreachable,
- .empty_struct => unreachable,
- .generic_poison => unreachable,
-
- _ => {},
-
- .none => unreachable,
+ if (ty.ip_index != .none) {
+ if (@enumToInt(ty.ip_index) < Air.ref_start_index)
+ return @intToEnum(Air.Inst.Ref, @enumToInt(ty.ip_index));
+ try sema.air_instructions.append(sema.gpa, .{
+ .tag = .interned,
+ .data = .{ .interned = ty.ip_index },
+ });
+ return Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1));
}
switch (ty.tag()) {
.u1 => return .u1_type,
src/type.zig
@@ -2827,21 +2827,35 @@ pub const Type = struct {
};
}
- /// TODO add enums with no fields here
pub fn isNoReturn(ty: Type) bool {
- switch (ty.tag()) {
- .noreturn => return true,
- .error_set => {
- const err_set_obj = ty.castTag(.error_set).?.data;
- const names = err_set_obj.names.keys();
- return names.len == 0;
- },
- .error_set_merged => {
- const name_map = ty.castTag(.error_set_merged).?.data;
- const names = name_map.keys();
- return names.len == 0;
- },
+ switch (@enumToInt(ty.ip_index)) {
+ @enumToInt(InternPool.Index.first_type)...@enumToInt(InternPool.Index.noreturn_type) - 1 => return false,
+
+ @enumToInt(InternPool.Index.noreturn_type) => return true,
+
+ @enumToInt(InternPool.Index.noreturn_type) + 1...@enumToInt(InternPool.Index.last_type) => return false,
+
+ @enumToInt(InternPool.Index.first_value)...@enumToInt(InternPool.Index.last_value) => unreachable,
+ @enumToInt(InternPool.Index.generic_poison) => unreachable,
+
+ // TODO add empty error sets here
+ // TODO add enums with no fields here
else => return false,
+
+ @enumToInt(InternPool.Index.none) => switch (ty.tag()) {
+ .noreturn => return true,
+ .error_set => {
+ const err_set_obj = ty.castTag(.error_set).?.data;
+ const names = err_set_obj.names.keys();
+ return names.len == 0;
+ },
+ .error_set_merged => {
+ const name_map = ty.castTag(.error_set_merged).?.data;
+ const names = name_map.keys();
+ return names.len == 0;
+ },
+ else => return false,
+ },
}
}