diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 9c54defbfe9858f30acb100ea36c62d22c00ef96..8bb33f83e0d0911b2f427ede147964df5c73cf9a 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -847,7 +847,7 @@ pub const Object = struct { return diags.fail("emitting without libllvm not implemented", .{}); } - initializeLLVMTarget(comp.root_mod.resolved_target.result.cpu.arch); + initializeLLVMTarget(io, comp.root_mod.resolved_target.result.cpu.arch); const context: *bindings.Context = .create(); errdefer context.dispose(); @@ -4811,7 +4811,14 @@ const struct_layout_version = 2; // https://github.com/llvm/llvm-project/issues/56585/ is fixed pub const optional_layout_version = 3; -pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void { +var target_registry_mutex: std.Io.Mutex = .init; + +pub fn initializeLLVMTarget(io: Io, arch: std.Target.Cpu.Arch) void { + // Repeated initialization is safe, as targets which have already been registered will be skipped. + // It is however the client's responsibility to synchronize registry access. + target_registry_mutex.lockUncancelable(io); + defer target_registry_mutex.unlock(io); + switch (arch) { .aarch64, .aarch64_be => { bindings.LLVMInitializeAArch64Target(); diff --git a/src/link/Lld.zig b/src/link/Lld.zig index 1ac882f2d95cfed859cafc44d6096eaa05c008a8..6a4d8db174fb7a485c0d85e15b688d20d80a5b71 100644 --- a/src/link/Lld.zig +++ b/src/link/Lld.zig @@ -341,7 +341,7 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) link.Error!void { const llvm_bindings = @import("../codegen/llvm/bindings.zig"); const llvm = @import("../codegen/llvm.zig"); const target = &comp.root_mod.resolved_target.result; - llvm.initializeLLVMTarget(target.cpu.arch); + llvm.initializeLLVMTarget(comp.io, target.cpu.arch); var err_file_index: usize = undefined; var err_msg: [*:0]u8 = undefined; if (llvm_bindings.WriteArchive(