authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-03-05 15:19:54+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-06 14:17:36-05:00
log6d84f22fa0d30f688a2fbe69acab2979373a7806
tree03d39cb2386d7c9da060e84de495a9e2de9dfc51
parent716abe338907dbcb0ea115dd014c2e13c3a6637b

stage2: Fix wasm linker for llvm backend

This fixes 2 entrypoints within the self-hosted wasm linker that would be called for the llvm backend, whereas we should simply call into the llvm backend to perform such action. i.e. not allocate a decl index when we have an llvm object, and when flushing a module, we should be calling it on llvm's object, rather than have the wasm linker perform the operation. Also, this fixes the wasm intrinsics for wasm.memory.size and wasm.memory.grow. Lastly, this commit ensures that when an extern function is being resolved, we tell LLVM how to import such function.

3 files changed, 18 insertions(+), 3 deletions(-)

src/codegen/llvm.zig+10-2
......@@ -708,6 +708,14 @@ pub const DeclGen = struct {
708708 if (!is_extern) {
709709 llvm_fn.setLinkage(.Internal);
710710 llvm_fn.setUnnamedAddr(.True);
711 } else if (dg.module.getTarget().isWasm()) {
712 dg.addFnAttrString(llvm_fn, "wasm-import-name", std.mem.sliceTo(decl.name, 0));
713 if (decl.getExternFn().?.lib_name) |lib_name| {
714 const module_name = std.mem.sliceTo(lib_name, 0);
715 if (!std.mem.eql(u8, module_name, "c")) {
716 dg.addFnAttrString(llvm_fn, "wasm-import-module", module_name);
717 }
718 }
711719 }
712720
713721 if (sret) {
......@@ -3483,7 +3491,7 @@ pub const FuncGen = struct {
34833491 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
34843492 const index = pl_op.payload;
34853493 const llvm_u32 = self.context.intType(32);
3486 const llvm_fn = self.getIntrinsic("llvm.wasm.memory.size.i32", &.{llvm_u32});
3494 const llvm_fn = self.getIntrinsic("llvm.wasm.memory.size", &.{llvm_u32});
34873495 const args: [1]*const llvm.Value = .{llvm_u32.constInt(index, .False)};
34883496 return self.builder.buildCall(llvm_fn, &args, args.len, .Fast, .Auto, "");
34893497 }
......@@ -3493,7 +3501,7 @@ pub const FuncGen = struct {
34933501 const index = pl_op.payload;
34943502 const operand = try self.resolveInst(pl_op.operand);
34953503 const llvm_u32 = self.context.intType(32);
3496 const llvm_fn = self.getIntrinsic("llvm.wasm.memory.grow.i32", &.{ llvm_u32, llvm_u32 });
3504 const llvm_fn = self.getIntrinsic("llvm.wasm.memory.grow", &.{llvm_u32});
34973505 const args: [2]*const llvm.Value = .{
34983506 llvm_u32.constInt(index, .False),
34993507 operand,
src/link/Wasm.zig+7-1
......@@ -466,6 +466,7 @@ pub fn deinit(self: *Wasm) void {
466466}
467467
468468pub fn allocateDeclIndexes(self: *Wasm, decl: *Module.Decl) !void {
469 if (self.llvm_object) |_| return;
469470 if (decl.link.wasm.sym_index != 0) return;
470471
471472 try self.symbols.ensureUnusedCapacity(self.base.allocator, 1);
......@@ -1365,10 +1366,15 @@ pub fn flush(self: *Wasm, comp: *Compilation) !void {
13651366}
13661367
13671368pub fn flushModule(self: *Wasm, comp: *Compilation) !void {
1368 _ = comp;
13691369 const tracy = trace(@src());
13701370 defer tracy.end();
13711371
1372 if (build_options.have_llvm) {
1373 if (self.llvm_object) |llvm_object| {
1374 return try llvm_object.flushModule(comp);
1375 }
1376 }
1377
13721378 // The amount of sections that will be written
13731379 var section_count: u32 = 0;
13741380 // Index of the code section. Used to tell relocation table where the section lives.
test/behavior/struct.zig+1
......@@ -429,6 +429,7 @@ test "packed struct 24bits" {
429429 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
430430 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
431431 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
432 if (builtin.zig_backend == .stage2_llvm and builtin.stage2_arch == .wasm32) return error.SkipZigTest; // TODO
432433
433434 comptime {
434435 try expect(@sizeOf(Foo24Bits) == 4);