diff --git a/src/Compilation.zig b/src/Compilation.zig index 2ff390f196..4196eb634d 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -736,6 +736,7 @@ pub const InitOptions = struct { linker_tsaware: bool = false, linker_nxcompat: bool = false, linker_dynamicbase: bool = false, + linker_optimization: ?u8 = null, major_subsystem_version: ?u32 = null, minor_subsystem_version: ?u32 = null, clang_passthrough_mode: bool = false, @@ -1140,6 +1141,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { const strip = options.strip or !target_util.hasDebugInfo(options.target); const red_zone = options.want_red_zone orelse target_util.hasRedZone(options.target); const omit_frame_pointer = options.omit_frame_pointer orelse (options.optimize_mode != .Debug); + const linker_optimization: u8 = options.linker_optimization orelse switch (options.optimize_mode) { + .Debug => @as(u8, 0), + else => @as(u8, 3), + }; // We put everything into the cache hash that *cannot be modified during an incremental update*. // For example, one cannot change the target between updates, but one can change source files, @@ -1450,6 +1455,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .tsaware = options.linker_tsaware, .nxcompat = options.linker_nxcompat, .dynamicbase = options.linker_dynamicbase, + .linker_optimization = linker_optimization, .major_subsystem_version = options.major_subsystem_version, .minor_subsystem_version = options.minor_subsystem_version, .stack_size_override = options.stack_size_override, diff --git a/src/link.zig b/src/link.zig index 3657397500..f4c51c735f 100644 --- a/src/link.zig +++ b/src/link.zig @@ -99,6 +99,7 @@ pub const Options = struct { tsaware: bool, nxcompat: bool, dynamicbase: bool, + linker_optimization: u8, bind_global_refs_locally: bool, import_memory: bool, initial_memory: ?u64, diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 43447e0ec4..646a568684 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1349,6 +1349,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { man.hash.add(self.base.options.bind_global_refs_locally); man.hash.add(self.base.options.tsan); man.hash.addOptionalBytes(self.base.options.sysroot); + man.hash.add(self.base.options.linker_optimization); // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock. _ = try man.hit(); @@ -1425,10 +1426,13 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { if (self.base.options.lto) { switch (self.base.options.optimize_mode) { .Debug => {}, - .ReleaseSmall => try argv.append("-O2"), - .ReleaseFast, .ReleaseSafe => try argv.append("-O3"), + .ReleaseSmall => try argv.append("--lto-O2"), + .ReleaseFast, .ReleaseSafe => try argv.append("--lto-O3"), } } + try argv.append(try std.fmt.allocPrint(arena, "-O{d}", .{ + self.base.options.linker_optimization, + })); if (self.base.options.output_mode == .Exe) { try argv.append("-z"); diff --git a/src/main.zig b/src/main.zig index 2c99f508d4..c2e7d293ec 100644 --- a/src/main.zig +++ b/src/main.zig @@ -635,6 +635,7 @@ fn buildOutputType( var linker_tsaware = false; var linker_nxcompat = false; var linker_dynamicbase = false; + var linker_optimization: ?u8 = null; var test_evented_io = false; var test_no_exec = false; var stack_size_override: ?u64 = null; @@ -1488,11 +1489,13 @@ fn buildOutputType( if (i >= linker_args.items.len) { fatal("expected linker arg after '{s}'", .{arg}); } - warn("ignoring linker arg -O{s} because it does nothing", .{ - linker_args.items[i], - }); + linker_optimization = std.fmt.parseUnsigned(u8, linker_args.items[i], 10) catch |err| { + fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); + }; } else if (mem.startsWith(u8, arg, "-O")) { - warn("ignoring linker arg {s} because it does nothing", .{arg}); + linker_optimization = std.fmt.parseUnsigned(u8, arg["-O".len..], 10) catch |err| { + fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); + }; } else if (mem.eql(u8, arg, "--gc-sections")) { linker_gc_sections = true; } else if (mem.eql(u8, arg, "--no-gc-sections")) { @@ -2309,6 +2312,7 @@ fn buildOutputType( .linker_tsaware = linker_tsaware, .linker_nxcompat = linker_nxcompat, .linker_dynamicbase = linker_dynamicbase, + .linker_optimization = linker_optimization, .major_subsystem_version = major_subsystem_version, .minor_subsystem_version = minor_subsystem_version, .link_eh_frame_hdr = link_eh_frame_hdr, diff --git a/test/standalone/install_raw_hex/build.zig b/test/standalone/install_raw_hex/build.zig index 086fafebbc..789197b627 100644 --- a/test/standalone/install_raw_hex/build.zig +++ b/test/standalone/install_raw_hex/build.zig @@ -35,7 +35,7 @@ pub fn build(b: *Builder) void { ":1001140000000000000000000000000000000000DB", ":1001240000000000000000000000000000000000CB", ":1001340000000000000000000000000000000000BB", - ":10014400830202006C020100090000002102010088", + ":1001440083020200F401010009000000FE01010025", ":100154000900000001000000000000000000000091", ":1001640000080002008001010004000010000000EB", ":100174000000000000000000000000001F0000005C", @@ -44,17 +44,17 @@ pub fn build(b: *Builder) void { ":1001A40000000000000000001F000000000000002C", ":1001B400000000000000000000000000000000003B", ":1001C400000000000000000000000000000000002B", - ":1001D4005B02010010000000F40101002C0000008B", - ":1001E4003F0201001B0000002B020100130000006D", - ":1001F40072656D61696E646572206469766973699C", - ":100204006F6E206279207A65726F206F72206E653E", - ":100214006761746976652076616C756500636F72D9", - ":100224007465782D6D3400696E646578206F75741B", - ":10023400206F6620626F756E647300696E74656703", - ":1002440065722063617374207472756E6361746582", - ":10025400642062697473006469766973696F6E20DF", - ":100264006279207A65726F00636F727465785F6D6E", - ":100274003400000081B00091FFE700BEFDE7D0B577", + ":1001D4000802010010000000190201002C000000B8", + ":1001E400460201001B00000062020100130000002F", + ":1001F400636F727465785F6D3400636F72746578D1", + ":100204002D6D34006469766973696F6E206279209C", + ":100214007A65726F0072656D61696E6465722064DF", + ":1002240069766973696F6E206279207A65726F20CE", + ":100234006F72206E656761746976652076616C758E", + ":100244006500696E746567657220636173742074F8", + ":1002540072756E6361746564206269747300696E9B", + ":10026400646578206F7574206F6620626F756E64A4", + ":100274007300000081B00091FFE700BEFDE7D0B538", ":1002840002AF90B00391029007A800F029F80399F7", ":100294000020069048680490FFE7049906980190AE", ":1002A40088420FD2FFE7019903980068405C07F881", @@ -89,7 +89,7 @@ pub fn build(b: *Builder) void { ":1001140000000000000000000000000000000000DB", ":1001240000000000000000000000000000000000CB", ":1001340000000000000000000000000000000000BB", - ":10014400830202006C020100090000002102010088", + ":1001440083020200F401010009000000FE01010025", ":100154000900000001000000000000000000000091", ":1001640000080002008001010004000010000000EB", ":100174000000000000000000000000001F0000005C", @@ -98,17 +98,17 @@ pub fn build(b: *Builder) void { ":1001A40000000000000000001F000000000000002C", ":1001B400000000000000000000000000000000003B", ":1001C400000000000000000000000000000000002B", - ":1001D4005B02010010000000F40101002C0000008B", - ":1001E4003F0201001B0000002B020100130000006D", - ":1001F40072656D61696E646572206469766973699C", - ":100204006F6E206279207A65726F206F72206E653E", - ":100214006761746976652076616C756500636F72D9", - ":100224007465782D6D3400696E646578206F75741B", - ":10023400206F6620626F756E647300696E74656703", - ":1002440065722063617374207472756E6361746582", - ":10025400642062697473006469766973696F6E20DF", - ":100264006279207A65726F00636F727465785F6D6E", - ":100274003400000081B00091FFE700BEFDE7D0B577", + ":1001D4000802010010000000190201002C000000B8", + ":1001E400460201001B00000062020100130000002F", + ":1001F400636F727465785F6D3400636F72746578D1", + ":100204002D6D34006469766973696F6E206279209C", + ":100214007A65726F0072656D61696E6465722064DF", + ":1002240069766973696F6E206279207A65726F20CE", + ":100234006F72206E656761746976652076616C758E", + ":100244006500696E746567657220636173742074F8", + ":1002540072756E6361746564206269747300696E9B", + ":10026400646578206F7574206F6620626F756E64A4", + ":100274007300000081B00091FFE700BEFDE7D0B538", ":1002840002AF90B00391029007A800F029F80399F7", ":100294000020069048680490FFE7049906980190AE", ":1002A40088420FD2FFE7019903980068405C07F881",