Skip to content

Commit 15278b7

Browse files
authored
Merge pull request #7856 from ziglang/lto
add LTO support
2 parents 843d91e + 0d4b6ac commit 15278b7

19 files changed

+577
-400
lines changed

src/Compilation.zig

+37
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ pub const InitOptions = struct {
444444
want_valgrind: ?bool = null,
445445
want_tsan: ?bool = null,
446446
want_compiler_rt: ?bool = null,
447+
want_lto: ?bool = null,
447448
use_llvm: ?bool = null,
448449
use_lld: ?bool = null,
449450
use_clang: ?bool = null,
@@ -602,6 +603,12 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
602603
if (ofmt == .c)
603604
break :blk false;
604605

606+
if (options.want_lto) |lto| {
607+
if (lto) {
608+
break :blk true;
609+
}
610+
}
611+
605612
// Our linker can't handle objects or most advanced options yet.
606613
if (options.link_objects.len != 0 or
607614
options.c_source_files.len != 0 or
@@ -647,6 +654,26 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
647654
break :outer opts;
648655
} else .{};
649656

657+
const lto = blk: {
658+
if (options.want_lto) |explicit| {
659+
if (!use_lld)
660+
return error.LtoUnavailableWithoutLld;
661+
break :blk explicit;
662+
} else if (!use_lld) {
663+
break :blk false;
664+
} else if (options.c_source_files.len == 0) {
665+
break :blk false;
666+
} else if (darwin_options.system_linker_hack) {
667+
break :blk false;
668+
} else switch (options.output_mode) {
669+
.Lib, .Obj => break :blk false,
670+
.Exe => switch (options.optimize_mode) {
671+
.Debug => break :blk false,
672+
.ReleaseSafe, .ReleaseFast, .ReleaseSmall => break :blk true,
673+
},
674+
}
675+
};
676+
650677
const tsan = options.want_tsan orelse false;
651678

652679
const link_libc = options.link_libc or target_util.osRequiresLibC(options.target) or tsan;
@@ -821,6 +848,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
821848
cache.hash.add(ofmt);
822849
cache.hash.add(pic);
823850
cache.hash.add(pie);
851+
cache.hash.add(lto);
824852
cache.hash.add(tsan);
825853
cache.hash.add(stack_check);
826854
cache.hash.add(red_zone);
@@ -1022,6 +1050,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
10221050
.libc_installation = libc_dirs.libc_installation,
10231051
.pic = pic,
10241052
.pie = pie,
1053+
.lto = lto,
10251054
.valgrind = valgrind,
10261055
.tsan = tsan,
10271056
.stack_check = stack_check,
@@ -2233,6 +2262,9 @@ pub fn addCCArgs(
22332262
"-nostdinc",
22342263
"-fno-spell-checking",
22352264
});
2265+
if (comp.bin_file.options.lto) {
2266+
try argv.append("-flto");
2267+
}
22362268

22372269
// According to Rich Felker libc headers are supposed to go before C language headers.
22382270
// However as noted by @dimenus, appending libc headers before c_headers breaks intrinsics
@@ -3255,6 +3287,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
32553287
.err_color = @enumToInt(comp.color),
32563288
.pic = comp.bin_file.options.pic,
32573289
.pie = comp.bin_file.options.pie,
3290+
.lto = comp.bin_file.options.lto,
32583291
.link_libc = comp.bin_file.options.link_libc,
32593292
.link_libcpp = comp.bin_file.options.link_libcpp,
32603293
.strip = comp.bin_file.options.strip,
@@ -3415,6 +3448,10 @@ pub fn build_crt_file(
34153448
.want_tsan = false,
34163449
.want_pic = comp.bin_file.options.pic,
34173450
.want_pie = comp.bin_file.options.pie,
3451+
.want_lto = switch (output_mode) {
3452+
.Lib => comp.bin_file.options.lto,
3453+
.Obj, .Exe => false,
3454+
},
34183455
.emit_h = null,
34193456
.strip = comp.compilerRtStrip(),
34203457
.is_native_os = comp.bin_file.options.is_native_os,

src/clang_options_data.zig

+24-3
Original file line numberDiff line numberDiff line change
@@ -2732,7 +2732,14 @@ flagpd1("fkeep-static-consts"),
27322732
flagpd1("flat_namespace"),
27332733
flagpd1("flax-vector-conversions"),
27342734
flagpd1("flimit-debug-info"),
2735-
flagpd1("flto"),
2735+
.{
2736+
.name = "flto",
2737+
.syntax = .flag,
2738+
.zig_equivalent = .lto,
2739+
.pd1 = true,
2740+
.pd2 = false,
2741+
.psl = false,
2742+
},
27362743
flagpd1("flto-unit"),
27372744
flagpd1("flto-visibility-public-std"),
27382745
sepd1("fmacro-backtrace-limit"),
@@ -2942,7 +2949,14 @@ flagpd1("fno-jump-tables"),
29422949
flagpd1("fno-keep-static-consts"),
29432950
flagpd1("fno-lax-vector-conversions"),
29442951
flagpd1("fno-limit-debug-info"),
2945-
flagpd1("fno-lto"),
2952+
.{
2953+
.name = "fno-lto",
2954+
.syntax = .flag,
2955+
.zig_equivalent = .no_lto,
2956+
.pd1 = true,
2957+
.pd2 = false,
2958+
.psl = false,
2959+
},
29462960
flagpd1("fno-lto-unit"),
29472961
flagpd1("fno-math-builtin"),
29482962
flagpd1("fno-math-errno"),
@@ -5638,7 +5652,14 @@ jspd1("Ttext"),
56385652
.pd2 = true,
56395653
.psl = false,
56405654
},
5641-
joinpd1("flto="),
5655+
.{
5656+
.name = "flto=",
5657+
.syntax = .joined,
5658+
.zig_equivalent = .lto,
5659+
.pd1 = true,
5660+
.pd2 = false,
5661+
.psl = false,
5662+
},
56425663
joinpd1("gcoff"),
56435664
joinpd1("mabi="),
56445665
joinpd1("mabs="),

src/codegen/llvm/bindings.zig

+7-1
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,13 @@ pub const TargetMachine = opaque {
243243
extern fn LLVMDisposeTargetMachine(T: *const TargetMachine) void;
244244

245245
pub const emitToFile = LLVMTargetMachineEmitToFile;
246-
extern fn LLVMTargetMachineEmitToFile(*const TargetMachine, M: *const Module, Filename: [*:0]const u8, codegen: CodeGenFileType, ErrorMessage: *[*:0]const u8) LLVMBool;
246+
extern fn LLVMTargetMachineEmitToFile(
247+
*const TargetMachine,
248+
M: *const Module,
249+
Filename: [*:0]const u8,
250+
codegen: CodeGenFileType,
251+
ErrorMessage: *[*:0]const u8,
252+
) LLVMBool;
247253
};
248254

249255
pub const CodeMode = extern enum {

src/link.zig

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ pub const Options = struct {
7474
is_native_abi: bool,
7575
pic: bool,
7676
pie: bool,
77+
lto: bool,
7778
valgrind: bool,
7879
tsan: bool,
7980
stack_check: bool,

src/link/Coff.zig

+7
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,13 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
945945
if (!self.base.options.strip) {
946946
try argv.append("-DEBUG");
947947
}
948+
if (self.base.options.lto) {
949+
switch (self.base.options.optimize_mode) {
950+
.Debug => {},
951+
.ReleaseSmall => try argv.append("-OPT:lldlto=2"),
952+
.ReleaseFast, .ReleaseSafe => try argv.append("-OPT:lldlto=3"),
953+
}
954+
}
948955
if (self.base.options.output_mode == .Exe) {
949956
const stack_size = self.base.options.stack_size_override orelse 16777216;
950957
try argv.append(try allocPrint(arena, "-STACK:{d}", .{stack_size}));

0 commit comments

Comments
 (0)