authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-08 18:05:54+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-08 21:00:07+01:00
log9981b3fd2f7ab85146efa9feebe08a795411d131
tree426608bca102609dd4e4926179b01b68af7b4081
parentf50203c83667ed3ad0c57fdc953322a5f9c221ac

stage2: tiny improvements all over the place

* pass more x64 behavior tests * return with a TODO error when lowering a decl with no runtime bits * insert some debug logs for tracing recursive descent down the type-value tree when lowering types * print `Decl`'s name when print debugging `decl_ref` value

8 files changed, 27 insertions(+), 9 deletions(-)

src/arch/wasm/CodeGen.zig+2
...@@ -970,6 +970,8 @@ pub const DeclGen = struct {...@@ -970,6 +970,8 @@ pub const DeclGen = struct {
970970
971 /// Generates the wasm bytecode for the declaration belonging to `Context`971 /// Generates the wasm bytecode for the declaration belonging to `Context`
972 fn genTypedValue(self: *DeclGen, ty: Type, val: Value) InnerError!Result {972 fn genTypedValue(self: *DeclGen, ty: Type, val: Value) InnerError!Result {
973 log.debug("genTypedValue: ty = {}, val = {}", .{ ty, val });
974
973 const writer = self.code.writer();975 const writer = self.code.writer();
974 if (val.isUndef()) {976 if (val.isUndef()) {
975 try writer.writeByteNTimes(0xaa, @intCast(usize, ty.abiSize(self.target())));977 try writer.writeByteNTimes(0xaa, @intCast(usize, ty.abiSize(self.target())));
src/arch/x86_64/CodeGen.zig+7-4
...@@ -1973,6 +1973,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde...@@ -1973,6 +1973,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
1973 if (self.liveness.isUnused(inst)) {1973 if (self.liveness.isUnused(inst)) {
1974 return MCValue.dead;1974 return MCValue.dead;
1975 }1975 }
1976
1976 const mcv = try self.resolveInst(operand);1977 const mcv = try self.resolveInst(operand);
1977 const ptr_ty = self.air.typeOf(operand);1978 const ptr_ty = self.air.typeOf(operand);
1978 const struct_ty = ptr_ty.childType();1979 const struct_ty = ptr_ty.childType();
...@@ -2190,6 +2191,7 @@ fn genBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs:...@@ -2190,6 +2191,7 @@ fn genBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs:
2190}2191}
21912192
2192fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void {2193fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void {
2194 const abi_size = dst_ty.abiSize(self.target.*);
2193 switch (dst_mcv) {2195 switch (dst_mcv) {
2194 .none => unreachable,2196 .none => unreachable,
2195 .undef => unreachable,2197 .undef => unreachable,
...@@ -2216,7 +2218,6 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC...@@ -2216,7 +2218,6 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC
2216 });2218 });
2217 },2219 },
2218 .immediate => |imm| {2220 .immediate => |imm| {
2219 const abi_size = dst_ty.abiSize(self.target.*);
2220 _ = try self.addInst(.{2221 _ = try self.addInst(.{
2221 .tag = mir_tag,2222 .tag = mir_tag,
2222 .ops = (Mir.Ops{2223 .ops = (Mir.Ops{
...@@ -2226,7 +2227,11 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC...@@ -2226,7 +2227,11 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC
2226 });2227 });
2227 },2228 },
2228 .embedded_in_code, .memory => {2229 .embedded_in_code, .memory => {
2229 return self.fail("TODO implement x86 ADD/SUB/CMP source memory", .{});2230 assert(abi_size <= 8);
2231 self.register_manager.freezeRegs(&.{dst_reg});
2232 defer self.register_manager.unfreezeRegs(&.{dst_reg});
2233 const reg = try self.copyToTmpRegister(dst_ty, src_mcv);
2234 return self.genBinMathOpMir(mir_tag, dst_ty, dst_mcv, .{ .register = reg });
2230 },2235 },
2231 .got_load, .direct_load => {2236 .got_load, .direct_load => {
2232 return self.fail("TODO implement x86 ADD/SUB/CMP source symbol at index in linker", .{});2237 return self.fail("TODO implement x86 ADD/SUB/CMP source symbol at index in linker", .{});
...@@ -2235,7 +2240,6 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC...@@ -2235,7 +2240,6 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC
2235 if (off > math.maxInt(i32)) {2240 if (off > math.maxInt(i32)) {
2236 return self.fail("stack offset too large", .{});2241 return self.fail("stack offset too large", .{});
2237 }2242 }
2238 const abi_size = dst_ty.abiSize(self.target.*);
2239 const adj_off = off + @intCast(i32, abi_size);2243 const adj_off = off + @intCast(i32, abi_size);
2240 _ = try self.addInst(.{2244 _ = try self.addInst(.{
2241 .tag = mir_tag,2245 .tag = mir_tag,
...@@ -2259,7 +2263,6 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC...@@ -2259,7 +2263,6 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC
2259 if (off > math.maxInt(i32)) {2263 if (off > math.maxInt(i32)) {
2260 return self.fail("stack offset too large", .{});2264 return self.fail("stack offset too large", .{});
2261 }2265 }
2262 const abi_size = dst_ty.abiSize(self.target.*);
2263 if (abi_size > 8) {2266 if (abi_size > 8) {
2264 return self.fail("TODO implement ADD/SUB/CMP for stack dst with large ABI", .{});2267 return self.fail("TODO implement ADD/SUB/CMP for stack dst with large ABI", .{});
2265 }2268 }
src/codegen.zig+14
...@@ -150,6 +150,8 @@ pub fn generateSymbol(...@@ -150,6 +150,8 @@ pub fn generateSymbol(
150 const tracy = trace(@src());150 const tracy = trace(@src());
151 defer tracy.end();151 defer tracy.end();
152152
153 log.debug("generateSymbol: ty = {}, val = {}", .{ typed_value.ty, typed_value.val });
154
153 if (typed_value.val.isUndefDeep()) {155 if (typed_value.val.isUndefDeep()) {
154 const target = bin_file.options.target;156 const target = bin_file.options.target;
155 const abi_size = try math.cast(usize, typed_value.ty.abiSize(target));157 const abi_size = try math.cast(usize, typed_value.ty.abiSize(target));
...@@ -485,6 +487,18 @@ fn lowerDeclRef(...@@ -485,6 +487,18 @@ fn lowerDeclRef(
485 return Result{ .appended = {} };487 return Result{ .appended = {} };
486 }488 }
487489
490 const is_fn_body = decl.ty.zigTypeTag() == .Fn;
491 if (!is_fn_body and !decl.ty.hasRuntimeBits()) {
492 return Result{
493 .fail = try ErrorMsg.create(
494 bin_file.allocator,
495 src_loc,
496 "TODO handle void types when lowering decl ref",
497 .{},
498 ),
499 };
500 }
501
488 if (decl.analysis != .complete) return error.AnalysisFail;502 if (decl.analysis != .complete) return error.AnalysisFail;
489 decl.markAlive();503 decl.markAlive();
490 const vaddr = vaddr: {504 const vaddr = vaddr: {
src/value.zig+4-1
...@@ -711,7 +711,10 @@ pub const Value = extern union {...@@ -711,7 +711,10 @@ pub const Value = extern union {
711 const decl = val.castTag(.decl_ref_mut).?.data.decl;711 const decl = val.castTag(.decl_ref_mut).?.data.decl;
712 return out_stream.print("(decl_ref_mut '{s}')", .{decl.name});712 return out_stream.print("(decl_ref_mut '{s}')", .{decl.name});
713 },713 },
714 .decl_ref => return out_stream.writeAll("(decl ref)"),714 .decl_ref => {
715 const decl = val.castTag(.decl_ref).?.data;
716 return out_stream.print("(decl ref '{s}')", .{decl.name});
717 },
715 .elem_ptr => {718 .elem_ptr => {
716 const elem_ptr = val.castTag(.elem_ptr).?.data;719 const elem_ptr = val.castTag(.elem_ptr).?.data;
717 try out_stream.print("&[{}] ", .{elem_ptr.index});720 try out_stream.print("&[{}] ", .{elem_ptr.index});
test/behavior/bugs/1025.zig-1
...@@ -9,7 +9,6 @@ fn getA() A {...@@ -9,7 +9,6 @@ fn getA() A {
9}9}
1010
11test "bug 1025" {11test "bug 1025" {
12 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
13 const a = getA();12 const a = getA();
14 try @import("std").testing.expect(a.B == u8);13 try @import("std").testing.expect(a.B == u8);
15}14}
test/behavior/bugs/1277.zig-1
...@@ -13,6 +13,5 @@ fn f() i32 {...@@ -13,6 +13,5 @@ fn f() i32 {
1313
14test "don't emit an LLVM global for a const function when it's in an optional in a struct" {14test "don't emit an LLVM global for a const function when it's in an optional in a struct" {
15 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;15 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
16 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
17 try std.testing.expect(s.f.?() == 1234);16 try std.testing.expect(s.f.?() == 1234);
18}17}
test/behavior/bugs/1310.zig-1
...@@ -24,6 +24,5 @@ fn agent_callback(_vm: [*]VM, options: [*]u8) callconv(.C) i32 {...@@ -24,6 +24,5 @@ fn agent_callback(_vm: [*]VM, options: [*]u8) callconv(.C) i32 {
2424
25test "fixed" {25test "fixed" {
26 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;26 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
27 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
28 try expect(agent_callback(undefined, undefined) == 11);27 try expect(agent_callback(undefined, undefined) == 11);
29}28}
test/behavior/bugs/1500.zig-1
...@@ -7,7 +7,6 @@ const B = *const fn (A) void;...@@ -7,7 +7,6 @@ const B = *const fn (A) void;
77
8test "allow these dependencies" {8test "allow these dependencies" {
9 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;9 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
11 var a: A = undefined;10 var a: A = undefined;
12 var b: B = undefined;11 var b: B = undefined;
13 if (false) {12 if (false) {