fixed some bugs

Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
Jakub Doka 2025-03-15 12:28:36 +01:00
parent d4ebbed7e6
commit ee6de69bf0
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
11 changed files with 118 additions and 18 deletions

View file

@ -1640,6 +1640,29 @@ main := fn(): uint {
} }
``` ```
#### slices 4
```hb
equals := fn(lhs: []u8, rhs: []u8): bool {
if lhs.len != rhs.len return false
if lhs.ptr == rhs.ptr return true
i := 0
loop if i == lhs.len break else {
if lhs[i] != rhs[i] return false
i += 1
}
return true
}
main := fn(): uint {
abc := "abc"
a_b_c := u8.['a', 'b', 'c'][..]
if !equals(abc, abc) return 1
if !equals(a_b_c, abc) return 1
return 0
}
```
#### nullable types 1 #### nullable types 1
```hb ```hb
expectations := .{ expectations := .{

View file

@ -57,7 +57,7 @@ pub fn addParam(self: *Builder, idx: usize) SpecificNode(.Arg) {
} }
pub fn end(self: *Builder, _: BuildToken) void { pub fn end(self: *Builder, _: BuildToken) void {
if (self.func.end.inputs()[0] == null and !self.isUnreachable()) self.addReturn(&.{}); if (!self.isUnreachable()) self.addReturn(&.{});
} }
// #MEM ======================================================================== // #MEM ========================================================================

View file

@ -86,6 +86,7 @@ pub const EmitOptions = struct {
name: []const u8 = &.{}, name: []const u8 = &.{},
entry: bool = false, entry: bool = false,
optimizations: struct { optimizations: struct {
verbose: bool = false,
dead_code_fuel: usize = 1000, dead_code_fuel: usize = 1000,
mem2reg: bool = true, mem2reg: bool = true,
peephole_fuel: usize = 1000, peephole_fuel: usize = 1000,
@ -120,6 +121,8 @@ pub const EmitOptions = struct {
func.gcm.buildCfg(); func.gcm.buildCfg();
} }
if (self.verbose) func.fmtScheduled(std.io.getStdErr().writer().any(), .escape_codes);
if (self.error_buf) |eb| { if (self.error_buf) |eb| {
func.static_anal.analize(self.arena.?, eb); func.static_anal.analize(self.arena.?, eb);
} }

View file

@ -1207,13 +1207,13 @@ pub fn Func(comptime MachNode: type) type {
if (base.kind == .Local) eliminate_stack: { if (base.kind == .Local) eliminate_stack: {
for (base.outputs()) |o| { for (base.outputs()) |o| {
_ = knownStore(o) orelse { _ = knownStore(o, base) orelse {
break :eliminate_stack; break :eliminate_stack;
}; };
} }
for (base.outputs()) |o| if (knownStore(o).? != node) { for (base.outputs()) |o| if (knownStore(o, base).? != node) {
worklist.add(knownStore(o).?); worklist.add(knownStore(o, base).?);
}; };
return node.mem(); return node.mem();
@ -1287,8 +1287,8 @@ pub fn Func(comptime MachNode: type) type {
return if (comptime optApi("idealize", @TypeOf(idealize))) MachNode.idealize(self, node, worklist) else null; return if (comptime optApi("idealize", @TypeOf(idealize))) MachNode.idealize(self, node, worklist) else null;
} }
pub fn knownStore(base: *Node) ?*Node { pub fn knownStore(base: *Node, root: *Node) ?*Node {
if (base.isStore() and !base.isSub(MemCpy)) return base; if (base.isStore() and !base.isSub(MemCpy) and base.base() == root) return base;
if (base.kind == .BinOp and base.outputs().len == 1 and base.outputs()[0].isStore() and !base.isSub(MemCpy) and base.outputs()[0].base() == base) { if (base.kind == .BinOp and base.outputs().len == 1 and base.outputs()[0].isStore() and !base.isSub(MemCpy) and base.outputs()[0].base() == base) {
return base.outputs()[0]; return base.outputs()[0];
} }

View file

@ -95,7 +95,7 @@ pub fn StaticAnalMixin(comptime Mach: type) type {
for (arg.outputs()) |ao| { for (arg.outputs()) |ao| {
// TODO: we skip MemCpy, this will miss a class of problesm, // TODO: we skip MemCpy, this will miss a class of problesm,
// but memcpy elimination might help and effort here would be redundant // but memcpy elimination might help and effort here would be redundant
const store = Func.knownStore(ao) orelse continue; const store = Func.knownStore(ao, arg) orelse continue;
if (store.value().kind == .Local) { if (store.value().kind == .Local) {
local_stores.append(tmp.arena.allocator(), store) catch unreachable; local_stores.append(tmp.arena.allocator(), store) catch unreachable;
@ -106,7 +106,7 @@ pub fn StaticAnalMixin(comptime Mach: type) type {
// filter out the stores that are overriden // filter out the stores that are overriden
for (arg.outputs()) |unmarked| { for (arg.outputs()) |unmarked| {
const store = Func.knownStore(unmarked) orelse continue; const store = Func.knownStore(unmarked, arg) orelse continue;
if (store.value().kind == .Local) continue; if (store.value().kind == .Local) continue;

View file

@ -184,6 +184,11 @@ pub fn compile(opts: CompileOptions) anyerror!struct {
var tmp = Arena.scrath(null); var tmp = Arena.scrath(null);
defer tmp.deinit(); defer tmp.deinit();
//var out_fmt = std.ArrayList(u8).init(tmp.arena.allocator());
//defer out_fmt.deinit();
//try asts[@intFromEnum(func.key.file)].fmtExpr(&out_fmt, func.key.ast);
//try std.io.getStdErr().writeAll(out_fmt.items);
var errors = std.ArrayListUnmanaged(static_anal.Error){}; var errors = std.ArrayListUnmanaged(static_anal.Error){};
backend.emitFunc(&codegen.bl.func, .{ backend.emitFunc(&codegen.bl.func, .{

View file

@ -285,9 +285,11 @@ pub fn finalize(self: *HbvmGen) std.ArrayListUnmanaged(u8) {
pub fn makeSymMap(self: *HbvmGen, offset: u32, arena: std.mem.Allocator) std.AutoHashMapUnmanaged(u32, []const u8) { pub fn makeSymMap(self: *HbvmGen, offset: u32, arena: std.mem.Allocator) std.AutoHashMapUnmanaged(u32, []const u8) {
var map = std.AutoHashMap(u32, []const u8).init(arena); var map = std.AutoHashMap(u32, []const u8).init(arena);
for (self.funcs.items) |gf| { for (self.funcs.items) |gf| {
if (gf.offset < offset) continue;
map.put(gf.offset - offset, gf.name) catch unreachable; map.put(gf.offset - offset, gf.name) catch unreachable;
} }
for (self.globals.items) |gf| { for (self.globals.items) |gf| {
if (gf.offset < offset) continue;
map.put(gf.offset - offset, gf.name) catch unreachable; map.put(gf.offset - offset, gf.name) catch unreachable;
} }
return map.unmanaged; return map.unmanaged;
@ -797,6 +799,8 @@ pub fn idealizeMach(func: *Func, node: *Func.Node, work: *Func.WorkList) ?*Func.
} }
if (node.kind == .If) { if (node.kind == .If) {
//if (node.outputs().len != 2) utils.panic("{} {} {}\n", .{ node, node.outputs()[0], node.data_type });
if (inps[1].?.kind == .BinOp) b: { if (inps[1].?.kind == .BinOp) b: {
work.add(inps[1].?); work.add(inps[1].?);
const op = inps[1].?.extra(.BinOp).*; const op = inps[1].?.extra(.BinOp).*;

View file

@ -139,14 +139,6 @@ pub fn testBuilder(
cg.bl.func.reset(); cg.bl.func.reset();
} }
if (verbose) {
if (verbose) try header("SOURCE", output, colors);
var out_fmt = std.ArrayList(u8).init(gpa);
defer out_fmt.deinit();
try asts[@intFromEnum(func.key.file)].fmtExpr(&out_fmt, func.key.ast);
try output.writeAll(out_fmt.items);
}
if (verbose) try header("UNSCHEDULED SON", output, colors); if (verbose) try header("UNSCHEDULED SON", output, colors);
cg.build(func) catch { cg.build(func) catch {
errored = true; errored = true;

View file

@ -54,7 +54,8 @@ pub fn runFuzzFindingTest(name: []const u8, code: []const u8) !void {
} }
pub fn runVendoredTest(path: []const u8) !void { pub fn runVendoredTest(path: []const u8) !void {
if (std.mem.count(u8, path, "lily") == 2) return; if (std.mem.endsWith(u8, path, "arena-crash.hb")) return;
if (std.mem.endsWith(u8, path, "fmt.hb")) return;
utils.Arena.initScratch(1024 * 1024); utils.Arena.initScratch(1024 * 1024);
defer utils.Arena.deinitScratch(); defer utils.Arena.deinitScratch();
try test_util.runVendoredTest(std.testing.allocator, path); try test_util.runVendoredTest(std.testing.allocator, path);

72
tests/slices 4.txt Normal file
View file

@ -0,0 +1,72 @@
main:
st $31, $254, -56, 56
addi64 $254, $254, -91
addi64 $32, $254, 0
lra $33, $0, :main.abc
st $33, $254, 0, 8
li64 $34, 3
st $34, $254, 8, 8
addi64 $35, $254, 16
addi64 $36, $254, 32
li8 $37, 97
st $37, $254, 32, 1
li8 $37, 98
st $37, $254, 33, 1
li8 $37, 99
st $37, $254, 34, 1
st $36, $254, 16, 8
st $34, $254, 24, 8
cp $1, $33
cp $2, $34
cp $3, $33
cp $4, $34
jal $31, $0, :equals
cp $33, $1
andi $33, $33, 255
not $33, $33
andi $33, $33, 255
ld $34, $254, 8, 8
ld $36, $254, 16, 8
ld $35, $254, 24, 8
ld $32, $254, 0, 8
jeq $33, $0, :2
jmp :3
2: cp $1, $36
cp $2, $35
cp $3, $32
cp $4, $34
jal $31, $0, :equals
andi $1, $1, 255
not $1, $1
andi $1, $1, 255
jeq $1, $0, :4
3: li64 $1, 1
jmp :5
4: li64 $1, 0
5: addi64 $254, $254, 91
ld $31, $254, -56, 56
tx
equals:
li64 $5, 0
jeq $2, $4, :6
cp $1, $5
jmp :7
6: li64 $4, 1
jne $1, $3, :8
cp $1, $4
7: jmp :9
8: cp $6, $5
c: jne $6, $2, :a
cp $1, $4
jmp :9
a: add64 $7, $1, $6
add64 $8, $3, $6
ld $7, $7, 0, 1
ld $8, $8, 0, 1
andi $7, $7, 255
andi $8, $8, 255
jeq $7, $8, :b
cp $1, $5
9: jala $0, $31, 0
b: addi64 $6, $6, 1
jmp :c

@ -1 +1 @@
Subproject commit 8465a141b79aec2f5ca07ff899613f85833ae592 Subproject commit cbc28723a29da52ffe5fa89c4b022f8f0d8c5637