diff --git a/src/codegen/wasm/CodeGen.zig b/src/codegen/wasm/CodeGen.zig index a3a6ab0c740c100bf9b1ed754587a9b719b779a1..14f2716b3300c297b4dee8fa6803ab9658f5d940 100644 --- a/src/codegen/wasm/CodeGen.zig +++ b/src/codegen/wasm/CodeGen.zig @@ -345,7 +345,10 @@ fn finishAir(cg: *CodeGen, inst: Air.Inst.Index, result: WValue, operands: []con if (!dies) continue; processDeath(cg, operand); } + try cg.finishAirResult(inst, result); +} +fn finishAirResult(cg: *CodeGen, inst: Air.Inst.Index, result: WValue) InnerError!void { // results of `none` can never be referenced. if (result != .none) { const trackable_result = if (result != .stack) @@ -374,37 +377,10 @@ inline fn currentBranch(cg: *CodeGen) *Branch { return &cg.branches.items[cg.branches.items.len - 1]; } -const BigTomb = struct { - gen: *CodeGen, - inst: Air.Inst.Index, - lbt: Air.Liveness.BigTomb, - - fn feed(bt: *BigTomb, op_ref: Air.Inst.Ref) void { - const dies = bt.lbt.feed(); - if (!dies) return; - // This will be a nop for interned constants. - processDeath(bt.gen, op_ref); +fn feed(cg: *CodeGen, bt: *Air.Liveness.BigTomb, operand: Air.Inst.Ref) void { + if (bt.feed()) { + cg.processDeath(operand); } - - fn finishAir(bt: *BigTomb, result: WValue) void { - assert(result != .stack); - if (result != .none) { - bt.gen.currentBranch().values.putAssumeCapacityNoClobber(bt.inst.toRef(), result); - } - - if (std.debug.runtime_safety) { - bt.gen.air_bookkeeping += 1; - } - } -}; - -fn iterateBigTomb(cg: *CodeGen, inst: Air.Inst.Index, operand_count: usize) !BigTomb { - try cg.currentBranch().values.ensureUnusedCapacity(cg.gpa, operand_count + 1); - return BigTomb{ - .gen = cg, - .inst = inst, - .lbt = cg.liveness.iterateBigTomb(inst), - }; } fn processDeath(cg: *CodeGen, ref: Air.Inst.Ref) void { @@ -766,11 +742,15 @@ pub fn generate( fn generateInner(cg: *CodeGen, any_returns: bool) InnerError!Mir { const zcu = cg.pt.zcu; + // branch used for const values + try cg.branches.append(cg.gpa, .{}); + // func scope branch try cg.branches.append(cg.gpa, .{}); - // clean up outer branch defer { - var outer_branch = cg.branches.pop().?; - outer_branch.deinit(cg.gpa); + var func_branch = cg.branches.pop().?; + func_branch.deinit(cg.gpa); + var const_branch = cg.branches.pop().?; + const_branch.deinit(cg.gpa); assert(cg.branches.items.len == 0); // missing branch merge } // Generate MIR for function body @@ -1920,7 +1900,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { continue; } const old_bookkeeping_value = cg.air_bookkeeping; - try cg.currentBranch().values.ensureUnusedCapacity(cg.gpa, Air.Liveness.bpi); + try cg.currentBranch().values.ensureUnusedCapacity(cg.gpa, 1); try cg.genInst(inst); if (std.debug.runtime_safety and cg.air_bookkeeping < old_bookkeeping_value + 1) { @@ -2102,10 +2082,10 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie } }; - var bt = try cg.iterateBigTomb(inst, 1 + args.len); - bt.feed(call.callee); - for (args) |arg| bt.feed(arg); - return bt.finishAir(result_value); + var bt = cg.liveness.iterateBigTomb(inst); + cg.feed(&bt, call.callee); + for (args) |arg| cg.feed(&bt, arg); + return cg.finishAirResult(inst, result_value); } fn airAlloc(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { @@ -4608,11 +4588,15 @@ fn lowerBlock(cg: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []const .value = block_result, }); - try cg.genBody(body); - try cg.endBlock(); - - const liveness = cg.liveness.getBlock(inst); - try cg.currentBranch().values.ensureUnusedCapacity(cg.gpa, liveness.deaths.len); + { + try cg.branches.append(cg.gpa, .{}); + defer { + var branch = cg.branches.pop().?; + branch.deinit(cg.gpa); + } + try cg.genBody(body); + try cg.endBlock(); + } return cg.finishAir(inst, block_result, &.{}); } @@ -4653,7 +4637,6 @@ fn airCondBr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { const condition = try cg.resolveInst(cond_br.condition); const then_body = cond_br.then_body; const else_body = cond_br.else_body; - const liveness_condbr = cg.liveness.getCondBr(inst); // result type is always noreturn, so use `block_empty` as type. try cg.startBlock(.block, .empty); @@ -4668,7 +4651,6 @@ fn airCondBr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { try cg.branches.ensureUnusedCapacity(cg.gpa, 2); { cg.branches.appendAssumeCapacity(.{}); - try cg.currentBranch().values.ensureUnusedCapacity(cg.gpa, @as(u32, @intCast(liveness_condbr.else_deaths.len))); defer { var else_stack = cg.branches.pop().?; else_stack.deinit(cg.gpa); @@ -4680,7 +4662,6 @@ fn airCondBr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { // Outer block that matches the condition { cg.branches.appendAssumeCapacity(.{}); - try cg.currentBranch().values.ensureUnusedCapacity(cg.gpa, @as(u32, @intCast(liveness_condbr.then_deaths.len))); defer { var then_stack = cg.branches.pop().?; then_stack.deinit(cg.gpa); @@ -5172,9 +5153,6 @@ fn airSwitchBr(cg: *CodeGen, inst: Air.Inst.Index, is_dispatch_loop: bool) Inner break :target target; } else try cg.resolveInst(switch_br.operand); - const liveness = try cg.liveness.getSwitchBr(cg.gpa, inst, switch_br.cases_len + 1); - defer cg.gpa.free(liveness.deaths); - const has_else_body = switch_br.else_body_len != 0; const branch_count = switch_br.cases_len + 1; // if else branch is missing, we trap when failing all conditions try cg.branches.ensureUnusedCapacity(cg.gpa, switch_br.cases_len + @intFromBool(has_else_body)); @@ -5186,8 +5164,6 @@ fn airSwitchBr(cg: *CodeGen, inst: Air.Inst.Index, is_dispatch_loop: bool) Inner const else_body = it.elseBody(); cg.branches.appendAssumeCapacity(.{}); - const else_deaths = liveness.deaths.len - 1; - try cg.currentBranch().values.ensureUnusedCapacity(cg.gpa, liveness.deaths[else_deaths].len); defer { var else_branch = cg.branches.pop().?; else_branch.deinit(cg.gpa); @@ -5321,7 +5297,6 @@ fn airSwitchBr(cg: *CodeGen, inst: Air.Inst.Index, is_dispatch_loop: bool) Inner try cg.endBlock(); cg.branches.appendAssumeCapacity(.{}); - try cg.currentBranch().values.ensureUnusedCapacity(cg.gpa, liveness.deaths[case.idx].len); defer { var case_branch = cg.branches.pop().?; case_branch.deinit(cg.gpa); @@ -5336,8 +5311,6 @@ fn airSwitchBr(cg: *CodeGen, inst: Air.Inst.Index, is_dispatch_loop: bool) Inner const else_body = cases_it.elseBody(); cg.branches.appendAssumeCapacity(.{}); - const else_deaths = liveness.deaths.len - 1; - try cg.currentBranch().values.ensureUnusedCapacity(cg.gpa, liveness.deaths[else_deaths].len); defer { var else_branch = cg.branches.pop().?; else_branch.deinit(cg.gpa); @@ -6329,14 +6302,9 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { } }; - if (elements.len <= Air.Liveness.bpi - 1) { - var buf = [1]Air.Inst.Ref{.none} ** (Air.Liveness.bpi - 1); - @memcpy(buf[0..elements.len], elements); - return cg.finishAir(inst, result, &buf); - } - var bt = try cg.iterateBigTomb(inst, elements.len); - for (elements) |arg| bt.feed(arg); - return bt.finishAir(result); + var bt = cg.liveness.iterateBigTomb(inst); + for (elements) |arg| cg.feed(&bt, arg); + return cg.finishAirResult(inst, result); } fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { @@ -6671,6 +6639,7 @@ fn lowerTry( err_union_ty: Type, operand_is_ptr: bool, ) InnerError!WValue { + _ = inst; const zcu = cg.pt.zcu; const pl_ty = err_union_ty.errorUnionPayload(zcu); @@ -6692,9 +6661,7 @@ fn lowerTry( try cg.addTag(.i32_eqz); try cg.addLabel(.br_if, 0); // jump out of block when error is '0' - const liveness = cg.liveness.getCondBr(inst); try cg.branches.append(cg.gpa, .{}); - try cg.currentBranch().values.ensureUnusedCapacity(cg.gpa, liveness.else_deaths.len + liveness.then_deaths.len); defer { var branch = cg.branches.pop().?; branch.deinit(cg.gpa); diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 041a8c6d27bb03507f334fcbae865651e2161866..b4760bce4d676f6ec591180af3c4ffa4075352d2 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -931,8 +931,7 @@ pub const ZcuFunc = union { const ip = &zcu.intern_pool; switch (ip.indexToKey(i.key(wasm).*)) { .func => |func| { - const fn_ty = zcu.navValue(func.owner_nav).typeOf(zcu); - const fn_info = zcu.typeToFunc(fn_ty).?; + const fn_info = zcu.typeToFunc(.fromInterned(func.ty)).?; return wasm.getExistingFunctionType(fn_info.cc, fn_info.param_types.get(ip), .fromInterned(fn_info.return_type), target).?; }, .enum_type => { diff --git a/src/target.zig b/src/target.zig index 43858ea5f200b4f0b4a2271b158e22d2313d62ca..3d04c06f5e5d1da0fe5e61ed693cf32651055e85 100644 --- a/src/target.zig +++ b/src/target.zig @@ -910,6 +910,7 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt .stage2_llvm, .stage2_x86_64, .stage2_riscv64, + .stage2_wasm, => true, else => false, }, diff --git a/test/incremental/add_decl b/test/incremental/add_decl index e91eda1930a5c90485112ef01c08f9ea8fab18e9..4716c7787bba5f9a222c0fea7ae991b41874aedd 100644 --- a/test/incremental/add_decl +++ b/test/incremental/add_decl @@ -3,7 +3,7 @@ #target=x86_64-linux-cbe #target=x86_64-windows-cbe #target=x86_64-linux-llvm -//#target=wasm32-wasi-selfhosted +#target=wasm32-wasi-selfhosted #update=initial version #file=main.zig const std = @import("std"); diff --git a/test/incremental/add_decl_namespaced b/test/incremental/add_decl_namespaced index 389aef6fb8d289a480260811b7d51a0c6a32858d..96872d737250163e14d2e066c6bb88c0f5c5631a 100644 --- a/test/incremental/add_decl_namespaced +++ b/test/incremental/add_decl_namespaced @@ -3,7 +3,7 @@ #target=x86_64-linux-cbe #target=x86_64-windows-cbe #target=x86_64-linux-llvm -//#target=wasm32-wasi-selfhosted +#target=wasm32-wasi-selfhosted #update=initial version #file=main.zig const std = @import("std"); diff --git a/test/incremental/add_remove_struct_fields b/test/incremental/add_remove_struct_fields index 34ad260ae1aa479686eec3fd68d4061e2afa8cc5..bf19be99de72fb45ced938e73a249c4dbf63c6d8 100644 --- a/test/incremental/add_remove_struct_fields +++ b/test/incremental/add_remove_struct_fields @@ -3,7 +3,7 @@ #target=x86_64-linux-cbe #target=x86_64-windows-cbe #target=x86_64-linux-llvm -//#target=wasm32-wasi-selfhosted +#target=wasm32-wasi-selfhosted #update=initial version #file=main.zig const S = struct { x: u8 }; diff --git a/test/incremental/add_remove_toplevel_fields b/test/incremental/add_remove_toplevel_fields index 83775ae3e3cafa535ebfd79ec9d0b21b250fed66..c404827958b703b9bd6500b9c0d1cab9c57e24dd 100644 --- a/test/incremental/add_remove_toplevel_fields +++ b/test/incremental/add_remove_toplevel_fields @@ -3,7 +3,7 @@ #target=x86_64-linux-cbe #target=x86_64-windows-cbe #target=x86_64-linux-llvm -//#target=wasm32-wasi-selfhosted +#target=wasm32-wasi-selfhosted #update=initial version #file=main.zig const S = @This(); diff --git a/test/incremental/change_fn_type b/test/incremental/change_fn_type index 69e25a5a4aa7e896e44583867873bc34f5da07b7..fc2e5bb8a2af08f6777c73edfceb1cbcec3b5048 100644 --- a/test/incremental/change_fn_type +++ b/test/incremental/change_fn_type @@ -3,6 +3,7 @@ #target=x86_64-linux-cbe #target=x86_64-windows-cbe #target=x86_64-linux-llvm +#target=wasm32-wasi-selfhosted #update=initial version #file=main.zig pub fn main() !void { diff --git a/test/incremental/change_panic_handler b/test/incremental/change_panic_handler index 13685406dff01786fe8ff1fe17ad0133a162f448..6ce1409eb7d535069df60c9e183712f3c10fa0c1 100644 --- a/test/incremental/change_panic_handler +++ b/test/incremental/change_panic_handler @@ -3,6 +3,7 @@ #target=x86_64-linux-cbe #target=x86_64-windows-cbe #target=x86_64-linux-llvm +#target=wasm32-wasi-selfhosted #update=initial version #file=main.zig pub fn main() !u8 { diff --git a/test/incremental/change_panic_handler_explicit b/test/incremental/change_panic_handler_explicit index ed4cfcfca44cad7f2c7085b6855a3312bdf7542c..e165ec4eda159f31da234b9081cae31bfcc0dc78 100644 --- a/test/incremental/change_panic_handler_explicit +++ b/test/incremental/change_panic_handler_explicit @@ -3,6 +3,7 @@ #target=x86_64-linux-cbe #target=x86_64-windows-cbe #target=x86_64-linux-llvm +#target=wasm32-wasi-selfhosted #update=initial version #file=main.zig pub fn main() !u8 { diff --git a/test/incremental/change_zon_file b/test/incremental/change_zon_file index 822996ac74966971b237718461d555ce461d194f..77eef7c7f1e7d7ac3b0eccf916e4862e6808648b 100644 --- a/test/incremental/change_zon_file +++ b/test/incremental/change_zon_file @@ -3,7 +3,7 @@ #target=x86_64-linux-cbe #target=x86_64-windows-cbe #target=x86_64-linux-llvm -//#target=wasm32-wasi-selfhosted +#target=wasm32-wasi-selfhosted #update=initial version #file=main.zig const std = @import("std"); diff --git a/test/incremental/change_zon_file_no_result_type b/test/incremental/change_zon_file_no_result_type index f9a3c3006577c64a6b8725e90fef02e67364130f..8e4500d0ca0a3c5732ae185aef51be633f634e71 100644 --- a/test/incremental/change_zon_file_no_result_type +++ b/test/incremental/change_zon_file_no_result_type @@ -3,7 +3,7 @@ #target=x86_64-linux-cbe #target=x86_64-windows-cbe #target=x86_64-linux-llvm -//#target=wasm32-wasi-selfhosted +#target=wasm32-wasi-selfhosted #update=initial version #file=main.zig const std = @import("std"); diff --git a/test/incremental/function_becomes_inline b/test/incremental/function_becomes_inline index b63aa3e5697a600d2463dfb3af9282ea62b223a4..4c211d865a4c273aa50af57c0eae57033b9d4a07 100644 --- a/test/incremental/function_becomes_inline +++ b/test/incremental/function_becomes_inline @@ -3,6 +3,7 @@ #target=x86_64-linux-cbe #target=x86_64-windows-cbe #target=x86_64-linux-llvm +#target=wasm32-wasi-selfhosted #update=non-inline version #file=main.zig pub fn main() !void { diff --git a/test/incremental/no_change_preserves_tag_names b/test/incremental/no_change_preserves_tag_names index 7d7e0b20ea4d0756258815d477368ec68d715664..659cefade6cb2935eb72c296a00f4f9756036d98 100644 --- a/test/incremental/no_change_preserves_tag_names +++ b/test/incremental/no_change_preserves_tag_names @@ -3,7 +3,7 @@ #target=x86_64-linux-cbe #target=x86_64-windows-cbe #target=x86_64-linux-llvm -//#target=wasm32-wasi-selfhosted +#target=wasm32-wasi-selfhosted #update=initial version #file=main.zig const std = @import("std");