aboutsummaryrefslogtreecommitdiff
path: root/src/compile.zig
diff options
context:
space:
mode:
authorMathias Magnusson <mathias@magnusson.space>2025-06-02 21:55:11 +0200
committerMathias Magnusson <mathias@magnusson.space>2025-06-02 22:01:00 +0200
commite2e77b4b06e51c7f7d3ea187defaf1ad08e513c1 (patch)
tree71879baf4d1a8db3163e599bc3b628c01b6ba942 /src/compile.zig
parente18b172d3e4e31b4d50ca978a66187730f744a31 (diff)
downloadhuginn-e2e77b4b06e51c7f7d3ea187defaf1ad08e513c1.tar.gz
remove the need for explicit discard instructions
by also considering an instruction's destination register(s) to be uses and when cleaning up registers, also cleaning up those from previous instructions (specifically this is the output of the last instruction if it is not used anywhere)
Diffstat (limited to 'src/compile.zig')
-rw-r--r--src/compile.zig29
1 files changed, 7 insertions, 22 deletions
diff --git a/src/compile.zig b/src/compile.zig
index c837495..ac7768e 100644
--- a/src/compile.zig
+++ b/src/compile.zig
@@ -15,7 +15,6 @@ pub const Instr = struct {
constant: Constant,
bin_op: BinOp,
proc_call: ProcCall,
- discard: Discard,
};
pub const Constant = struct {
@@ -58,14 +57,6 @@ pub const Instr = struct {
}
};
- pub const Discard = struct {
- vreg: VReg,
-
- pub fn sources(self: Discard) Sources {
- return Sources.fromSlice(&.{self.vreg}) catch unreachable;
- }
- };
-
pub fn sources(self: Instr) Sources {
return switch (self.type) {
inline else => |instr| instr.sources(),
@@ -75,7 +66,6 @@ pub const Instr = struct {
pub fn dest(self: *const Instr) ?VReg {
return switch (self.type) {
inline .constant, .bin_op, .proc_call => |s| s.dest,
- // inline .x => null,
};
}
@@ -85,17 +75,15 @@ pub const Instr = struct {
pub const Block = struct {
// arguments: []Reg,
instrs: []Instr,
- vreg_last_use: std.AutoHashMap(usize, std.ArrayList(VReg)),
+ vreg_last_use: std.AutoHashMap(VReg, usize),
fn init(allocator: Allocator, instrs: []Instr) !Block {
- var vreg_last_use: std.AutoHashMap(usize, std.ArrayList(VReg)) = .init(allocator);
+ var vreg_last_use: std.AutoHashMap(VReg, usize) = .init(allocator);
for (0.., instrs) |i, instr| {
- const kv = try vreg_last_use.getOrPut(i);
- if (!kv.found_existing) kv.value_ptr.* = .init(allocator);
- for (instr.sources().slice()) |src| {
- if (std.mem.indexOfScalar(VReg, kv.value_ptr.items, src) == null)
- try kv.value_ptr.append(src);
- }
+ for (instr.sources().slice()) |src|
+ try vreg_last_use.put(src, i);
+ if (instr.dest()) |dest|
+ try vreg_last_use.put(dest, i);
}
return .{
.instrs = instrs,
@@ -134,10 +122,7 @@ const CompileContext = struct {
fn compileStmt(self: *Self, stmt: parse.Stmt) !void {
switch (stmt.type) {
- .expr => |expr| try self.addInstr(.{
- .loc = stmt.loc,
- .type = .{ .discard = .{ .vreg = try self.compileExpr(expr) } },
- }),
+ .expr => |expr| _ = try self.compileExpr(expr),
.declare_var => |declare_var| {
const val = try self.compileExpr(declare_var.value);
const name = declare_var.ident.getIdent(self.source);