Commit 3c74a478a4
Changed files (3)
src
arch
x86_64
src/arch/x86_64/CodeGen.zig
@@ -9731,7 +9731,7 @@ fn computeFrameLayout(self: *CodeGen, cc: std.builtin.CallingConvention) !FrameL
// Create list of registers to save in the prologue.
// TODO handle register classes
- var save_reg_list = Mir.RegisterList{};
+ var save_reg_list: Mir.RegisterList = .empty;
const callee_preserved_regs =
abi.getCalleePreservedRegs(abi.resolveCallingConvention(cc, self.target.*));
for (callee_preserved_regs) |reg| {
@@ -9972,43 +9972,34 @@ fn restoreState(self: *CodeGen, state: State, deaths: []const Air.Inst.Index, co
reg_locks.deinit();
};
- for (0..state.registers.len) |index| {
- const current_maybe_inst = if (self.register_manager.free_registers.isSet(index))
- null
- else
- self.register_manager.registers[index];
- const target_maybe_inst = if (state.free_registers.isSet(index))
- null
- else
- state.registers[index];
+ for (
+ 0..,
+ self.register_manager.registers,
+ state.registers,
+ state.reg_tracking,
+ ) |reg_i, current_slot, target_slot, reg_tracking| {
+ const reg_index: RegisterManager.TrackedIndex = @intCast(reg_i);
+ const current_maybe_inst = if (self.register_manager.isRegIndexFree(reg_index)) null else current_slot;
+ const target_maybe_inst = if (state.free_registers.isSet(reg_index)) null else target_slot;
if (std.debug.runtime_safety) if (target_maybe_inst) |target_inst|
assert(self.inst_tracking.getIndex(target_inst).? < state.inst_tracking_len);
if (opts.emit_instructions) {
- if (current_maybe_inst) |current_inst| {
+ if (current_maybe_inst) |current_inst|
try self.inst_tracking.getPtr(current_inst).?.spill(self, current_inst);
- }
- if (target_maybe_inst) |target_inst| {
- const target_tracking = self.inst_tracking.getPtr(target_inst).?;
- try target_tracking.materialize(self, target_inst, state.reg_tracking[index]);
- }
+ if (target_maybe_inst) |target_inst|
+ try self.inst_tracking.getPtr(target_inst).?.materialize(self, target_inst, reg_tracking);
}
if (opts.update_tracking) {
if (current_maybe_inst) |current_inst| {
try self.inst_tracking.getPtr(current_inst).?.trackSpill(self, current_inst);
- }
- {
- const reg = RegisterManager.regAtTrackedIndex(@intCast(index));
- self.register_manager.freeReg(reg);
- self.register_manager.getRegAssumeFree(reg, target_maybe_inst);
+ self.register_manager.freeRegIndex(reg_index);
}
if (target_maybe_inst) |target_inst| {
- self.inst_tracking.getPtr(target_inst).?.trackMaterialize(
- target_inst,
- state.reg_tracking[index],
- );
+ self.register_manager.getRegIndexAssumeFree(reg_index, target_maybe_inst);
+ self.inst_tracking.getPtr(target_inst).?.trackMaterialize(target_inst, reg_tracking);
}
} else if (target_maybe_inst) |_|
- try reg_locks.append(self.register_manager.lockRegIndexAssumeUnused(@intCast(index)));
+ try reg_locks.append(self.register_manager.lockRegIndexAssumeUnused(reg_index));
}
if (opts.emit_instructions) if (self.eflags_inst) |inst|
try self.inst_tracking.getPtr(inst).?.spill(self, inst);
src/arch/x86_64/Mir.zig
@@ -1168,11 +1168,13 @@ pub const AirOffset = struct { air_inst: Air.Inst.Index, off: i32 };
/// Used in conjunction with payload to transfer a list of used registers in a compact manner.
pub const RegisterList = struct {
- bitset: BitSet = BitSet.initEmpty(),
+ bitset: BitSet,
const BitSet = IntegerBitSet(32);
const Self = @This();
+ pub const empty: RegisterList = .{ .bitset = .initEmpty() };
+
fn getIndexForReg(registers: []const Register, reg: Register) BitSet.MaskInt {
for (registers, 0..) |cpreg, i| {
if (reg.id() == cpreg.id()) return @intCast(i);
src/register_manager.zig
@@ -99,8 +99,7 @@ pub fn RegisterManager(
max_id = @max(elem_id, max_id);
}
- const OptionalIndex = std.math.IntFittingRange(0, set.len);
- comptime var map = [1]OptionalIndex{set.len} ** (max_id - min_id + 1);
+ comptime var map: [max_id - min_id + 1]std.math.IntFittingRange(0, set.len) = @splat(set.len);
inline for (set, 0..) |elem, elem_index| map[comptime elem.id() - min_id] = elem_index;
const id_index = reg.id() -% min_id;
@@ -384,7 +383,7 @@ pub fn RegisterManager(
/// Allocates the specified register with the specified
/// instruction. Asserts that the register is free and no
/// spilling is necessary.
- fn getRegIndexAssumeFree(
+ pub fn getRegIndexAssumeFree(
self: *Self,
tracked_index: TrackedIndex,
inst: ?Air.Inst.Index,
@@ -403,7 +402,7 @@ pub fn RegisterManager(
}
/// Marks the specified register as free
- fn freeRegIndex(self: *Self, tracked_index: TrackedIndex) void {
+ pub fn freeRegIndex(self: *Self, tracked_index: TrackedIndex) void {
log.debug("freeing register {}", .{regAtTrackedIndex(tracked_index)});
self.registers[tracked_index] = undefined;
self.markRegIndexFree(tracked_index);