authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-06-07 18:10:28+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-06-07 19:33:43+02:00
log0c727604540df7dbff4f57e4599fa01e01b36695
treea0804a6b8417b5c80360b394a87e583caf1a38b7
parentfc015231ad4e2e449e848fd08dd003efd049ad43

x64: optimise element offset calculation if dealing with immediates

If `index` MCValue is actually an immediate, we can calculate offset directly at "comptime" rather than at runtime.

1 files changed, 16 insertions(+), 2 deletions(-)

src/arch/x86_64/CodeGen.zig+16-2
...@@ -2100,8 +2100,22 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2100,8 +2100,22 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
2100}2100}
21012101
2102fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Register {2102fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Register {
2103 const reg = try self.copyToTmpRegister(index_ty, index);2103 const reg: Register = blk: {
2104 try self.genIntMulComplexOpMir(index_ty, .{ .register = reg }, .{ .immediate = elem_size });2104 switch (index) {
2105 .immediate => |imm| {
2106 // Optimisation: if index MCValue is an immediate, we can multiply in `comptime`
2107 // and set the register directly to the scaled offset as an immediate.
2108 const reg = try self.register_manager.allocReg(null, gp);
2109 try self.genSetReg(index_ty, reg, .{ .immediate = imm * elem_size });
2110 break :blk reg;
2111 },
2112 else => {
2113 const reg = try self.copyToTmpRegister(index_ty, index);
2114 try self.genIntMulComplexOpMir(index_ty, .{ .register = reg }, .{ .immediate = elem_size });
2115 break :blk reg;
2116 },
2117 }
2118 };
2105 return reg;2119 return reg;
2106}2120}
21072121