fixed more bugs

Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
Jakub Doka 2025-03-17 17:02:46 +01:00
parent cfb17ed01b
commit 5b9e112ebd
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
11 changed files with 76 additions and 32 deletions

View file

@ -80,7 +80,7 @@ pub fn build(b: *std.Build) !void {
const out = run_gen.addOutputFileArg("tests.zig");
const test_run = b.addTest(.{
.name = "vendored_tests",
.name = "example_tests",
.root_source_file = out,
.target = b.graph.host,
.optimize = optimize,

1
profile.json Normal file

File diff suppressed because one or more lines are too long

View file

@ -87,9 +87,9 @@ pub const EmitOptions = struct {
entry: bool = false,
optimizations: struct {
verbose: bool = false,
dead_code_fuel: usize = 1000,
dead_code_fuel: usize = 10000,
mem2reg: bool = true,
peephole_fuel: usize = 1000,
peephole_fuel: usize = 10000,
do_gcm: bool = true,
arena: ?*root.Arena = null,
error_buf: ?*std.ArrayListUnmanaged(static_anal.Error) = null,

View file

@ -651,7 +651,7 @@ pub fn Func(comptime MachNode: type) type {
}
pub fn kill(self: *Node) void {
if (self.output_len != 0) utils.panic("{s}\n", .{self.outputs()});
if (self.output_len != 0) utils.panic("{any} {}\n", .{ self.outputs(), self });
std.debug.assert(self.output_len == 0);
for (self.inputs()) |oi| if (oi) |i| {
i.removeUse(self);
@ -961,23 +961,38 @@ pub fn Func(comptime MachNode: type) type {
}
pub fn subsumeNoKill(self: *Self, this: *Node, target: *Node) void {
std.debug.assert(this != target);
//std.debug.print("{} {} {any}\n", .{ target, this, target.outputs() });
for (self.arena.allocator().dupe(*Node, target.outputs()) catch unreachable) |use| {
if (use.id == std.math.maxInt(u16)) continue;
const index = std.mem.indexOfScalar(?*Node, use.inputs(), target) orelse {
utils.panic("{} {any} {}", .{ this, target.outputs(), use });
};
_ = self.setInput(use, index, this);
if (use == target) {
target.inputs()[index] = null;
target.removeUse(target);
} else {
_ = self.setInput(use, index, this);
}
}
var iter = self.interner.iterator();
while (iter.next()) |e| std.debug.assert(e.key_ptr.node.id != std.math.maxInt(u16));
if (@import("builtin").mode == .Debug) {
var iter = self.interner.iterator();
while (iter.next()) |e| std.debug.assert(e.key_ptr.node.id != std.math.maxInt(u16));
}
//if (target.outputs().len != 0)
// utils.panic("-- {any}\n", .{target.outputs()})
//else
// std.debug.print("--\n", .{});
}
pub fn subsume(self: *Self, this: *Node, target: *Node) void {
if (this.sloc == Sloc.none) this.sloc = target.sloc;
self.subsumeNoKill(this, target);
self.uninternNode(target);
self.subsumeNoKill(this, target);
target.kill();
}

View file

@ -1510,6 +1510,19 @@ pub fn typeCheck(self: *Codegen, expr: anytype, got: *Value, expected: Types.Id)
) };
}
if (got.ty.data() == .Enum) {
const len = @TypeOf(got.ty.data().Enum).Data.getFields(got.ty.data().Enum, self.types).len;
if (len <= 1) {
got.id = .{ .Value = self.bl.addIntImm(self.abiCata(expected).ByValue, 0) };
} else if (got.ty.size(self.types) < expected.size(self.types)) {
got.id = .{ .Value = self.bl.addUnOp(
.uext,
self.abiCata(expected).ByValue,
got.getValue(self),
) };
}
}
got.ty = expected;
}
@ -1602,7 +1615,12 @@ pub fn emitGenericStore(self: *Codegen, loc: *Node, value: *Value) void {
}
pub fn resolveAnonTy(self: *Codegen, expr: Ast.Id) !Types.Id {
return self.types.ct.evalTy("", .{ .Tmp = self }, expr);
const prev_name = self.name;
defer self.name = prev_name;
self.name = "";
var vl = try self.emitTyped(.{}, .type, expr);
return self.unwrapTyConst(expr, &vl);
}
pub fn resolveTy(self: *Codegen, name: []const u8, expr: Ast.Id) !Types.Id {
@ -1658,6 +1676,11 @@ pub fn lookupScopeItem(self: *Codegen, pos: Ast.Pos, bsty: Types.Id, name: []con
pub fn resolveGlobal(self: *Codegen, name: []const u8, bsty: Types.Id, ast: *const Ast, decl: Ast.Id, path: []Ast.Pos) EmitError!Value {
const vari = ast.exprs.getTyped(.Decl, decl).?;
// NOTE: we do this here particularly because the explicit type can contain a cycle
try self.types.ct.addInProgress(vari.value, bsty.file(self.types).?);
defer _ = self.types.ct.in_progress.pop().?;
const ty = if (vari.ty.tag() == .Void) null else try self.resolveAnonTy(vari.ty);
const global_ty, const new = self.types.resolveGlobal(bsty, name, vari.value);

View file

@ -299,6 +299,20 @@ pub fn inferType(self: *Comptime, name: []const u8, scope: Codegen.Scope, ctx: C
})[1];
}
pub fn addInProgress(self: *Comptime, expr: Ast.Id, file: Types.File) !void {
const types = self.getTypes();
for (self.in_progress.items, 0..) |p, i| {
if (std.meta.eql(p, .{ .ast = expr, .file = file })) {
for (self.in_progress.items[i..]) |lc| {
types.report(lc.file, lc.ast, "cycle goes trough here", .{});
}
return error.Never;
}
}
self.in_progress.append(self.comptime_code.gpa, .{ .ast = expr, .file = file }) catch unreachable;
}
pub fn jitExprLow(
self: *Comptime,
name: []const u8,
@ -316,17 +330,6 @@ pub fn jitExprLow(
var gen = Codegen.init(self.getGpa(), tmp.arena, types, .@"comptime");
defer gen.deinit();
for (self.in_progress.items, 0..) |p, i| {
if (std.meta.eql(p, .{ .ast = value, .file = scope.file(types) })) {
for (self.in_progress.items[i..]) |lc| {
types.report(lc.file, lc.ast, "cycle goes trough here", .{});
}
return error.Never;
}
}
self.in_progress.append(self.comptime_code.gpa, .{ .ast = value, .file = scope.file(types) }) catch unreachable;
defer _ = self.in_progress.pop().?;
gen.only_inference = only_inference;
const reloc_frame = self.comptime_code.global_relocs.items.len;

View file

@ -554,13 +554,13 @@ pub const Abi = enum {
for (@TypeOf(stru).Data.getFields(stru, types)) |f| {
const fspec = Abi.ableos.categorize(f.ty, types) orelse continue;
if (fspec == .Imaginary) continue;
if (fspec == .ByRef) return fspec;
if (res == .Imaginary) {
res = fspec;
offset += f.ty.size(types);
continue;
}
if (fspec == .ByRef) return fspec;
if (fspec == .ByValuePair) return .ByRef;
if (res == .ByValuePair) return .ByRef;
std.debug.assert(res != .ByRef);

View file

@ -179,12 +179,14 @@ pub fn emitFunc(self: *HbvmGen, func: *Func, opts: Mach.EmitOptions) void {
if (bb.base.kind == .CallEnd) break false;
} else true;
const reg_shift: u8 = 1; //if (is_tail) 12 else 32;
const reg_shift: u8 = 1;
for (self.allocs) |*r| r.* += reg_shift;
const used_registers = if (self.allocs.len == 0) 0 else @min(std.mem.max(u16, self.allocs), max_alloc_regs) -| 31;
const max_reg = std.mem.max(u16, self.allocs);
const used_registers = if (self.allocs.len == 0) 0 else @min(max_reg, max_alloc_regs) -|
(@intFromEnum(isa.Reg.ret_addr) - @intFromBool(is_tail));
const used_reg_size = @as(u16, (used_registers + @intFromBool(!is_tail))) * 8;
const spill_count = (std.mem.max(u16, self.allocs) -| max_alloc_regs) * 8;
const spill_count = (max_reg -| max_alloc_regs) * 8;
var local_size: i64 = 0;
if (func.root.outputs().len > 1) {

View file

@ -38,7 +38,7 @@ pub fn runTest(name: []const u8, code: [:0]const u8) !void {
}
pub fn runFuzzFindingTest(name: []const u8, code: []const u8) !void {
utils.Arena.initScratch(1024 * 1024);
utils.Arena.initScratch(1024 * 1024 * 10);
defer utils.Arena.deinitScratch();
const gpa = std.testing.allocator;
@ -46,9 +46,9 @@ pub fn runFuzzFindingTest(name: []const u8, code: []const u8) !void {
std.debug.print("{s}\n", .{code});
//errdefer {
// const stderr = std.io.getStdErr();
// const colors = std.io.tty.detectConfig(stderr);
// test_util.testBuilder(name, code, gpa, stderr.writer().any(), colors, true) catch {};
//const stderr = std.io.getStdErr();
//const colors = std.io.tty.detectConfig(stderr);
//test_util.testBuilder(name, code, gpa, stderr.writer().any(), colors, true) catch {};
//}
try test_util.testBuilder(name, code, gpa, std.io.null_writer.any(), .no_color, false);

View file

@ -1,3 +1,3 @@
main:
li32 $1, 0
li64 $1, 0
tx

View file

@ -12,10 +12,10 @@ main:
ld $31, $254, -24, 24
tx
NameMap(Enum = Nm)(StrBuf = [6]u8, IndexBuf = [4]uint).get:
andi $3, $2, 255
addi64 $3, $3, 1
addi64 $4, $1, 8
andi $2, $2, 255
addi64 $3, $2, 1
muli64 $2, $2, 8
addi64 $4, $1, 8
muli64 $3, $3, 8
add64 $2, $4, $2
add64 $3, $4, $3