aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-06-07 18:10:28 +0200
committerJakub Konka <kubkon@jakubkonka.com>2022-06-07 19:33:43 +0200
commit0c727604540df7dbff4f57e4599fa01e01b36695 (patch)
treea0804a6b8417b5c80360b394a87e583caf1a38b7 /src
parentfc015231ad4e2e449e848fd08dd003efd049ad43 (diff)
downloadzig-0c727604540df7dbff4f57e4599fa01e01b36695.tar.gz
zig-0c727604540df7dbff4f57e4599fa01e01b36695.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86_64/CodeGen.zig18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig
index be41f99b56..5c81233845 100644
--- a/src/arch/x86_64/CodeGen.zig
+++ b/src/arch/x86_64/CodeGen.zig
@@ -2100,8 +2100,22 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Register {
- const reg = try self.copyToTmpRegister(index_ty, index);
- try self.genIntMulComplexOpMir(index_ty, .{ .register = reg }, .{ .immediate = elem_size });
+ const reg: Register = blk: {
+ switch (index) {
+ .immediate => |imm| {
+ // Optimisation: if index MCValue is an immediate, we can multiply in `comptime`
+ // and set the register directly to the scaled offset as an immediate.
+ const reg = try self.register_manager.allocReg(null, gp);
+ try self.genSetReg(index_ty, reg, .{ .immediate = imm * elem_size });
+ break :blk reg;
+ },
+ else => {
+ const reg = try self.copyToTmpRegister(index_ty, index);
+ try self.genIntMulComplexOpMir(index_ty, .{ .register = reg }, .{ .immediate = elem_size });
+ break :blk reg;
+ },
+ }
+ };
return reg;
}