stage2: support LLD -O flags on ELF

In 7e23b3245a9bf6e002009e6c18c10a9995671afa I made -O flags to the
linker emit a warning that the argument does nothing. That was not
correct however; LLD does have some logic that does different things
depending on -O0, -O1, and -O2. It defaults to -O1, and it does less
optimizations with -O0 and more with -O2.

With this commit, e.g. `-Wl,-O1` is supported by the `zig cc` frontend,
and by default we pass `-O0` to LLD in debug mode, and `-O3` in release
modes.

I also fixed a bug in the LLD ELF linker line which was incorrectly
passing `-O` flags instead of `--lto-O` flags for LTO.
This commit is contained in:
Andrew Kelley 2021-11-24 18:35:37 -07:00
parent 27c5c7fb23
commit 20cc7af8e6
5 changed files with 45 additions and 30 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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");

View File

@ -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,

View File

@ -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",