| author | |
| committer | |
| log | 9a48a5ab0784ae9744c72cfcc6d7ad9b2cea6a9c |
| tree | e4d9e85b058a1cf23776c8f30bd3fc70e2fdfff5 |
| parent | 43720be04af8ddb8334b210ff936a834fb8871a7 |
8 files changed, 51 insertions(+), 28 deletions(-)
src/Compilation.zig+4-6| ... | ... | @@ -1871,7 +1871,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1871 | 1871 | try comp.work_queue.writeItem(.libtsan); |
| 1872 | 1872 | } |
| 1873 | 1873 | |
| 1874 | if (comp.getTarget().isMinGW() and !comp.bin_file.options.single_threaded) { | |
| 1874 | if (comp.getTarget().isMinGW() and comp.config.any_non_single_threaded) { | |
| 1875 | 1875 | // LLD might drop some symbols as unused during LTO and GCing, therefore, |
| 1876 | 1876 | // we force mark them for resolution here. |
| 1877 | 1877 | |
| ... | ... | @@ -2418,10 +2418,8 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2418 | 2418 | try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.main_mod, .{ .files = man }); |
| 2419 | 2419 | |
| 2420 | 2420 | // Synchronize with other matching comments: ZigOnlyHashStuff |
| 2421 | man.hash.add(comp.bin_file.options.valgrind); | |
| 2422 | man.hash.add(comp.bin_file.options.single_threaded); | |
| 2423 | man.hash.add(comp.bin_file.options.use_llvm); | |
| 2424 | man.hash.add(comp.bin_file.options.use_lib_llvm); | |
| 2421 | man.hash.add(comp.config.use_llvm); | |
| 2422 | man.hash.add(comp.config.use_lib_llvm); | |
| 2425 | 2423 | man.hash.add(comp.bin_file.options.dll_export_fns); |
| 2426 | 2424 | man.hash.add(comp.bin_file.options.is_test); |
| 2427 | 2425 | man.hash.add(comp.test_evented_io); |
| ... | ... | @@ -4922,7 +4920,7 @@ pub fn addCCArgs( |
| 4922 | 4920 | try argv.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS"); |
| 4923 | 4921 | try argv.append("-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS"); |
| 4924 | 4922 | |
| 4925 | if (comp.bin_file.options.single_threaded) { | |
| 4923 | if (!comp.config.any_non_single_threaded) { | |
| 4926 | 4924 | try argv.append("-D_LIBCPP_HAS_NO_THREADS"); |
| 4927 | 4925 | } |
| 4928 | 4926 |
src/Compilation/Config.zig+4-2| ... | ... | @@ -7,6 +7,8 @@ link_libc: bool, |
| 7 | 7 | link_libcpp: bool, |
| 8 | 8 | link_libunwind: bool, |
| 9 | 9 | any_unwind_tables: bool, |
| 10 | any_c_source_files: bool, | |
| 11 | any_non_single_threaded: bool, | |
| 10 | 12 | pie: bool, |
| 11 | 13 | /// If this is true then linker code is responsible for making an LLVM IR |
| 12 | 14 | /// Module, outputting it to an object file, and then linking that together |
| ... | ... | @@ -31,7 +33,6 @@ shared_memory: bool, |
| 31 | 33 | is_test: bool, |
| 32 | 34 | test_evented_io: bool, |
| 33 | 35 | entry: ?[]const u8, |
| 34 | any_c_source_files: bool, | |
| 35 | 36 | |
| 36 | 37 | pub const CFrontend = enum { clang, aro }; |
| 37 | 38 | |
| ... | ... | @@ -374,6 +375,8 @@ pub fn resolve(options: Options) !Config { |
| 374 | 375 | .link_libcpp = link_libcpp, |
| 375 | 376 | .link_libunwind = link_libunwind, |
| 376 | 377 | .any_unwind_tables = any_unwind_tables, |
| 378 | .any_c_source_files = options.any_c_source_files, | |
| 379 | .any_non_single_threaded = options.any_non_single_threaded, | |
| 377 | 380 | .pie = pie, |
| 378 | 381 | .lto = lto, |
| 379 | 382 | .import_memory = import_memory, |
| ... | ... | @@ -385,7 +388,6 @@ pub fn resolve(options: Options) !Config { |
| 385 | 388 | .use_lld = use_lld, |
| 386 | 389 | .entry = entry, |
| 387 | 390 | .wasi_exec_model = wasi_exec_model, |
| 388 | .any_c_source_files = options.any_c_source_files, | |
| 389 | 391 | }; |
| 390 | 392 | } |
| 391 | 393 |
src/arch/wasm/CodeGen.zig+4-1| ... | ... | @@ -7724,10 +7724,13 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7724 | 7724 | } |
| 7725 | 7725 | |
| 7726 | 7726 | fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7727 | const zcu = func.bin_file.base.comp.module.?; | |
| 7727 | 7728 | // Only when the atomic feature is enabled, and we're not building |
| 7728 | 7729 | // for a single-threaded build, can we emit the `fence` instruction. |
| 7729 | 7730 | // In all other cases, we emit no instructions for a fence. |
| 7730 | if (func.useAtomicFeature() and !func.bin_file.base.options.single_threaded) { | |
| 7731 | const func_namespace = zcu.namespacePtr(zcu.declPtr(func.decl).namespace); | |
| 7732 | const single_threaded = func_namespace.file_scope.mod.single_threaded; | |
| 7733 | if (func.useAtomicFeature() and !single_threaded) { | |
| 7731 | 7734 | try func.addAtomicTag(.atomic_fence); |
| 7732 | 7735 | } |
| 7733 | 7736 |
src/codegen.zig+3-1| ... | ... | @@ -942,7 +942,9 @@ fn genDeclRef( |
| 942 | 942 | |
| 943 | 943 | try mod.markDeclAlive(decl); |
| 944 | 944 | |
| 945 | const is_threadlocal = tv.val.isPtrToThreadLocal(mod) and !bin_file.options.single_threaded; | |
| 945 | const decl_namespace = mod.namespacePtr(decl.namespace_index); | |
| 946 | const single_threaded = decl_namespace.file_scope.mod.single_threaded; | |
| 947 | const is_threadlocal = tv.val.isPtrToThreadLocal(mod) and !single_threaded; | |
| 946 | 948 | const is_extern = decl.isExtern(mod); |
| 947 | 949 | |
| 948 | 950 | if (bin_file.cast(link.File.Elf)) |elf_file| { |
src/codegen/llvm.zig+11-4| ... | ... | @@ -1591,8 +1591,10 @@ pub const Object = struct { |
| 1591 | 1591 | var di_file: ?if (build_options.have_llvm) *llvm.DIFile else noreturn = null; |
| 1592 | 1592 | var di_scope: ?if (build_options.have_llvm) *llvm.DIScope else noreturn = null; |
| 1593 | 1593 | |
| 1594 | const namespace = mod.namespacePtr(decl.src_namespace); | |
| 1595 | ||
| 1594 | 1596 | if (o.di_builder) |dib| { |
| 1595 | di_file = try o.getDIFile(gpa, mod.namespacePtr(decl.src_namespace).file_scope); | |
| 1597 | di_file = try o.getDIFile(gpa, namespace.file_scope); | |
| 1596 | 1598 | |
| 1597 | 1599 | const line_number = decl.src_line + 1; |
| 1598 | 1600 | const is_internal_linkage = decl.val.getExternFunc(mod) == null and |
| ... | ... | @@ -1623,6 +1625,8 @@ pub const Object = struct { |
| 1623 | 1625 | di_scope = subprogram.toScope(); |
| 1624 | 1626 | } |
| 1625 | 1627 | |
| 1628 | const single_threaded = namespace.file_scope.mod.single_threaded; | |
| 1629 | ||
| 1626 | 1630 | var fg: FuncGen = .{ |
| 1627 | 1631 | .gpa = gpa, |
| 1628 | 1632 | .air = air, |
| ... | ... | @@ -1634,7 +1638,7 @@ pub const Object = struct { |
| 1634 | 1638 | .arg_index = 0, |
| 1635 | 1639 | .func_inst_table = .{}, |
| 1636 | 1640 | .blocks = .{}, |
| 1637 | .sync_scope = if (mod.comp.bin_file.options.single_threaded) .singlethread else .system, | |
| 1641 | .sync_scope = if (single_threaded) .singlethread else .system, | |
| 1638 | 1642 | .di_scope = di_scope, |
| 1639 | 1643 | .di_file = di_file, |
| 1640 | 1644 | .base_line = dg.decl.src_line, |
| ... | ... | @@ -1788,8 +1792,10 @@ pub const Object = struct { |
| 1788 | 1792 | if (mod.wantDllExports()) global_index.setDllStorageClass(.default, &self.builder); |
| 1789 | 1793 | global_index.setUnnamedAddr(.unnamed_addr, &self.builder); |
| 1790 | 1794 | if (decl.val.getVariable(mod)) |decl_var| { |
| 1795 | const decl_namespace = mod.namespacePtr(decl.namespace_index); | |
| 1796 | const single_threaded = decl_namespace.file_scope.mod.single_threaded; | |
| 1791 | 1797 | global_index.ptrConst(&self.builder).kind.variable.setThreadLocal( |
| 1792 | if (decl_var.is_threadlocal and !mod.comp.bin_file.options.single_threaded) | |
| 1798 | if (decl_var.is_threadlocal and !single_threaded) | |
| 1793 | 1799 | .generaldynamic |
| 1794 | 1800 | else |
| 1795 | 1801 | .default, |
| ... | ... | @@ -3176,7 +3182,8 @@ pub const Object = struct { |
| 3176 | 3182 | variable_index.setLinkage(.external, &o.builder); |
| 3177 | 3183 | variable_index.setUnnamedAddr(.default, &o.builder); |
| 3178 | 3184 | if (decl.val.getVariable(mod)) |decl_var| { |
| 3179 | const single_threaded = mod.comp.bin_file.options.single_threaded; | |
| 3185 | const decl_namespace = mod.namespacePtr(decl.namespace_index); | |
| 3186 | const single_threaded = decl_namespace.file_scope.mod.single_threaded; | |
| 3180 | 3187 | variable_index.setThreadLocal( |
| 3181 | 3188 | if (decl_var.is_threadlocal and !single_threaded) .generaldynamic else .default, |
| 3182 | 3189 | &o.builder, |
src/libcxx.zig+2-2| ... | ... | @@ -154,7 +154,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 154 | 154 | continue; |
| 155 | 155 | if (std.mem.startsWith(u8, cxx_src, "src/support/ibm/") and target.os.tag != .zos) |
| 156 | 156 | continue; |
| 157 | if (comp.bin_file.options.single_threaded) { | |
| 157 | if (!comp.config.any_non_single_threaded) { | |
| 158 | 158 | if (std.mem.startsWith(u8, cxx_src, "src/support/win32/thread_win32.cpp")) { |
| 159 | 159 | continue; |
| 160 | 160 | } |
| ... | ... | @@ -332,7 +332,7 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 332 | 332 | } |
| 333 | 333 | |
| 334 | 334 | // WASM targets are single threaded. |
| 335 | if (comp.bin_file.options.single_threaded) { | |
| 335 | if (!comp.config.any_non_single_threaded) { | |
| 336 | 336 | if (std.mem.startsWith(u8, cxxabi_src, "src/cxa_thread_atexit.cpp")) { |
| 337 | 337 | continue; |
| 338 | 338 | } |
src/libunwind.zig+1-1| ... | ... | @@ -67,7 +67,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 67 | 67 | if (comp.bin_file.options.optimize_mode == .Debug) { |
| 68 | 68 | try cflags.append("-D_DEBUG"); |
| 69 | 69 | } |
| 70 | if (comp.bin_file.options.single_threaded) { | |
| 70 | if (!comp.config.any_non_single_threaded) { | |
| 71 | 71 | try cflags.append("-D_LIBUNWIND_HAS_NO_THREADS"); |
| 72 | 72 | } |
| 73 | 73 | if (target.cpu.arch.isARM() and target.abi.floatAbi() == .hard) { |
src/link/MachO.zig+22-11| ... | ... | @@ -267,7 +267,10 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*MachO { |
| 267 | 267 | }); |
| 268 | 268 | try self.strtab.buffer.append(gpa, 0); |
| 269 | 269 | |
| 270 | try self.populateMissingMetadata(); | |
| 270 | try self.populateMissingMetadata(.{ | |
| 271 | .symbol_count_hint = options.symbol_count_hint, | |
| 272 | .program_code_size_hint = options.program_code_size_hint, | |
| 273 | }); | |
| 271 | 274 | |
| 272 | 275 | if (self.d_sym) |*d_sym| { |
| 273 | 276 | try d_sym.populateMissingMetadata(self); |
| ... | ... | @@ -1704,7 +1707,8 @@ pub fn createDsoHandleSymbol(self: *MachO) !void { |
| 1704 | 1707 | } |
| 1705 | 1708 | |
| 1706 | 1709 | pub fn resolveSymbols(self: *MachO) !void { |
| 1707 | const output_mode = self.base.comp.config.output_mode; | |
| 1710 | const comp = self.base.comp; | |
| 1711 | const output_mode = comp.config.output_mode; | |
| 1708 | 1712 | // We add the specified entrypoint as the first unresolved symbols so that |
| 1709 | 1713 | // we search for it in libraries should there be no object files specified |
| 1710 | 1714 | // on the linker line. |
| ... | ... | @@ -1729,7 +1733,7 @@ pub fn resolveSymbols(self: *MachO) !void { |
| 1729 | 1733 | if (self.unresolved.count() > 0 and self.dyld_stub_binder_index == null) { |
| 1730 | 1734 | self.dyld_stub_binder_index = try self.addUndefined("dyld_stub_binder", .{ .add_got = true }); |
| 1731 | 1735 | } |
| 1732 | if (!self.base.options.single_threaded and self.mode == .incremental) { | |
| 1736 | if (comp.config.any_non_single_threaded and self.mode == .incremental) { | |
| 1733 | 1737 | _ = try self.addUndefined("__tlv_bootstrap", .{}); |
| 1734 | 1738 | } |
| 1735 | 1739 | |
| ... | ... | @@ -2436,7 +2440,8 @@ pub fn updateDecl(self: *MachO, mod: *Module, decl_index: InternPool.DeclIndex) |
| 2436 | 2440 | const tracy = trace(@src()); |
| 2437 | 2441 | defer tracy.end(); |
| 2438 | 2442 | |
| 2439 | const gpa = self.base.comp.gpa; | |
| 2443 | const comp = self.base.comp; | |
| 2444 | const gpa = comp.gpa; | |
| 2440 | 2445 | const decl = mod.declPtr(decl_index); |
| 2441 | 2446 | |
| 2442 | 2447 | if (decl.val.getExternFunc(mod)) |_| { |
| ... | ... | @@ -2453,7 +2458,7 @@ pub fn updateDecl(self: *MachO, mod: *Module, decl_index: InternPool.DeclIndex) |
| 2453 | 2458 | } |
| 2454 | 2459 | |
| 2455 | 2460 | const is_threadlocal = if (decl.val.getVariable(mod)) |variable| |
| 2456 | variable.is_threadlocal and !self.base.options.single_threaded | |
| 2461 | variable.is_threadlocal and comp.config.any_non_single_threaded | |
| 2457 | 2462 | else |
| 2458 | 2463 | false; |
| 2459 | 2464 | if (is_threadlocal) return self.updateThreadlocalVariable(mod, decl_index); |
| ... | ... | @@ -3129,11 +3134,17 @@ pub fn getAnonDeclVAddr(self: *MachO, decl_val: InternPool.Index, reloc_info: li |
| 3129 | 3134 | return 0; |
| 3130 | 3135 | } |
| 3131 | 3136 | |
| 3132 | fn populateMissingMetadata(self: *MachO) !void { | |
| 3137 | const PopulateMissingMetadataOptions = struct { | |
| 3138 | symbol_count_hint: u64, | |
| 3139 | program_code_size_hint: u64, | |
| 3140 | }; | |
| 3141 | ||
| 3142 | fn populateMissingMetadata(self: *MachO, options: PopulateMissingMetadataOptions) !void { | |
| 3133 | 3143 | assert(self.mode == .incremental); |
| 3134 | 3144 | |
| 3135 | const gpa = self.base.comp.gpa; | |
| 3136 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 3145 | const comp = self.base.comp; | |
| 3146 | const gpa = comp.gpa; | |
| 3147 | const target = comp.root_mod.resolved_target.result; | |
| 3137 | 3148 | const cpu_arch = target.cpu.arch; |
| 3138 | 3149 | const pagezero_vmsize = self.calcPagezeroSize(); |
| 3139 | 3150 | |
| ... | ... | @@ -3171,7 +3182,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 3171 | 3182 | if (self.text_section_index == null) { |
| 3172 | 3183 | // Sadly, segments need unique string identfiers for some reason. |
| 3173 | 3184 | self.text_section_index = try self.allocateSection("__TEXT1", "__text", .{ |
| 3174 | .size = self.base.options.program_code_size_hint, | |
| 3185 | .size = options.program_code_size_hint, | |
| 3175 | 3186 | .alignment = switch (cpu_arch) { |
| 3176 | 3187 | .x86_64 => 1, |
| 3177 | 3188 | .aarch64 => @sizeOf(u32), |
| ... | ... | @@ -3207,7 +3218,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 3207 | 3218 | |
| 3208 | 3219 | if (self.got_section_index == null) { |
| 3209 | 3220 | self.got_section_index = try self.allocateSection("__DATA_CONST", "__got", .{ |
| 3210 | .size = @sizeOf(u64) * self.base.options.symbol_count_hint, | |
| 3221 | .size = @sizeOf(u64) * options.symbol_count_hint, | |
| 3211 | 3222 | .alignment = @alignOf(u64), |
| 3212 | 3223 | .flags = macho.S_NON_LAZY_SYMBOL_POINTERS, |
| 3213 | 3224 | .prot = macho.PROT.READ | macho.PROT.WRITE, |
| ... | ... | @@ -3245,7 +3256,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 3245 | 3256 | self.segment_table_dirty = true; |
| 3246 | 3257 | } |
| 3247 | 3258 | |
| 3248 | if (!self.base.options.single_threaded) { | |
| 3259 | if (comp.config.any_non_single_threaded) { | |
| 3249 | 3260 | if (self.thread_vars_section_index == null) { |
| 3250 | 3261 | self.thread_vars_section_index = try self.allocateSection("__DATA2", "__thread_vars", .{ |
| 3251 | 3262 | .size = @sizeOf(u64) * 3, |