diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-05-26 09:06:42 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-05-26 12:05:51 +0200 |
| commit | 0e0b00fd48ea680f2d69207297e877f54dd9ec89 (patch) | |
| tree | 9baa6bd9110641ce42d4e02bbd1d054f6a70dde2 /src | |
| parent | ab88165326abfd81c5046e8c064bd6603198ed94 (diff) | |
| download | zig-0e0b00fd48ea680f2d69207297e877f54dd9ec89.tar.gz zig-0e0b00fd48ea680f2d69207297e877f54dd9ec89.zip | |
regalloc: use StaticBitSet internally
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/aarch64/abi.zig | 18 | ||||
| -rw-r--r-- | src/arch/arm/abi.zig | 18 | ||||
| -rw-r--r-- | src/arch/riscv64/abi.zig | 18 | ||||
| -rw-r--r-- | src/arch/sparc64/abi.zig | 18 | ||||
| -rw-r--r-- | src/arch/x86_64/abi.zig | 38 | ||||
| -rw-r--r-- | src/register_manager.zig | 453 |
6 files changed, 121 insertions, 442 deletions
diff --git a/src/arch/aarch64/abi.zig b/src/arch/aarch64/abi.zig index 89a3a6c21d..cb28b1fffa 100644 --- a/src/arch/aarch64/abi.zig +++ b/src/arch/aarch64/abi.zig @@ -27,14 +27,12 @@ pub const RegisterManager = RegisterManagerFn(@import("CodeGen.zig"), Register, // Register classes const RegisterBitSet = RegisterManager.RegisterBitSet; pub const RegisterClass = struct { - pub const gp: RegisterBitSet = std.math.maxInt(RegisterBitSet); - // TODO uncomment once #11680 is fixed. - // pub const gp: RegisterBitSet = blk: { - // var set = RegisterBitSet.initEmpty(); - // set.setRangeValue(.{ - // .start = 0, - // .end = callee_preserved_regs.len, - // }, true); - // break :blk set; - // }; + pub const gp: RegisterBitSet = blk: { + var set = RegisterBitSet.initEmpty(); + set.setRangeValue(.{ + .start = 0, + .end = callee_preserved_regs.len, + }, true); + break :blk set; + }; }; diff --git a/src/arch/arm/abi.zig b/src/arch/arm/abi.zig index c76c3b0ea0..3fcfb0e561 100644 --- a/src/arch/arm/abi.zig +++ b/src/arch/arm/abi.zig @@ -15,14 +15,12 @@ pub const RegisterManager = RegisterManagerFn(@import("CodeGen.zig"), Register, // Register classes const RegisterBitSet = RegisterManager.RegisterBitSet; pub const RegisterClass = struct { - pub const gp: RegisterBitSet = std.math.maxInt(RegisterBitSet); - // TODO uncomment once #11680 is fixed. - // pub const gp: RegisterBitSet = blk: { - // var set = RegisterBitSet.initEmpty(); - // set.setRangeValue(.{ - // .start = 0, - // .end = caller_preserved_regs.len + callee_preserved_regs.len, - // }, true); - // break :blk set; - // }; + pub const gp: RegisterBitSet = blk: { + var set = RegisterBitSet.initEmpty(); + set.setRangeValue(.{ + .start = 0, + .end = caller_preserved_regs.len + callee_preserved_regs.len, + }, true); + break :blk set; + }; }; diff --git a/src/arch/riscv64/abi.zig b/src/arch/riscv64/abi.zig index 30d3719a46..3792c4ab18 100644 --- a/src/arch/riscv64/abi.zig +++ b/src/arch/riscv64/abi.zig @@ -13,14 +13,12 @@ pub const RegisterManager = RegisterManagerFn(@import("CodeGen.zig"), Register, // Register classes const RegisterBitSet = RegisterManager.RegisterBitSet; pub const RegisterClass = struct { - pub const gp: RegisterBitSet = std.math.maxInt(RegisterBitSet); - // TODO uncomment once #11680 is fixed. - // pub const gp: RegisterBitSet = blk: { - // var set = RegisterBitSet.initEmpty(); - // set.setRangeValue(.{ - // .start = 0, - // .end = callee_preserved_regs.len, - // }, true); - // break :blk set; - // }; + pub const gp: RegisterBitSet = blk: { + var set = RegisterBitSet.initEmpty(); + set.setRangeValue(.{ + .start = 0, + .end = callee_preserved_regs.len, + }, true); + break :blk set; + }; }; diff --git a/src/arch/sparc64/abi.zig b/src/arch/sparc64/abi.zig index 1c6d40941f..a18262f62b 100644 --- a/src/arch/sparc64/abi.zig +++ b/src/arch/sparc64/abi.zig @@ -43,14 +43,12 @@ pub const RegisterManager = RegisterManagerFn(@import("CodeGen.zig"), Register, // Register classes const RegisterBitSet = RegisterManager.RegisterBitSet; pub const RegisterClass = struct { - pub const gp: RegisterBitSet = std.math.maxInt(RegisterBitSet); - // TODO uncomment once #11680 is fixed. - // pub const gp: RegisterBitSet = blk: { - // var set = RegisterBitSet.initEmpty(); - // set.setRangeValue(.{ - // .start = 0, - // .end = allocatable_regs.len, - // }, true); - // break :blk set; - // }; + pub const gp: RegisterBitSet = blk: { + var set = RegisterBitSet.initEmpty(); + set.setRangeValue(.{ + .start = 0, + .end = allocatable_regs.len, + }, true); + break :blk set; + }; }; diff --git a/src/arch/x86_64/abi.zig b/src/arch/x86_64/abi.zig index 77f28c11f4..7e2025a23d 100644 --- a/src/arch/x86_64/abi.zig +++ b/src/arch/x86_64/abi.zig @@ -393,26 +393,20 @@ pub const RegisterManager = RegisterManagerFn(@import("CodeGen.zig"), Register, // Register classes const RegisterBitSet = RegisterManager.RegisterBitSet; pub const RegisterClass = struct { - pub const gp: RegisterBitSet = @as(RegisterBitSet, std.math.maxInt(std.meta.Int( - .unsigned, - caller_preserved_regs.len + callee_preserved_regs.len, - ))); - pub const sse: RegisterBitSet = std.math.maxInt(RegisterBitSet) - gp; - // TODO uncomment once #11680 is fixed. - // pub const gp: RegisterBitSet = blk: { - // var set = RegisterBitSet.initEmpty(); - // set.setRangeValue(.{ - // .start = 0, - // .end = caller_preserved_regs.len + callee_preserved_regs.len, - // }, true); - // break :blk set; - // }; - // pub const sse: RegisterBitSet = blk: { - // var set = RegisterBitSet.initEmpty(); - // set.setRangeValue(.{ - // .start = caller_preserved_regs.len + callee_preserved_regs.len, - // .end = allocatable_registers.len, - // }, true); - // break :blk set; - // }; + pub const gp: RegisterBitSet = blk: { + var set = RegisterBitSet.initEmpty(); + set.setRangeValue(.{ + .start = 0, + .end = caller_preserved_regs.len + callee_preserved_regs.len, + }, true); + break :blk set; + }; + pub const sse: RegisterBitSet = blk: { + var set = RegisterBitSet.initEmpty(); + set.setRangeValue(.{ + .start = caller_preserved_regs.len + callee_preserved_regs.len, + .end = allocatable_registers.len, + }, true); + break :blk set; + }; }; diff --git a/src/register_manager.zig b/src/register_manager.zig index 98ee8c9ab3..64f6609a9b 100644 --- a/src/register_manager.zig +++ b/src/register_manager.zig @@ -4,6 +4,7 @@ const mem = std.mem; const assert = std.debug.assert; const Allocator = std.mem.Allocator; const Air = @import("Air.zig"); +const StaticBitSet = std.bit_set.StaticBitSet; const Type = @import("type.zig").Type; const Module = @import("Module.zig"); const expect = std.testing.expect; @@ -41,49 +42,39 @@ pub fn RegisterManager( registers: [tracked_registers.len]Air.Inst.Index = undefined, /// Tracks which registers are free (in which case the /// corresponding bit is set to 1) - free_registers: RegisterBitSet = math.maxInt(RegisterBitSet), + free_registers: RegisterBitSet = RegisterBitSet.initFull(), /// Tracks all registers allocated in the course of this /// function - allocated_registers: RegisterBitSet = 0, + allocated_registers: RegisterBitSet = RegisterBitSet.initEmpty(), /// Tracks registers which are locked from being allocated - locked_registers: RegisterBitSet = 0, + locked_registers: RegisterBitSet = RegisterBitSet.initEmpty(), const Self = @This(); - /// An integer whose bits represent all the registers and - /// whether they are free. - pub const RegisterBitSet = std.meta.Int(.unsigned, tracked_registers.len); - const ShiftInt = math.Log2Int(RegisterBitSet); + pub const RegisterBitSet = StaticBitSet(tracked_registers.len); fn getFunction(self: *Self) *Function { return @fieldParentPtr(Function, "register_manager", self); } fn excludeRegister(reg: Register, register_class: RegisterBitSet) bool { - const mask = getRegisterMask(reg) orelse return true; - return mask & register_class == 0; - } - - fn getRegisterMask(reg: Register) ?RegisterBitSet { - const index = indexOfRegIntoTracked(reg) orelse return null; - const shift = @intCast(ShiftInt, index); - const mask = @as(RegisterBitSet, 1) << shift; - return mask; + const index = indexOfRegIntoTracked(reg) orelse return true; + return !register_class.isSet(index); } fn markRegAllocated(self: *Self, reg: Register) void { - const mask = getRegisterMask(reg) orelse return; - self.allocated_registers |= mask; + const index = indexOfRegIntoTracked(reg) orelse return; + self.allocated_registers.set(index); } fn markRegUsed(self: *Self, reg: Register) void { - const mask = getRegisterMask(reg) orelse return; - self.free_registers &= ~mask; + const index = indexOfRegIntoTracked(reg) orelse return; + self.free_registers.unset(index); } fn markRegFree(self: *Self, reg: Register) void { - const mask = getRegisterMask(reg) orelse return; - self.free_registers |= mask; + const index = indexOfRegIntoTracked(reg) orelse return; + self.free_registers.set(index); } pub fn indexOfReg( @@ -96,14 +87,14 @@ pub fn RegisterManager( return null; } - pub fn indexOfRegIntoTracked(reg: Register) ?ShiftInt { + pub fn indexOfRegIntoTracked(reg: Register) ?RegisterBitSet.ShiftInt { return indexOfReg(tracked_registers, reg); } /// Returns true when this register is not tracked pub fn isRegFree(self: Self, reg: Register) bool { - const mask = getRegisterMask(reg) orelse return true; - return self.free_registers & mask != 0; + const index = indexOfRegIntoTracked(reg) orelse return true; + return self.free_registers.isSet(index); } /// Returns whether this register was allocated in the course @@ -111,16 +102,16 @@ pub fn RegisterManager( /// /// Returns false when this register is not tracked pub fn isRegAllocated(self: Self, reg: Register) bool { - const mask = getRegisterMask(reg) orelse return false; - return self.allocated_registers & mask != 0; + const index = indexOfRegIntoTracked(reg) orelse return false; + return self.allocated_registers.isSet(index); } /// Returns whether this register is locked /// /// Returns false when this register is not tracked pub fn isRegLocked(self: Self, reg: Register) bool { - const mask = getRegisterMask(reg) orelse return false; - return self.locked_registers & mask != 0; + const index = indexOfRegIntoTracked(reg) orelse return false; + return self.locked_registers.isSet(index); } pub const RegisterLock = struct { @@ -139,8 +130,8 @@ pub fn RegisterManager( log.debug(" register already locked", .{}); return null; } - const mask = getRegisterMask(reg) orelse return null; - self.locked_registers |= mask; + const index = indexOfRegIntoTracked(reg) orelse return null; + self.locked_registers.set(index); return RegisterLock{ .register = reg }; } @@ -149,8 +140,8 @@ pub fn RegisterManager( pub fn lockRegAssumeUnused(self: *Self, reg: Register) RegisterLock { log.debug("locking asserting free {}", .{reg}); assert(!self.isRegLocked(reg)); - const mask = getRegisterMask(reg) orelse unreachable; - self.locked_registers |= mask; + const index = indexOfRegIntoTracked(reg) orelse unreachable; + self.locked_registers.set(index); return RegisterLock{ .register = reg }; } @@ -172,13 +163,13 @@ pub fn RegisterManager( /// Call `lockReg` to obtain the lock first. pub fn unlockReg(self: *Self, lock: RegisterLock) void { log.debug("unlocking {}", .{lock.register}); - const mask = getRegisterMask(lock.register) orelse return; - self.locked_registers &= ~mask; + const index = indexOfRegIntoTracked(lock.register) orelse return; + self.locked_registers.unset(index); } /// Returns true when at least one register is locked pub fn lockedRegsExist(self: Self) bool { - return self.locked_registers != 0; + return self.locked_registers.count() > 0; } /// Allocates a specified number of registers, optionally @@ -192,10 +183,15 @@ pub fn RegisterManager( ) ?[count]Register { comptime assert(count > 0 and count <= tracked_registers.len); - const free_registers = self.free_registers & register_class; - const free_and_not_locked_registers = free_registers & ~self.locked_registers; - const free_and_not_locked_registers_count = @popCount(RegisterBitSet, free_and_not_locked_registers); - if (free_and_not_locked_registers_count < count) return null; + var free_and_not_locked_registers = self.free_registers; + free_and_not_locked_registers.setIntersection(register_class); + + var unlocked_registers = self.locked_registers; + unlocked_registers.toggleAll(); + + free_and_not_locked_registers.setIntersection(unlocked_registers); + + if (free_and_not_locked_registers.count() < count) return null; var regs: [count]Register = undefined; var i: usize = 0; @@ -242,10 +238,10 @@ pub fn RegisterManager( ) AllocateRegistersError![count]Register { comptime assert(count > 0 and count <= tracked_registers.len); - const available_registers_count = @popCount(RegisterBitSet, register_class); - const locked_registers = self.locked_registers & register_class; - const locked_registers_count = @popCount(RegisterBitSet, locked_registers); - if (count > available_registers_count - locked_registers_count) return error.OutOfRegisters; + var locked_registers = self.locked_registers; + locked_registers.setIntersection(register_class); + + if (count > register_class.count() - locked_registers.count()) return error.OutOfRegisters; const result = self.tryAllocRegs(count, insts, register_class) orelse blk: { // We'll take over the first count registers. Spill @@ -255,7 +251,7 @@ pub fn RegisterManager( var i: usize = 0; for (tracked_registers) |reg| { if (i >= count) break; - if (excludeRegister(reg, register_class)) continue; + if (excludeRegister(reg, register_class)) break; if (self.isRegLocked(reg)) continue; regs[i] = reg; @@ -352,334 +348,6 @@ pub fn RegisterManager( }; } -// TODO delete current implementation of RegisterManager above, and uncomment the one -// below once #11680 is fixed: -// https://github.com/ziglang/zig/issues/11680 - -//pub fn RegisterManager( -// comptime Function: type, -// comptime Register: type, -// comptime tracked_registers: []const Register, -//) type { -// // architectures which do not have a concept of registers should -// // refrain from using RegisterManager -// assert(tracked_registers.len > 0); // see note above - -// return struct { -// /// Tracks the AIR instruction allocated to every register. If -// /// no instruction is allocated to a register (i.e. the -// /// register is free), the value in that slot is undefined. -// /// -// /// The key must be canonical register. -// registers: [tracked_registers.len]Air.Inst.Index = undefined, -// /// Tracks which registers are free (in which case the -// /// corresponding bit is set to 1) -// free_registers: RegisterBitSet = RegisterBitSet.initFull(), -// /// Tracks all registers allocated in the course of this -// /// function -// allocated_registers: RegisterBitSet = RegisterBitSet.initEmpty(), -// /// Tracks registers which are locked from being allocated -// locked_registers: RegisterBitSet = RegisterBitSet.initEmpty(), - -// const Self = @This(); - -// pub const RegisterBitSet = StaticBitSet(tracked_registers.len); - -// fn getFunction(self: *Self) *Function { -// return @fieldParentPtr(Function, "register_manager", self); -// } - -// fn excludeRegister(reg: Register, register_class: RegisterBitSet) bool { -// const index = indexOfRegIntoTracked(reg) orelse return true; -// return !register_class.isSet(index); -// } - -// fn markRegAllocated(self: *Self, reg: Register) void { -// const index = indexOfRegIntoTracked(reg) orelse return; -// self.allocated_registers.set(index); -// } - -// fn markRegUsed(self: *Self, reg: Register) void { -// const index = indexOfRegIntoTracked(reg) orelse return; -// self.free_registers.unset(index); -// } - -// fn markRegFree(self: *Self, reg: Register) void { -// const index = indexOfRegIntoTracked(reg) orelse return; -// self.free_registers.set(index); -// } - -// pub fn indexOfReg( -// comptime registers: []const Register, -// reg: Register, -// ) ?std.math.IntFittingRange(0, registers.len - 1) { -// inline for (tracked_registers) |cpreg, i| { -// if (reg.id() == cpreg.id()) return i; -// } -// return null; -// } - -// pub fn indexOfRegIntoTracked(reg: Register) ?RegisterBitSet.ShiftInt { -// return indexOfReg(tracked_registers, reg); -// } - -// /// Returns true when this register is not tracked -// pub fn isRegFree(self: Self, reg: Register) bool { -// const index = indexOfRegIntoTracked(reg) orelse return true; -// return self.free_registers.isSet(index); -// } - -// /// Returns whether this register was allocated in the course -// /// of this function. -// /// -// /// Returns false when this register is not tracked -// pub fn isRegAllocated(self: Self, reg: Register) bool { -// const index = indexOfRegIntoTracked(reg) orelse return false; -// return self.allocated_registers.isSet(index); -// } - -// /// Returns whether this register is locked -// /// -// /// Returns false when this register is not tracked -// pub fn isRegLocked(self: Self, reg: Register) bool { -// const index = indexOfRegIntoTracked(reg) orelse return false; -// return self.locked_registers.isSet(index); -// } - -// pub const RegisterLock = struct { -// register: Register, -// }; - -// /// Prevents the register from being allocated until they are -// /// unlocked again. -// /// Returns `RegisterLock` if the register was not already -// /// locked, or `null` otherwise. -// /// Only the owner of the `RegisterLock` can unlock the -// /// register later. -// pub fn lockReg(self: *Self, reg: Register) ?RegisterLock { -// log.debug("locking {}", .{reg}); -// if (self.isRegLocked(reg)) { -// log.debug(" register already locked", .{}); -// return null; -// } -// const index = indexOfRegIntoTracked(reg) orelse return null; -// self.locked_registers.set(index); -// return RegisterLock{ .register = reg }; -// } - -// /// Like `lockReg` but asserts the register was unused always -// /// returning a valid lock. -// pub fn lockRegAssumeUnused(self: *Self, reg: Register) RegisterLock { -// log.debug("locking asserting free {}", .{reg}); -// assert(!self.isRegLocked(reg)); -// const index = indexOfRegIntoTracked(reg) orelse unreachable; -// self.locked_registers.set(index); -// return RegisterLock{ .register = reg }; -// } - -// /// Like `lockRegAssumeUnused` but locks multiple registers. -// pub fn lockRegsAssumeUnused( -// self: *Self, -// comptime count: comptime_int, -// regs: [count]Register, -// ) [count]RegisterLock { -// var buf: [count]RegisterLock = undefined; -// for (regs) |reg, i| { -// buf[i] = self.lockRegAssumeUnused(reg); -// } -// return buf; -// } - -// /// Unlocks the register allowing its re-allocation and re-use. -// /// Requires `RegisterLock` to unlock a register. -// /// Call `lockReg` to obtain the lock first. -// pub fn unlockReg(self: *Self, lock: RegisterLock) void { -// log.debug("unlocking {}", .{lock.register}); -// const index = indexOfRegIntoTracked(lock.register) orelse return; -// self.locked_registers.unset(index); -// } - -// /// Returns true when at least one register is locked -// pub fn lockedRegsExist(self: Self) bool { -// return self.locked_registers.count() > 0; -// } - -// /// Allocates a specified number of registers, optionally -// /// tracking them. Returns `null` if not enough registers are -// /// free. -// pub fn tryAllocRegs( -// self: *Self, -// comptime count: comptime_int, -// insts: [count]?Air.Inst.Index, -// register_class: RegisterBitSet, -// ) ?[count]Register { -// comptime assert(count > 0 and count <= tracked_registers.len); - -// var free_and_not_locked_registers = self.free_registers; -// free_and_not_locked_registers.setIntersection(register_class); - -// var unlocked_registers = self.locked_registers; -// unlocked_registers.toggleAll(); - -// free_and_not_locked_registers.setIntersection(unlocked_registers); - -// if (free_and_not_locked_registers.count() < count) return null; - -// var regs: [count]Register = undefined; -// var i: usize = 0; -// for (tracked_registers) |reg| { -// if (i >= count) break; -// if (excludeRegister(reg, register_class)) continue; -// if (self.isRegLocked(reg)) continue; -// if (!self.isRegFree(reg)) continue; - -// regs[i] = reg; -// i += 1; -// } -// assert(i == count); - -// for (regs) |reg, j| { -// self.markRegAllocated(reg); - -// if (insts[j]) |inst| { -// // Track the register -// const index = indexOfRegIntoTracked(reg).?; // indexOfReg() on a callee-preserved reg should never return null -// self.registers[index] = inst; -// self.markRegUsed(reg); -// } -// } - -// return regs; -// } - -// /// Allocates a register and optionally tracks it with a -// /// corresponding instruction. Returns `null` if all registers -// /// are allocated. -// pub fn tryAllocReg(self: *Self, inst: ?Air.Inst.Index, register_class: RegisterBitSet) ?Register { -// return if (tryAllocRegs(self, 1, .{inst}, register_class)) |regs| regs[0] else null; -// } - -// /// Allocates a specified number of registers, optionally -// /// tracking them. Asserts that count is not -// /// larger than the total number of registers available. -// pub fn allocRegs( -// self: *Self, -// comptime count: comptime_int, -// insts: [count]?Air.Inst.Index, -// register_class: RegisterBitSet, -// ) AllocateRegistersError![count]Register { -// comptime assert(count > 0 and count <= tracked_registers.len); - -// var locked_registers = self.locked_registers; -// locked_registers.setIntersection(register_class); - -// if (count > register_class.count() - locked_registers.count()) return error.OutOfRegisters; - -// const result = self.tryAllocRegs(count, insts, register_class) orelse blk: { -// // We'll take over the first count registers. Spill -// // the instructions that were previously there to a -// // stack allocations. -// var regs: [count]Register = undefined; -// var i: usize = 0; -// for (tracked_registers) |reg| { -// if (i >= count) break; -// if (excludeRegister(reg, register_class)) break; -// if (self.isRegLocked(reg)) continue; - -// regs[i] = reg; -// self.markRegAllocated(reg); -// const index = indexOfRegIntoTracked(reg).?; // indexOfReg() on a callee-preserved reg should never return null -// if (insts[i]) |inst| { -// // Track the register -// if (self.isRegFree(reg)) { -// self.markRegUsed(reg); -// } else { -// const spilled_inst = self.registers[index]; -// try self.getFunction().spillInstruction(reg, spilled_inst); -// } -// self.registers[index] = inst; -// } else { -// // Don't track the register -// if (!self.isRegFree(reg)) { -// const spilled_inst = self.registers[index]; -// try self.getFunction().spillInstruction(reg, spilled_inst); -// self.freeReg(reg); -// } -// } - -// i += 1; -// } - -// break :blk regs; -// }; - -// log.debug("allocated registers {any} for insts {any}", .{ result, insts }); -// return result; -// } - -// /// Allocates a register and optionally tracks it with a -// /// corresponding instruction. -// pub fn allocReg( -// self: *Self, -// inst: ?Air.Inst.Index, -// register_class: RegisterBitSet, -// ) AllocateRegistersError!Register { -// return (try self.allocRegs(1, .{inst}, register_class))[0]; -// } - -// /// Spills the register if it is currently allocated. If a -// /// corresponding instruction is passed, will also track this -// /// register. -// pub fn getReg(self: *Self, reg: Register, inst: ?Air.Inst.Index) AllocateRegistersError!void { -// const index = indexOfRegIntoTracked(reg) orelse return; -// log.debug("getReg {} for inst {}", .{ reg, inst }); -// self.markRegAllocated(reg); - -// if (inst) |tracked_inst| -// if (!self.isRegFree(reg)) { -// // Move the instruction that was previously there to a -// // stack allocation. -// const spilled_inst = self.registers[index]; -// self.registers[index] = tracked_inst; -// try self.getFunction().spillInstruction(reg, spilled_inst); -// } else { -// self.getRegAssumeFree(reg, tracked_inst); -// } -// else { -// if (!self.isRegFree(reg)) { -// // Move the instruction that was previously there to a -// // stack allocation. -// const spilled_inst = self.registers[index]; -// try self.getFunction().spillInstruction(reg, spilled_inst); -// self.freeReg(reg); -// } -// } -// } - -// /// Allocates the specified register with the specified -// /// instruction. Asserts that the register is free and no -// /// spilling is necessary. -// pub fn getRegAssumeFree(self: *Self, reg: Register, inst: Air.Inst.Index) void { -// const index = indexOfRegIntoTracked(reg) orelse return; -// log.debug("getRegAssumeFree {} for inst {}", .{ reg, inst }); -// self.markRegAllocated(reg); - -// assert(self.isRegFree(reg)); -// self.registers[index] = inst; -// self.markRegUsed(reg); -// } - -// /// Marks the specified register as free -// pub fn freeReg(self: *Self, reg: Register) void { -// const index = indexOfRegIntoTracked(reg) orelse return; -// log.debug("freeing register {}", .{reg}); - -// self.registers[index] = undefined; -// self.markRegFree(reg); -// } -// }; -//} - const MockRegister1 = enum(u2) { r0, r1, @@ -698,7 +366,14 @@ const MockRegister1 = enum(u2) { &MockRegister1.allocatable_registers, ); - const gp: RM.RegisterBitSet = std.math.maxInt(RM.RegisterBitSet); + const gp: RM.RegisterBitSet = blk: { + var set = RM.RegisterBitSet.initEmpty(); + set.setRangeValue(.{ + .start = 0, + .end = allocatable_registers.len, + }, true); + break :blk set; + }; }; const MockRegister2 = enum(u2) { @@ -719,7 +394,14 @@ const MockRegister2 = enum(u2) { &MockRegister2.allocatable_registers, ); - const gp: RM.RegisterBitSet = std.math.maxInt(RM.RegisterBitSet); + const gp: RM.RegisterBitSet = blk: { + var set = RM.RegisterBitSet.initEmpty(); + set.setRangeValue(.{ + .start = 0, + .end = allocatable_registers.len, + }, true); + break :blk set; + }; }; const MockRegister3 = enum(u3) { @@ -753,11 +435,22 @@ const MockRegister3 = enum(u3) { &MockRegister3.allocatable_registers, ); - const gp: RM.RegisterBitSet = @as(RM.RegisterBitSet, std.math.maxInt(std.meta.Int( - .unsigned, - gp_regs.len, - ))); - const ext: RM.RegisterBitSet = std.math.maxInt(RM.RegisterBitSet) - gp; + const gp: RM.RegisterBitSet = blk: { + var set = RM.RegisterBitSet.initEmpty(); + set.setRangeValue(.{ + .start = 0, + .end = gp_regs.len, + }, true); + break :blk set; + }; + const ext: RM.RegisterBitSet = blk: { + var set = RM.RegisterBitSet.initEmpty(); + set.setRangeValue(.{ + .start = gp_regs.len, + .end = allocatable_registers.len, + }, true); + break :blk set; + }; }; fn MockFunction(comptime Register: type) type { |
