aboutsummaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/aarch64/CodeGen.zig28
-rw-r--r--src/arch/arm/CodeGen.zig28
-rw-r--r--src/arch/riscv64/CodeGen.zig24
-rw-r--r--src/arch/sparc64/CodeGen.zig28
-rw-r--r--src/arch/wasm/CodeGen.zig7
-rw-r--r--src/arch/x86_64/CodeGen.zig56
6 files changed, 42 insertions, 129 deletions
diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig
index 4d212148b2..a87845df2e 100644
--- a/src/arch/aarch64/CodeGen.zig
+++ b/src/arch/aarch64/CodeGen.zig
@@ -845,7 +845,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.ptr_elem_val => try self.airPtrElemVal(inst),
.ptr_elem_ptr => try self.airPtrElemPtr(inst),
- .inferred_alloc, .inferred_alloc_comptime, .interned => unreachable,
+ .inferred_alloc, .inferred_alloc_comptime => unreachable,
.unreach => self.finishAirBookkeeping(),
.optional_payload => try self.airOptionalPayload(inst),
@@ -920,7 +920,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
/// Asserts there is already capacity to insert into top branch inst_table.
fn processDeath(self: *Self, inst: Air.Inst.Index) void {
- assert(self.air.instructions.items(.tag)[inst] != .interned);
// When editing this function, note that the logic must synchronize with `reuseOperand`.
const prev_value = self.getResolvedInstValue(inst);
const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
@@ -953,9 +952,7 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
const dies = @as(u1, @truncate(tomb_bits)) != 0;
tomb_bits >>= 1;
if (!dies) continue;
- const op_int = @intFromEnum(op);
- if (op_int < Air.ref_start_index) continue;
- const op_index = @as(Air.Inst.Index, @intCast(op_int - Air.ref_start_index));
+ const op_index = Air.refToIndex(op) orelse continue;
self.processDeath(op_index);
}
const is_used = @as(u1, @truncate(tomb_bits)) == 0;
@@ -4696,9 +4693,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
// that death now instead of later as this has an effect on
// whether it needs to be spilled in the branches
if (self.liveness.operandDies(inst, 0)) {
- const op_int = @intFromEnum(pl_op.operand);
- if (op_int >= Air.ref_start_index) {
- const op_index = @as(Air.Inst.Index, @intCast(op_int - Air.ref_start_index));
+ if (Air.refToIndex(pl_op.operand)) |op_index| {
self.processDeath(op_index);
}
}
@@ -6149,22 +6144,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
.val = (try self.air.value(inst, mod)).?,
});
- switch (self.air.instructions.items(.tag)[inst_index]) {
- .interned => {
- // Constants have static lifetimes, so they are always memoized in the outer most table.
- const branch = &self.branch_stack.items[0];
- const gop = try branch.inst_table.getOrPut(self.gpa, inst_index);
- if (!gop.found_existing) {
- const interned = self.air.instructions.items(.data)[inst_index].interned;
- gop.value_ptr.* = try self.genTypedValue(.{
- .ty = inst_ty,
- .val = interned.toValue(),
- });
- }
- return gop.value_ptr.*;
- },
- else => return self.getResolvedInstValue(inst_index),
- }
+ return self.getResolvedInstValue(inst_index);
}
fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig
index d3f1efb192..d8c16fa434 100644
--- a/src/arch/arm/CodeGen.zig
+++ b/src/arch/arm/CodeGen.zig
@@ -829,7 +829,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.ptr_elem_val => try self.airPtrElemVal(inst),
.ptr_elem_ptr => try self.airPtrElemPtr(inst),
- .inferred_alloc, .inferred_alloc_comptime, .interned => unreachable,
+ .inferred_alloc, .inferred_alloc_comptime => unreachable,
.unreach => self.finishAirBookkeeping(),
.optional_payload => try self.airOptionalPayload(inst),
@@ -904,7 +904,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
/// Asserts there is already capacity to insert into top branch inst_table.
fn processDeath(self: *Self, inst: Air.Inst.Index) void {
- assert(self.air.instructions.items(.tag)[inst] != .interned);
// When editing this function, note that the logic must synchronize with `reuseOperand`.
const prev_value = self.getResolvedInstValue(inst);
const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
@@ -939,9 +938,7 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
const dies = @as(u1, @truncate(tomb_bits)) != 0;
tomb_bits >>= 1;
if (!dies) continue;
- const op_int = @intFromEnum(op);
- if (op_int < Air.ref_start_index) continue;
- const op_index = @as(Air.Inst.Index, @intCast(op_int - Air.ref_start_index));
+ const op_index = Air.refToIndex(op) orelse continue;
self.processDeath(op_index);
}
const is_used = @as(u1, @truncate(tomb_bits)) == 0;
@@ -4651,9 +4648,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
// that death now instead of later as this has an effect on
// whether it needs to be spilled in the branches
if (self.liveness.operandDies(inst, 0)) {
- const op_int = @intFromEnum(pl_op.operand);
- if (op_int >= Air.ref_start_index) {
- const op_index = @as(Air.Inst.Index, @intCast(op_int - Air.ref_start_index));
+ if (Air.refToIndex(pl_op.operand)) |op_index| {
self.processDeath(op_index);
}
}
@@ -6102,22 +6097,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
.val = (try self.air.value(inst, mod)).?,
});
- switch (self.air.instructions.items(.tag)[inst_index]) {
- .interned => {
- // Constants have static lifetimes, so they are always memoized in the outer most table.
- const branch = &self.branch_stack.items[0];
- const gop = try branch.inst_table.getOrPut(self.gpa, inst_index);
- if (!gop.found_existing) {
- const interned = self.air.instructions.items(.data)[inst_index].interned;
- gop.value_ptr.* = try self.genTypedValue(.{
- .ty = inst_ty,
- .val = interned.toValue(),
- });
- }
- return gop.value_ptr.*;
- },
- else => return self.getResolvedInstValue(inst_index),
- }
+ return self.getResolvedInstValue(inst_index);
}
fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig
index b15ac531e0..c240ff16f1 100644
--- a/src/arch/riscv64/CodeGen.zig
+++ b/src/arch/riscv64/CodeGen.zig
@@ -664,7 +664,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.ptr_elem_val => try self.airPtrElemVal(inst),
.ptr_elem_ptr => try self.airPtrElemPtr(inst),
- .inferred_alloc, .inferred_alloc_comptime, .interned => unreachable,
+ .inferred_alloc, .inferred_alloc_comptime => unreachable,
.unreach => self.finishAirBookkeeping(),
.optional_payload => try self.airOptionalPayload(inst),
@@ -731,7 +731,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
/// Asserts there is already capacity to insert into top branch inst_table.
fn processDeath(self: *Self, inst: Air.Inst.Index) void {
- assert(self.air.instructions.items(.tag)[inst] != .interned);
// When editing this function, note that the logic must synchronize with `reuseOperand`.
const prev_value = self.getResolvedInstValue(inst);
const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
@@ -757,9 +756,7 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
const dies = @as(u1, @truncate(tomb_bits)) != 0;
tomb_bits >>= 1;
if (!dies) continue;
- const op_int = @intFromEnum(op);
- if (op_int < Air.ref_start_index) continue;
- const op_index = @as(Air.Inst.Index, @intCast(op_int - Air.ref_start_index));
+ const op_index = Air.refToIndex(op) orelse continue;
self.processDeath(op_index);
}
const is_used = @as(u1, @truncate(tomb_bits)) == 0;
@@ -2556,22 +2553,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
.val = (try self.air.value(inst, mod)).?,
});
- switch (self.air.instructions.items(.tag)[inst_index]) {
- .interned => {
- // Constants have static lifetimes, so they are always memoized in the outer most table.
- const branch = &self.branch_stack.items[0];
- const gop = try branch.inst_table.getOrPut(self.gpa, inst_index);
- if (!gop.found_existing) {
- const interned = self.air.instructions.items(.data)[inst_index].interned;
- gop.value_ptr.* = try self.genTypedValue(.{
- .ty = inst_ty,
- .val = interned.toValue(),
- });
- }
- return gop.value_ptr.*;
- },
- else => return self.getResolvedInstValue(inst_index),
- }
+ return self.getResolvedInstValue(inst_index);
}
fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig
index 648e1bee45..f8dd621ca0 100644
--- a/src/arch/sparc64/CodeGen.zig
+++ b/src/arch/sparc64/CodeGen.zig
@@ -677,7 +677,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.ptr_elem_val => try self.airPtrElemVal(inst),
.ptr_elem_ptr => try self.airPtrElemPtr(inst),
- .inferred_alloc, .inferred_alloc_comptime, .interned => unreachable,
+ .inferred_alloc, .inferred_alloc_comptime => unreachable,
.unreach => self.finishAirBookkeeping(),
.optional_payload => try self.airOptionalPayload(inst),
@@ -1515,9 +1515,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
// that death now instead of later as this has an effect on
// whether it needs to be spilled in the branches
if (self.liveness.operandDies(inst, 0)) {
- const op_int = @intFromEnum(pl_op.operand);
- if (op_int >= Air.ref_start_index) {
- const op_index = @as(Air.Inst.Index, @intCast(op_int - Air.ref_start_index));
+ if (Air.refToIndex(pl_op.operand)) |op_index| {
self.processDeath(op_index);
}
}
@@ -3570,9 +3568,7 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
const dies = @as(u1, @truncate(tomb_bits)) != 0;
tomb_bits >>= 1;
if (!dies) continue;
- const op_int = @intFromEnum(op);
- if (op_int < Air.ref_start_index) continue;
- const op_index = @as(Air.Inst.Index, @intCast(op_int - Air.ref_start_index));
+ const op_index = Air.refToIndex(op) orelse continue;
self.processDeath(op_index);
}
const is_used = @as(u1, @truncate(tomb_bits)) == 0;
@@ -4422,7 +4418,6 @@ fn performReloc(self: *Self, inst: Mir.Inst.Index) !void {
/// Asserts there is already capacity to insert into top branch inst_table.
fn processDeath(self: *Self, inst: Air.Inst.Index) void {
- assert(self.air.instructions.items(.tag)[inst] != .interned);
// When editing this function, note that the logic must synchronize with `reuseOperand`.
const prev_value = self.getResolvedInstValue(inst);
const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
@@ -4550,22 +4545,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;
if (Air.refToIndex(ref)) |inst| {
- switch (self.air.instructions.items(.tag)[inst]) {
- .interned => {
- // Constants have static lifetimes, so they are always memoized in the outer most table.
- const branch = &self.branch_stack.items[0];
- const gop = try branch.inst_table.getOrPut(self.gpa, inst);
- if (!gop.found_existing) {
- const interned = self.air.instructions.items(.data)[inst].interned;
- gop.value_ptr.* = try self.genTypedValue(.{
- .ty = ty,
- .val = interned.toValue(),
- });
- }
- return gop.value_ptr.*;
- },
- else => return self.getResolvedInstValue(inst),
- }
+ return self.getResolvedInstValue(inst);
}
return self.genTypedValue(.{
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig
index 33d4a46741..ab6ded682e 100644
--- a/src/arch/wasm/CodeGen.zig
+++ b/src/arch/wasm/CodeGen.zig
@@ -854,9 +854,9 @@ const BigTomb = struct {
lbt: Liveness.BigTomb,
fn feed(bt: *BigTomb, op_ref: Air.Inst.Ref) void {
- _ = Air.refToIndex(op_ref) orelse return; // constants do not have to be freed regardless
const dies = bt.lbt.feed();
if (!dies) return;
+ // This will be a nop for interned constants.
processDeath(bt.gen, op_ref);
}
@@ -882,8 +882,7 @@ fn iterateBigTomb(func: *CodeGen, inst: Air.Inst.Index, operand_count: usize) !B
}
fn processDeath(func: *CodeGen, ref: Air.Inst.Ref) void {
- const inst = Air.refToIndex(ref) orelse return;
- assert(func.air.instructions.items(.tag)[inst] != .interned);
+ if (Air.refToIndex(ref) == null) return;
// Branches are currently only allowed to free locals allocated
// within their own branch.
// TODO: Upon branch consolidation free any locals if needed.
@@ -1832,7 +1831,7 @@ fn buildPointerOffset(func: *CodeGen, ptr_value: WValue, offset: u64, action: en
fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const air_tags = func.air.instructions.items(.tag);
return switch (air_tags[inst]) {
- .inferred_alloc, .inferred_alloc_comptime, .interned => unreachable,
+ .inferred_alloc, .inferred_alloc_comptime => unreachable,
.add => func.airBinOp(inst, .add),
.add_sat => func.airSatBinOp(inst, .add),
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig
index 9d4804c8c8..651c2bfb8c 100644
--- a/src/arch/x86_64/CodeGen.zig
+++ b/src/arch/x86_64/CodeGen.zig
@@ -81,7 +81,7 @@ end_di_column: u32,
/// which is a relative jump, based on the address following the reloc.
exitlude_jump_relocs: std.ArrayListUnmanaged(Mir.Inst.Index) = .{},
-const_tracking: InstTrackingMap = .{},
+const_tracking: ConstTrackingMap = .{},
inst_tracking: InstTrackingMap = .{},
// Key is the block instruction
@@ -403,6 +403,7 @@ pub const MCValue = union(enum) {
};
const InstTrackingMap = std.AutoArrayHashMapUnmanaged(Air.Inst.Index, InstTracking);
+const ConstTrackingMap = std.AutoArrayHashMapUnmanaged(InternPool.Index, InstTracking);
const InstTracking = struct {
long: MCValue,
short: MCValue,
@@ -1927,7 +1928,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.ptr_elem_val => try self.airPtrElemVal(inst),
.ptr_elem_ptr => try self.airPtrElemPtr(inst),
- .inferred_alloc, .inferred_alloc_comptime, .interned => unreachable,
+ .inferred_alloc, .inferred_alloc_comptime => unreachable,
.unreach => if (self.wantSafety()) try self.airTrap() else self.finishAirBookkeeping(),
.optional_payload => try self.airOptionalPayload(inst),
@@ -2099,7 +2100,6 @@ fn feed(self: *Self, bt: *Liveness.BigTomb, operand: Air.Inst.Ref) void {
/// Asserts there is already capacity to insert into top branch inst_table.
fn processDeath(self: *Self, inst: Air.Inst.Index) void {
- assert(self.air.instructions.items(.tag)[inst] != .interned);
self.inst_tracking.getPtr(inst).?.die(self, inst);
}
@@ -2871,13 +2871,6 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {
const dst_info = dst_ty.intInfo(mod);
if (Air.refToIndex(dst_air)) |inst| {
switch (air_tag[inst]) {
- .interned => {
- const src_val = air_data[inst].interned.toValue();
- var space: Value.BigIntSpace = undefined;
- const src_int = src_val.toBigInt(&space, mod);
- return @as(u16, @intCast(src_int.bitCountTwosComp())) +
- @intFromBool(src_int.positive and dst_info.signedness == .signed);
- },
.intcast => {
const src_ty = self.typeOf(air_data[inst].ty_op.operand);
const src_info = src_ty.intInfo(mod);
@@ -2894,6 +2887,11 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {
},
else => {},
}
+ } else if (Air.refToInterned(dst_air)) |ip_index| {
+ var space: Value.BigIntSpace = undefined;
+ const src_int = ip_index.toValue().toBigInt(&space, mod);
+ return @as(u16, @intCast(src_int.bitCountTwosComp())) +
+ @intFromBool(src_int.positive and dst_info.signedness == .signed);
}
return dst_info.bits;
}
@@ -11635,32 +11633,26 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
// If the type has no codegen bits, no need to store it.
if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;
- if (Air.refToIndex(ref)) |inst| {
- const mcv = switch (self.air.instructions.items(.tag)[inst]) {
- .interned => tracking: {
- const gop = try self.const_tracking.getOrPut(self.gpa, inst);
- if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(try self.genTypedValue(.{
- .ty = ty,
- .val = self.air.instructions.items(.data)[inst].interned.toValue(),
- }));
- break :tracking gop.value_ptr;
- },
- else => self.inst_tracking.getPtr(inst).?,
- }.short;
- switch (mcv) {
- .none, .unreach, .dead => unreachable,
- else => return mcv,
- }
- }
+ const mcv = if (Air.refToIndex(ref)) |inst| mcv: {
+ break :mcv self.inst_tracking.getPtr(inst).?.short;
+ } else mcv: {
+ const ip_index = Air.refToInterned(ref).?;
+ const gop = try self.const_tracking.getOrPut(self.gpa, ip_index);
+ if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(try self.genTypedValue(.{
+ .ty = ty,
+ .val = ip_index.toValue(),
+ }));
+ break :mcv gop.value_ptr.short;
+ };
- return self.genTypedValue(.{ .ty = ty, .val = (try self.air.value(ref, mod)).? });
+ switch (mcv) {
+ .none, .unreach, .dead => unreachable,
+ else => return mcv,
+ }
}
fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) *InstTracking {
- const tracking = switch (self.air.instructions.items(.tag)[inst]) {
- .interned => &self.const_tracking,
- else => &self.inst_tracking,
- }.getPtr(inst).?;
+ const tracking = self.inst_tracking.getPtr(inst).?;
return switch (tracking.short) {
.none, .unreach, .dead => unreachable,
else => tracking,