authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-06-13 01:27:09+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-17 16:38:59-07:00
log2259d629d3d4e361f78e4d1b79425dfae912f05c
tree4402fb49cebdf9bbaec0bc6fa861712c6caee922
parent80790be3094f65877231209532c04f7fdb4441a7

compiler_rt: use single cache for libcompiler_rt.a static lib


8 files changed, 151 insertions(+), 105 deletions(-)

CMakeLists.txt+1
...@@ -490,6 +490,7 @@ set(ZIG_STAGE2_SOURCES...@@ -490,6 +490,7 @@ set(ZIG_STAGE2_SOURCES
490 "${CMAKE_SOURCE_DIR}/lib/compiler_rt/ceil.zig"490 "${CMAKE_SOURCE_DIR}/lib/compiler_rt/ceil.zig"
491 "${CMAKE_SOURCE_DIR}/lib/compiler_rt/clear_cache.zig"491 "${CMAKE_SOURCE_DIR}/lib/compiler_rt/clear_cache.zig"
492 "${CMAKE_SOURCE_DIR}/lib/compiler_rt/cmp.zig"492 "${CMAKE_SOURCE_DIR}/lib/compiler_rt/cmp.zig"
493 "${CMAKE_SOURCE_DIR}/lib/compiler_rt/common.zig"
493 "${CMAKE_SOURCE_DIR}/lib/compiler_rt/compareXf2.zig"494 "${CMAKE_SOURCE_DIR}/lib/compiler_rt/compareXf2.zig"
494 "${CMAKE_SOURCE_DIR}/lib/compiler_rt/cos.zig"495 "${CMAKE_SOURCE_DIR}/lib/compiler_rt/cos.zig"
495 "${CMAKE_SOURCE_DIR}/lib/compiler_rt/count0bits.zig"496 "${CMAKE_SOURCE_DIR}/lib/compiler_rt/count0bits.zig"
lib/compiler_rt/os_version_check.zig+5-8
...@@ -6,10 +6,7 @@ pub const panic = @import("common.zig").panic;...@@ -6,10 +6,7 @@ pub const panic = @import("common.zig").panic;
66
7comptime {7comptime {
8 if (builtin.os.tag.isDarwin()) {8 if (builtin.os.tag.isDarwin()) {
9 @export(IsPlatformVersionAtLeast.__isPlatformVersionAtLeast, .{9 @export(__isPlatformVersionAtLeast, .{ .name = "__isPlatformVersionAtLeast", .linkage = linkage });
10 .name = "__isPlatformVersionAtLeast",
11 .linkage = linkage,
12 });
13 }10 }
14}11}
1512
...@@ -28,7 +25,7 @@ comptime {...@@ -28,7 +25,7 @@ comptime {
28// the newer codepath, which merely calls out to the Darwin _availability_version_check API which is25// the newer codepath, which merely calls out to the Darwin _availability_version_check API which is
29// available on macOS 10.15+, iOS 13+, tvOS 13+ and watchOS 6+.26// available on macOS 10.15+, iOS 13+, tvOS 13+ and watchOS 6+.
3027
31const IsPlatformVersionAtLeast = struct {28const __isPlatformVersionAtLeast = if (builtin.os.tag.isDarwin()) struct {
32 inline fn constructVersion(major: u32, minor: u32, subminor: u32) u32 {29 inline fn constructVersion(major: u32, minor: u32, subminor: u32) u32 {
33 return ((major & 0xffff) << 16) | ((minor & 0xff) << 8) | (subminor & 0xff);30 return ((major & 0xffff) << 16) | ((minor & 0xff) << 8) | (subminor & 0xff);
34 }31 }
...@@ -50,7 +47,7 @@ const IsPlatformVersionAtLeast = struct {...@@ -50,7 +47,7 @@ const IsPlatformVersionAtLeast = struct {
50 };47 };
51 // Darwin-only48 // Darwin-only
52 extern "c" fn _availability_version_check(count: u32, versions: [*c]const dyld_build_version_t) bool;49 extern "c" fn _availability_version_check(count: u32, versions: [*c]const dyld_build_version_t) bool;
53};50}.__isPlatformVersionAtLeast else struct {};
5451
55test "isPlatformVersionAtLeast" {52test "isPlatformVersionAtLeast" {
56 if (!comptime builtin.os.tag.isDarwin()) return error.SkipZigTest;53 if (!comptime builtin.os.tag.isDarwin()) return error.SkipZigTest;
...@@ -58,6 +55,6 @@ test "isPlatformVersionAtLeast" {...@@ -58,6 +55,6 @@ test "isPlatformVersionAtLeast" {
58 // Note: this test depends on the actual host OS version since it is merely calling into the55 // Note: this test depends on the actual host OS version since it is merely calling into the
59 // native Darwin API.56 // native Darwin API.
60 const macos_platform_constant = 1;57 const macos_platform_constant = 1;
61 try testing.expect(IsPlatformVersionAtLeast.__isPlatformVersionAtLeast(macos_platform_constant, 10, 0, 15) == 1);58 try testing.expect(__isPlatformVersionAtLeast(macos_platform_constant, 10, 0, 15) == 1);
62 try testing.expect(IsPlatformVersionAtLeast.__isPlatformVersionAtLeast(macos_platform_constant, 99, 0, 0) == 0);59 try testing.expect(__isPlatformVersionAtLeast(macos_platform_constant, 99, 0, 0) == 0);
63}60}
src/Compilation.zig+5-3
...@@ -132,7 +132,7 @@ libssp_static_lib: ?CRTFile = null,...@@ -132,7 +132,7 @@ libssp_static_lib: ?CRTFile = null,
132libc_static_lib: ?CRTFile = null,132libc_static_lib: ?CRTFile = null,
133/// Populated when we build the libcompiler_rt static library. A Job to build this is placed in the queue133/// Populated when we build the libcompiler_rt static library. A Job to build this is placed in the queue
134/// and resolved before calling linker.flush().134/// and resolved before calling linker.flush().
135compiler_rt_static_lib: compiler_rt.CompilerRtLib = .{},135compiler_rt_lib: ?CRTFile = null,
136/// Populated when we build the compiler_rt_obj object. A Job to build this is placed in the queue136/// Populated when we build the compiler_rt_obj object. A Job to build this is placed in the queue
137/// and resolved before calling linker.flush().137/// and resolved before calling linker.flush().
138compiler_rt_obj: ?CRTFile = null,138compiler_rt_obj: ?CRTFile = null,
...@@ -1979,7 +1979,9 @@ pub fn destroy(self: *Compilation) void {...@@ -1979,7 +1979,9 @@ pub fn destroy(self: *Compilation) void {
1979 if (self.libcxxabi_static_lib) |*crt_file| {1979 if (self.libcxxabi_static_lib) |*crt_file| {
1980 crt_file.deinit(gpa);1980 crt_file.deinit(gpa);
1981 }1981 }
1982 self.compiler_rt_static_lib.deinit(gpa);1982 if (self.compiler_rt_lib) |*crt_file| {
1983 crt_file.deinit(gpa);
1984 }
1983 if (self.compiler_rt_obj) |*crt_file| {1985 if (self.compiler_rt_obj) |*crt_file| {
1984 crt_file.deinit(gpa);1986 crt_file.deinit(gpa);
1985 }1987 }
...@@ -3139,7 +3141,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -3139,7 +3141,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
31393141
3140 compiler_rt.buildCompilerRtLib(3142 compiler_rt.buildCompilerRtLib(
3141 comp,3143 comp,
3142 &comp.compiler_rt_static_lib,3144 &comp.compiler_rt_lib,
3143 ) catch |err| switch (err) {3145 ) catch |err| switch (err) {
3144 error.OutOfMemory => return error.OutOfMemory,3146 error.OutOfMemory => return error.OutOfMemory,
3145 error.SubCompilationFailed => return, // error reported already3147 error.SubCompilationFailed => return, // error reported already
src/compiler_rt.zig+136-90
...@@ -1,123 +1,169 @@...@@ -1,123 +1,169 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const build_options = @import("build_options");
3const Allocator = std.mem.Allocator;4const Allocator = std.mem.Allocator;
5const assert = std.debug.assert;
4const mem = std.mem;6const mem = std.mem;
5const tracy = @import("tracy.zig");7const tracy = @import("tracy.zig");
6const trace = tracy.trace;8const trace = tracy.trace;
79
10const Cache = @import("Cache.zig");
8const Compilation = @import("Compilation.zig");11const Compilation = @import("Compilation.zig");
9const CRTFile = Compilation.CRTFile;12const CRTFile = Compilation.CRTFile;
10const LinkObject = Compilation.LinkObject;13const LinkObject = Compilation.LinkObject;
11const Package = @import("Package.zig");14const Package = @import("Package.zig");
1215
13pub const CompilerRtLib = struct {16pub fn buildCompilerRtLib(comp: *Compilation, compiler_rt_lib: *?CRTFile) !void {
14 crt_object_files: [sources.len]?CRTFile = undefined,
15 crt_lib_file: ?CRTFile = null,
16
17 pub fn deinit(crt_lib: *CompilerRtLib, gpa: Allocator) void {
18 for (crt_lib.crt_object_files) |*crt_file| {
19 if (crt_file.*) |*cf| {
20 cf.deinit(gpa);
21 }
22 }
23 if (crt_lib.crt_lib_file) |*crt_file| {
24 crt_file.deinit(gpa);
25 }
26 }
27};
28
29pub fn buildCompilerRtLib(comp: *Compilation, compiler_rt_lib: *CompilerRtLib) !void {
30 const tracy_trace = trace(@src());17 const tracy_trace = trace(@src());
31 defer tracy_trace.end();18 defer tracy_trace.end();
3219
33 var progress: std.Progress = .{ .dont_print_on_dumb = true };20 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
34 var progress_node = progress.start("Compile Compiler-RT", sources.len + 1);21 defer arena_allocator.deinit();
35 defer progress_node.end();22 const arena = arena_allocator.allocator();
36 if (comp.color == .off) progress.terminal = null;
3723
38 progress_node.activate();24 const target = comp.getTarget();
3925
40 var link_objects: [sources.len]LinkObject = undefined;26 // Use the global cache directory.
41 for (sources) |source, i| {27 var cache_parent: Cache = .{
42 var obj_progress_node = progress_node.start(source, 0);28 .gpa = comp.gpa,
43 obj_progress_node.activate();29 .manifest_dir = try comp.global_cache_directory.handle.makeOpenPath("h", .{}),
44 defer obj_progress_node.end();30 };
31 defer cache_parent.manifest_dir.close();
4532
46 try comp.buildOutputFromZig(source, .Obj, &compiler_rt_lib.crt_object_files[i], .compiler_rt);33 var cache = cache_parent.obtain();
47 link_objects[i] = .{34 defer cache.deinit();
48 .path = compiler_rt_lib.crt_object_files[i].?.full_object_path,35
49 .must_link = true,36 cache.hash.add(sources.len);
50 };37 for (sources) |source| {
38 const full_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{source});
39 _ = try cache.addFile(full_path, null);
51 }40 }
5241
53 const root_name = "compiler_rt";42 cache.hash.addBytes(build_options.version);
43 cache.hash.addBytes(comp.zig_lib_directory.path orelse ".");
44 cache.hash.add(target.cpu.arch);
45 cache.hash.add(target.os.tag);
46 cache.hash.add(target.abi);
5447
55 var lib_progress_node = progress_node.start(root_name, 0);48 const hit = try cache.hit();
56 lib_progress_node.activate();49 const digest = cache.final();
57 defer lib_progress_node.end();50 const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });
5851
59 const target = comp.getTarget();52 var o_directory: Compilation.Directory = .{
60 const basename = try std.zig.binNameAlloc(comp.gpa, .{53 .handle = try comp.global_cache_directory.handle.makeOpenPath(o_sub_path, .{}),
54 .path = try std.fs.path.join(arena, &[_][]const u8{ comp.global_cache_directory.path.?, o_sub_path }),
55 };
56 defer o_directory.handle.close();
57
58 const ok_basename = "ok";
59 const actual_hit = if (hit) blk: {
60 o_directory.handle.access(ok_basename, .{}) catch |err| switch (err) {
61 error.FileNotFound => break :blk false,
62 else => |e| return e,
63 };
64 break :blk true;
65 } else false;
66
67 const root_name = "compiler_rt";
68 const basename = try std.zig.binNameAlloc(arena, .{
61 .root_name = root_name,69 .root_name = root_name,
62 .target = target,70 .target = target,
63 .output_mode = .Lib,71 .output_mode = .Lib,
64 });72 });
65 errdefer comp.gpa.free(basename);
6673
67 // TODO: This is extracted into a local variable to work around a stage1 miscompilation.74 if (!actual_hit) {
68 const emit_bin = Compilation.EmitLoc{75 var progress: std.Progress = .{ .dont_print_on_dumb = true };
69 .directory = null, // Put it in the cache directory.76 var progress_node = progress.start("Compile Compiler-RT", sources.len + 1);
70 .basename = basename,77 defer progress_node.end();
71 };78 if (comp.color == .off) progress.terminal = null;
72 const sub_compilation = try Compilation.create(comp.gpa, .{79
73 .local_cache_directory = comp.global_cache_directory,80 progress_node.activate();
74 .global_cache_directory = comp.global_cache_directory,81
75 .zig_lib_directory = comp.zig_lib_directory,82 var link_objects: [sources.len]LinkObject = undefined;
76 .cache_mode = .whole,83 for (sources) |source, i| {
77 .target = target,84 var obj_progress_node = progress_node.start(source, 0);
78 .root_name = root_name,85 obj_progress_node.activate();
79 .main_pkg = null,86 defer obj_progress_node.end();
80 .output_mode = .Lib,87
81 .link_mode = .Static,88 var tmp_crt_file: ?CRTFile = null;
82 .function_sections = true,89 defer if (tmp_crt_file) |*crt| crt.deinit(comp.gpa);
83 .thread_pool = comp.thread_pool,90 try comp.buildOutputFromZig(source, .Obj, &tmp_crt_file, .compiler_rt);
84 .libc_installation = comp.bin_file.options.libc_installation,91 link_objects[i] = .{
85 .emit_bin = emit_bin,92 .path = try arena.dupe(u8, tmp_crt_file.?.full_object_path),
86 .optimize_mode = comp.compilerRtOptMode(),93 .must_link = true,
87 .want_sanitize_c = false,94 };
88 .want_stack_check = false,95 }
89 .want_red_zone = comp.bin_file.options.red_zone,96
90 .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,97 var lib_progress_node = progress_node.start(root_name, 0);
91 .want_valgrind = false,98 lib_progress_node.activate();
92 .want_tsan = false,99 defer lib_progress_node.end();
93 .want_pic = comp.bin_file.options.pic,100
94 .want_pie = comp.bin_file.options.pie,101 // TODO: This is extracted into a local variable to work around a stage1 miscompilation.
95 .want_lto = comp.bin_file.options.lto,102 const emit_bin = Compilation.EmitLoc{
96 .emit_h = null,103 .directory = o_directory, // Put it in the cache directory.
97 .strip = comp.compilerRtStrip(),104 .basename = basename,
98 .is_native_os = comp.bin_file.options.is_native_os,105 };
99 .is_native_abi = comp.bin_file.options.is_native_abi,106 const sub_compilation = try Compilation.create(comp.gpa, .{
100 .self_exe_path = comp.self_exe_path,107 .local_cache_directory = comp.global_cache_directory,
101 .link_objects = &link_objects,108 .global_cache_directory = comp.global_cache_directory,
102 .verbose_cc = comp.verbose_cc,109 .zig_lib_directory = comp.zig_lib_directory,
103 .verbose_link = comp.bin_file.options.verbose_link,110 .cache_mode = .whole,
104 .verbose_air = comp.verbose_air,111 .target = target,
105 .verbose_llvm_ir = comp.verbose_llvm_ir,112 .root_name = root_name,
106 .verbose_cimport = comp.verbose_cimport,113 .main_pkg = null,
107 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,114 .output_mode = .Lib,
108 .clang_passthrough_mode = comp.clang_passthrough_mode,115 .link_mode = .Static,
109 .skip_linker_dependencies = true,116 .function_sections = true,
110 .parent_compilation_link_libc = comp.bin_file.options.link_libc,117 .thread_pool = comp.thread_pool,
111 });118 .libc_installation = comp.bin_file.options.libc_installation,
112 defer sub_compilation.destroy();119 .emit_bin = emit_bin,
120 .optimize_mode = comp.compilerRtOptMode(),
121 .want_sanitize_c = false,
122 .want_stack_check = false,
123 .want_red_zone = comp.bin_file.options.red_zone,
124 .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
125 .want_valgrind = false,
126 .want_tsan = false,
127 .want_pic = comp.bin_file.options.pic,
128 .want_pie = comp.bin_file.options.pie,
129 .want_lto = comp.bin_file.options.lto,
130 .emit_h = null,
131 .strip = comp.compilerRtStrip(),
132 .is_native_os = comp.bin_file.options.is_native_os,
133 .is_native_abi = comp.bin_file.options.is_native_abi,
134 .self_exe_path = comp.self_exe_path,
135 .link_objects = &link_objects,
136 .verbose_cc = comp.verbose_cc,
137 .verbose_link = comp.bin_file.options.verbose_link,
138 .verbose_air = comp.verbose_air,
139 .verbose_llvm_ir = comp.verbose_llvm_ir,
140 .verbose_cimport = comp.verbose_cimport,
141 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
142 .clang_passthrough_mode = comp.clang_passthrough_mode,
143 .skip_linker_dependencies = true,
144 .parent_compilation_link_libc = comp.bin_file.options.link_libc,
145 });
146 defer sub_compilation.destroy();
147
148 try sub_compilation.updateSubCompilation();
149
150 if (o_directory.handle.createFile(ok_basename, .{})) |file| {
151 file.close();
152 } else |err| {
153 std.log.warn("compiler-rt lib: failed to mark completion: {s}", .{@errorName(err)});
154 }
155 }
113156
114 try sub_compilation.updateSubCompilation();157 try cache.writeManifest();
115158
116 compiler_rt_lib.crt_lib_file = .{159 assert(compiler_rt_lib.* == null);
117 .full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(comp.gpa, &[_][]const u8{160 compiler_rt_lib.* = .{
118 sub_compilation.bin_file.options.emit.?.sub_path,161 .full_object_path = try std.fs.path.join(comp.gpa, &[_][]const u8{
162 comp.global_cache_directory.path.?,
163 o_sub_path,
164 basename,
119 }),165 }),
120 .lock = sub_compilation.bin_file.toOwnedLock(),166 .lock = cache.toOwnedLock(),
121 };167 };
122}168}
123169
src/link/Coff.zig+1-1
...@@ -1354,7 +1354,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !...@@ -1354,7 +1354,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !
1354 }1354 }
1355 // MSVC compiler_rt is missing some stuff, so we build it unconditionally but1355 // MSVC compiler_rt is missing some stuff, so we build it unconditionally but
1356 // and rely on weak linkage to allow MSVC compiler_rt functions to override ours.1356 // and rely on weak linkage to allow MSVC compiler_rt functions to override ours.
1357 if (comp.compiler_rt_static_lib.crt_lib_file) |lib| {1357 if (comp.compiler_rt_lib) |lib| {
1358 try argv.append(lib.full_object_path);1358 try argv.append(lib.full_object_path);
1359 }1359 }
1360 }1360 }
src/link/Elf.zig+1-1
...@@ -1272,7 +1272,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v...@@ -1272,7 +1272,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
1272 const stack_size = self.base.options.stack_size_override orelse 16777216;1272 const stack_size = self.base.options.stack_size_override orelse 16777216;
1273 const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;1273 const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;
1274 const compiler_rt_path: ?[]const u8 = blk: {1274 const compiler_rt_path: ?[]const u8 = blk: {
1275 if (comp.compiler_rt_static_lib.crt_lib_file) |x| break :blk x.full_object_path;1275 if (comp.compiler_rt_lib) |x| break :blk x.full_object_path;
1276 if (comp.compiler_rt_obj) |x| break :blk x.full_object_path;1276 if (comp.compiler_rt_obj) |x| break :blk x.full_object_path;
1277 break :blk null;1277 break :blk null;
1278 };1278 };
src/link/MachO.zig+1-1
...@@ -738,7 +738,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -738,7 +738,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
738 try positionals.append(p);738 try positionals.append(p);
739 }739 }
740740
741 if (comp.compiler_rt_static_lib.crt_lib_file) |lib| {741 if (comp.compiler_rt_lib) |lib| {
742 try positionals.append(lib.full_object_path);742 try positionals.append(lib.full_object_path);
743 }743 }
744744
src/link/Wasm.zig+1-1
...@@ -2255,7 +2255,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !...@@ -2255,7 +2255,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
2255 const is_obj = self.base.options.output_mode == .Obj;2255 const is_obj = self.base.options.output_mode == .Obj;
22562256
2257 const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt and !is_obj)2257 const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt and !is_obj)
2258 comp.compiler_rt_static_lib.crt_lib_file.?.full_object_path2258 comp.compiler_rt_lib.?.full_object_path
2259 else2259 else
2260 null;2260 null;
22612261