authorgravatar for travislange12@gmail.comTravis Lange <travislange12@gmail.com> 2025-01-03 11:04:40-05:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-01-05 18:08:11+01:00
log82e7f23c49be10ce74cb1a951aa7cb77799c2798
treeda65434206224508642a9b79adfbc21a29a2176c
parentda1ffae7d23b04c4efc5e99ba153d8c45eb980f3

Added support for thin lto


8 files changed, 50 insertions(+), 25 deletions(-)

src/Compilation.zig+5-3
......@@ -5399,8 +5399,10 @@ pub fn addCCArgs(
53995399 },
54005400 }
54015401
5402 if (comp.config.lto) {
5403 try argv.append("-flto");
5402 switch (comp.config.lto) {
5403 .none => try argv.append("-fno-lto"),
5404 .full => try argv.append("-flto=full"),
5405 .thin => try argv.append("-flto=thin"),
54045406 }
54055407
54065408 // This only works for preprocessed files. Guarded by `FileExt.clangSupportsDepFile`.
......@@ -6450,7 +6452,7 @@ pub fn build_crt_file(
64506452 .link_libc = false,
64516453 .lto = switch (output_mode) {
64526454 .Lib => comp.config.lto,
6453 .Obj, .Exe => false,
6455 .Obj, .Exe => .none,
64546456 },
64556457 });
64566458 const root_mod = try Package.Module.create(arena, .{
src/Compilation/Config.zig+13-11
......@@ -48,7 +48,7 @@ use_lib_llvm: bool,
4848/// and updates the final binary.
4949use_lld: bool,
5050c_frontend: CFrontend,
51lto: bool,
51lto: LtoMode,
5252/// WASI-only. Type of WASI execution model ("command" or "reactor").
5353/// Always set to `command` for non-WASI targets.
5454wasi_exec_model: std.builtin.WasiExecModel,
......@@ -65,6 +65,8 @@ san_cov_trace_pc_guard: bool,
6565
6666pub const CFrontend = enum { clang, aro };
6767
68pub const LtoMode = enum { none, full, thin };
69
6870pub const DebugFormat = union(enum) {
6971 strip,
7072 dwarf: std.dwarf.Format,
......@@ -101,7 +103,7 @@ pub const Options = struct {
101103 use_lib_llvm: ?bool = null,
102104 use_lld: ?bool = null,
103105 use_clang: ?bool = null,
104 lto: ?bool = null,
106 lto: ?LtoMode = null,
105107 /// WASI-only. Type of WASI execution model ("command" or "reactor").
106108 wasi_exec_model: ?std.builtin.WasiExecModel = null,
107109 import_memory: ?bool = null,
......@@ -258,7 +260,7 @@ pub fn resolve(options: Options) ResolveError!Config {
258260 break :b false;
259261 }
260262
261 if (options.lto == true) {
263 if (options.lto != null and options.lto != .none) {
262264 if (options.use_lld == false) return error.LtoRequiresLld;
263265 break :b true;
264266 }
......@@ -284,16 +286,16 @@ pub fn resolve(options: Options) ResolveError!Config {
284286 break :b .clang;
285287 };
286288
287 const lto = b: {
289 const lto: LtoMode = b: {
288290 if (!use_lld) {
289291 // zig ld LTO support is tracked by
290292 // https://github.com/ziglang/zig/issues/8680
291 if (options.lto == true) return error.LtoRequiresLld;
292 break :b false;
293 if (options.lto != null and options.lto != .none) return error.LtoRequiresLld;
294 break :b .none;
293295 }
294296
295297 if (options.lto) |x| break :b x;
296 if (!options.any_c_source_files) break :b false;
298 if (!options.any_c_source_files) break :b .none;
297299
298300 // https://github.com/llvm/llvm-project/pull/116537
299301 switch (target.abi) {
......@@ -303,15 +305,15 @@ pub fn resolve(options: Options) ResolveError!Config {
303305 .ilp32,
304306 .muslabin32,
305307 .muslx32,
306 => break :b false,
308 => break :b .none,
307309 else => {},
308310 }
309311
310312 break :b switch (options.output_mode) {
311 .Lib, .Obj => false,
313 .Lib, .Obj => .none,
312314 .Exe => switch (root_optimize_mode) {
313 .Debug => false,
314 .ReleaseSafe, .ReleaseFast, .ReleaseSmall => true,
315 .Debug => .none,
316 .ReleaseSafe, .ReleaseFast, .ReleaseSmall => .full,
315317 },
316318 };
317319 };
src/codegen/llvm.zig+2-2
......@@ -1056,7 +1056,7 @@ pub const Object = struct {
10561056 time_report: bool,
10571057 sanitize_thread: bool,
10581058 fuzz: bool,
1059 lto: bool,
1059 lto: Compilation.Config.LtoMode,
10601060 };
10611061
10621062 pub fn emit(o: *Object, options: EmitOptions) !void {
......@@ -1338,7 +1338,7 @@ pub const Object = struct {
13381338 .time_report = options.time_report,
13391339 .tsan = options.sanitize_thread,
13401340 .sancov = options.fuzz,
1341 .lto = options.lto,
1341 .lto = options.lto != .none,
13421342 // https://github.com/ziglang/zig/issues/21215
13431343 .allow_fast_isel = !comp.root_mod.resolved_target.result.cpu.arch.isMIPS(),
13441344 .asm_filename = null,
src/libunwind.zig+1-1
......@@ -37,7 +37,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
3737 .root_strip = comp.compilerRtStrip(),
3838 .link_libc = true,
3939 // Disable LTO to avoid https://github.com/llvm/llvm-project/issues/56825
40 .lto = false,
40 .lto = .none,
4141 }) catch |err| {
4242 comp.setMiscFailure(
4343 .libunwind,
src/link/Coff.zig+1-1
......@@ -1859,7 +1859,7 @@ fn linkWithLLD(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:
18591859 if (comp.version) |version| {
18601860 try argv.append(try allocPrint(arena, "-VERSION:{}.{}", .{ version.major, version.minor }));
18611861 }
1862 if (comp.config.lto) {
1862 if (comp.config.lto != .none) {
18631863 switch (optimize_mode) {
18641864 .Debug => {},
18651865 .ReleaseSmall => try argv.append("-OPT:lldlto=2"),
src/link/Elf.zig+2-2
......@@ -1640,7 +1640,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s
16401640 // copy when generating relocatables. Normally, we would expect `lld -r` to work.
16411641 // However, because LLD wants to resolve BPF relocations which it shouldn't, it fails
16421642 // before even generating the relocatable.
1643 if (output_mode == .Obj and (comp.config.lto or target.cpu.arch.isBpf())) {
1643 if (output_mode == .Obj and (comp.config.lto != .none or target.cpu.arch.isBpf())) {
16441644 // In this case we must do a simple file copy
16451645 // here. TODO: think carefully about how we can avoid this redundant operation when doing
16461646 // build-obj. See also the corresponding TODO in linkAsArchive.
......@@ -1683,7 +1683,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s
16831683 try argv.append(try std.fmt.allocPrint(arena, "--sysroot={s}", .{sysroot}));
16841684 }
16851685
1686 if (comp.config.lto) {
1686 if (comp.config.lto != .none) {
16871687 switch (comp.root_mod.optimize_mode) {
16881688 .Debug => {},
16891689 .ReleaseSmall => try argv.append("--lto-O2"),
src/link/Wasm.zig+1-1
......@@ -3537,7 +3537,7 @@ fn linkWithLLD(wasm: *Wasm, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:
35373537 try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, linker_command });
35383538 try argv.append("--error-limit=0");
35393539
3540 if (comp.config.lto) {
3540 if (comp.config.lto != .none) {
35413541 switch (comp.root_mod.optimize_mode) {
35423542 .Debug => {},
35433543 .ReleaseSmall => try argv.append("-O2"),
src/main.zig+25-4
......@@ -1386,9 +1386,18 @@ fn buildOutputType(
13861386 } else if (mem.eql(u8, arg, "-fno-PIE")) {
13871387 create_module.opts.pie = false;
13881388 } else if (mem.eql(u8, arg, "-flto")) {
1389 create_module.opts.lto = true;
1389 create_module.opts.lto = .full;
1390 } else if (mem.startsWith(u8, arg, "-flto=")) {
1391 const mode = arg["-flto=".len..];
1392 if (mem.eql(u8, mode, "full")) {
1393 create_module.opts.lto = .full;
1394 } else if (mem.eql(u8, mode, "thin")) {
1395 create_module.opts.lto = .thin;
1396 } else {
1397 fatal("Invalid -flto mode: '{s}'. Must be 'full'or 'thin'.", .{mode});
1398 }
13901399 } else if (mem.eql(u8, arg, "-fno-lto")) {
1391 create_module.opts.lto = false;
1400 create_module.opts.lto = .none;
13921401 } else if (mem.eql(u8, arg, "-funwind-tables")) {
13931402 mod_opts.unwind_tables = .sync;
13941403 } else if (mem.eql(u8, arg, "-fasync-unwind-tables")) {
......@@ -1958,8 +1967,20 @@ fn buildOutputType(
19581967 .no_pic => mod_opts.pic = false,
19591968 .pie => create_module.opts.pie = true,
19601969 .no_pie => create_module.opts.pie = false,
1961 .lto => create_module.opts.lto = true,
1962 .no_lto => create_module.opts.lto = false,
1970 .lto => {
1971 if (mem.eql(u8, it.only_arg, "flto") or
1972 mem.eql(u8, it.only_arg, "auto") or
1973 mem.eql(u8, it.only_arg, "full") or
1974 mem.eql(u8, it.only_arg, "jobserver"))
1975 {
1976 create_module.opts.lto = .full;
1977 } else if (mem.eql(u8, it.only_arg, "thin")) {
1978 create_module.opts.lto = .thin;
1979 } else {
1980 fatal("Invalid -flto mode: '{s}'. Must be 'auto', 'full', 'thin', or 'jobserver'.", .{it.only_arg});
1981 }
1982 },
1983 .no_lto => create_module.opts.lto = .none,
19631984 .red_zone => mod_opts.red_zone = true,
19641985 .no_red_zone => mod_opts.red_zone = false,
19651986 .omit_frame_pointer => mod_opts.omit_frame_pointer = true,