aboutsummaryrefslogtreecommitdiff
path: root/src/compile.zig
diff options
context:
space:
mode:
authorMathias Magnusson <mathias@magnusson.space>2025-07-31 00:35:04 +0200
committerMathias Magnusson <mathias@magnusson.space>2025-07-31 00:35:04 +0200
commit71995702df08e91ae2aea7c23def5ffee0835cd1 (patch)
tree12b2f7b8415077f9a6ba33e0c7aba82056d1d8ec /src/compile.zig
parent69ecbca927d963311469f4634c002553d0c99bd4 (diff)
downloadhuginn-71995702df08e91ae2aea7c23def5ffee0835cd1.tar.gz
use saved rregisters when needed
& store and restore saved registers on the stack
Diffstat (limited to 'src/compile.zig')
-rw-r--r--src/compile.zig14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/compile.zig b/src/compile.zig
index 0ce170c..3ee3eb0 100644
--- a/src/compile.zig
+++ b/src/compile.zig
@@ -94,6 +94,7 @@ pub const BasicBlock = struct {
instrs: std.ArrayListUnmanaged(Instr) = .empty,
vreg_last_use: std.AutoHashMapUnmanaged(VReg, usize) = .empty,
+ vreg_used_during_call: std.AutoHashMapUnmanaged(VReg, void) = .empty,
fn finalize(self: *BasicBlock, allocator: Allocator) !void {
std.debug.assert(self.instrs.items.len > 0);
@@ -102,11 +103,18 @@ pub const BasicBlock = struct {
});
self.vreg_last_use = .empty;
+ var set_at: std.AutoHashMapUnmanaged(VReg, usize) = .empty;
+ var last_call: usize = 0;
for (0.., self.instrs.items) |i, instr| {
- for (instr.sources().slice()) |src|
- try self.vreg_last_use.put(allocator, src, i);
- if (instr.dest()) |dest|
+ if (instr.dest()) |dest| {
try self.vreg_last_use.put(allocator, dest, i);
+ try set_at.put(allocator, dest, i);
+ }
+ for (instr.sources().slice()) |src| {
+ try self.vreg_last_use.put(allocator, src, i);
+ if (set_at.get(src).? < last_call) try self.vreg_used_during_call.put(allocator, src, {});
+ }
+ if (instr.type == .call) last_call = i;
}
}