aboutsummaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2023-11-03 07:55:09 -0400
committerJacob Young <jacobly0@users.noreply.github.com>2023-11-03 23:18:23 -0400
commit46d3e5bb04393c6be196b10e262d122e008403aa (patch)
tree295250ac18b7151352bd64cac40c2e97a278534f /src/arch
parent509be7cf1f10c5d329d2b0524f2af6bfcabd52de (diff)
downloadzig-46d3e5bb04393c6be196b10e262d122e008403aa.tar.gz
zig-46d3e5bb04393c6be196b10e262d122e008403aa.zip
x86_64: reduce `RegisterManager` performance regression
This reduces the regression from 0.11.0 by 95%. Closes #17678
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86_64/CodeGen.zig30
-rw-r--r--src/arch/x86_64/bits.zig2
2 files changed, 21 insertions, 11 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig
index 9d0a9e05b9..989af5565c 100644
--- a/src/arch/x86_64/CodeGen.zig
+++ b/src/arch/x86_64/CodeGen.zig
@@ -2608,8 +2608,17 @@ pub fn spillEflagsIfOccupied(self: *Self) !void {
}
}
-pub fn spillRegisters(self: *Self, registers: []const Register) !void {
- for (registers) |reg| try self.register_manager.getReg(reg, null);
+pub fn spillCallerPreservedRegs(self: *Self, cc: std.builtin.CallingConvention) !void {
+ switch (cc) {
+ inline .SysV, .Win64 => |known_cc| try self.spillRegisters(
+ comptime abi.getCallerPreservedRegs(known_cc),
+ ),
+ else => unreachable,
+ }
+}
+
+pub fn spillRegisters(self: *Self, comptime registers: []const Register) !void {
+ inline for (registers) |reg| try self.register_manager.getKnownReg(reg, null);
}
/// Copies a value to a register without tracking the register. The register is not considered
@@ -10639,30 +10648,30 @@ fn genCall(self: *Self, info: union(enum) {
}
try self.spillEflagsIfOccupied();
- try self.spillRegisters(abi.getCallerPreservedRegs(resolved_cc));
+ try self.spillCallerPreservedRegs(resolved_cc);
// set stack arguments first because this can clobber registers
// also clobber spill arguments as we go
switch (call_info.return_value.long) {
.none, .unreach => {},
- .indirect => |reg_off| try self.spillRegisters(&.{reg_off.reg}),
+ .indirect => |reg_off| try self.register_manager.getReg(reg_off.reg, null),
else => unreachable,
}
for (call_info.args, arg_types, args, frame_indices) |dst_arg, arg_ty, src_arg, *frame_index|
switch (dst_arg) {
.none => {},
.register => |reg| {
- try self.spillRegisters(&.{reg});
+ try self.register_manager.getReg(reg, null);
try reg_locks.append(self.register_manager.lockReg(reg));
},
.register_pair => |regs| {
- try self.spillRegisters(&regs);
+ for (regs) |reg| try self.register_manager.getReg(reg, null);
try reg_locks.appendSlice(&self.register_manager.lockRegs(2, regs));
},
.indirect => |reg_off| {
frame_index.* = try self.allocFrameIndex(FrameAlloc.initType(arg_ty, mod));
try self.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg);
- try self.spillRegisters(&.{reg_off.reg});
+ try self.register_manager.getReg(reg_off.reg, null);
try reg_locks.append(self.register_manager.lockReg(reg_off.reg));
},
.load_frame => {
@@ -11990,8 +11999,9 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
var args = std.ArrayList(MCValue).init(self.gpa);
try args.ensureTotalCapacity(outputs.len + inputs.len);
defer {
- for (args.items) |arg| if (arg.getReg()) |reg|
- self.register_manager.unlockReg(.{ .register = reg });
+ for (args.items) |arg| if (arg.getReg()) |reg| self.register_manager.unlockReg(.{
+ .tracked_index = RegisterManager.indexOfRegIntoTracked(reg) orelse continue,
+ });
args.deinit();
}
var arg_map = std.StringHashMap(u8).init(self.gpa);
@@ -14557,7 +14567,7 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
}
try self.spillEflagsIfOccupied();
- try self.spillRegisters(abi.getCallerPreservedRegs(resolved_cc));
+ try self.spillCallerPreservedRegs(resolved_cc);
const param_regs = abi.getCAbiIntParamRegs(resolved_cc);
diff --git a/src/arch/x86_64/bits.zig b/src/arch/x86_64/bits.zig
index 579934da8e..554f944054 100644
--- a/src/arch/x86_64/bits.zig
+++ b/src/arch/x86_64/bits.zig
@@ -222,7 +222,7 @@ pub const Register = enum(u7) {
@intFromEnum(Register.eax) ... @intFromEnum(Register.r15d) => @intFromEnum(Register.eax),
@intFromEnum(Register.ax) ... @intFromEnum(Register.r15w) => @intFromEnum(Register.ax),
@intFromEnum(Register.al) ... @intFromEnum(Register.r15b) => @intFromEnum(Register.al),
- @intFromEnum(Register.ah) ... @intFromEnum(Register.bh) => @intFromEnum(Register.ah) - 4,
+ @intFromEnum(Register.ah) ... @intFromEnum(Register.bh) => @intFromEnum(Register.ah),
@intFromEnum(Register.ymm0) ... @intFromEnum(Register.ymm15) => @intFromEnum(Register.ymm0) - 16,
@intFromEnum(Register.xmm0) ... @intFromEnum(Register.xmm15) => @intFromEnum(Register.xmm0) - 16,