Skip to content

Commit 8330a95

Browse files
kubkonandrewrk
authored andcommitted
compiler_rt: use single cache for libcompiler_rt.a static lib
1 parent fdff857 commit 8330a95

File tree

8 files changed

+151
-105
lines changed

8 files changed

+151
-105
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,7 @@ set(ZIG_STAGE2_SOURCES
490490
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/ceil.zig"
491491
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/clear_cache.zig"
492492
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/cmp.zig"
493+
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/common.zig"
493494
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/compareXf2.zig"
494495
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/cos.zig"
495496
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/count0bits.zig"

lib/compiler_rt/os_version_check.zig

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ pub const panic = @import("common.zig").panic;
66

77
comptime {
88
if (builtin.os.tag.isDarwin()) {
9-
@export(IsPlatformVersionAtLeast.__isPlatformVersionAtLeast, .{
10-
.name = "__isPlatformVersionAtLeast",
11-
.linkage = linkage,
12-
});
9+
@export(__isPlatformVersionAtLeast, .{ .name = "__isPlatformVersionAtLeast", .linkage = linkage });
1310
}
1411
}
1512

@@ -28,7 +25,7 @@ comptime {
2825
// the newer codepath, which merely calls out to the Darwin _availability_version_check API which is
2926
// available on macOS 10.15+, iOS 13+, tvOS 13+ and watchOS 6+.
3027

31-
const IsPlatformVersionAtLeast = struct {
28+
const __isPlatformVersionAtLeast = if (builtin.os.tag.isDarwin()) struct {
3229
inline fn constructVersion(major: u32, minor: u32, subminor: u32) u32 {
3330
return ((major & 0xffff) << 16) | ((minor & 0xff) << 8) | (subminor & 0xff);
3431
}
@@ -50,14 +47,14 @@ const IsPlatformVersionAtLeast = struct {
5047
};
5148
// Darwin-only
5249
extern "c" fn _availability_version_check(count: u32, versions: [*c]const dyld_build_version_t) bool;
53-
};
50+
}.__isPlatformVersionAtLeast else struct {};
5451

5552
test "isPlatformVersionAtLeast" {
5653
if (!comptime builtin.os.tag.isDarwin()) return error.SkipZigTest;
5754

5855
// Note: this test depends on the actual host OS version since it is merely calling into the
5956
// native Darwin API.
6057
const macos_platform_constant = 1;
61-
try testing.expect(IsPlatformVersionAtLeast.__isPlatformVersionAtLeast(macos_platform_constant, 10, 0, 15) == 1);
62-
try testing.expect(IsPlatformVersionAtLeast.__isPlatformVersionAtLeast(macos_platform_constant, 99, 0, 0) == 0);
58+
try testing.expect(__isPlatformVersionAtLeast(macos_platform_constant, 10, 0, 15) == 1);
59+
try testing.expect(__isPlatformVersionAtLeast(macos_platform_constant, 99, 0, 0) == 0);
6360
}

src/Compilation.zig

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ libssp_static_lib: ?CRTFile = null,
132132
libc_static_lib: ?CRTFile = null,
133133
/// Populated when we build the libcompiler_rt static library. A Job to build this is placed in the queue
134134
/// and resolved before calling linker.flush().
135-
compiler_rt_static_lib: compiler_rt.CompilerRtLib = .{},
135+
compiler_rt_lib: ?CRTFile = null,
136136
/// Populated when we build the compiler_rt_obj object. A Job to build this is placed in the queue
137137
/// and resolved before calling linker.flush().
138138
compiler_rt_obj: ?CRTFile = null,
@@ -1979,7 +1979,9 @@ pub fn destroy(self: *Compilation) void {
19791979
if (self.libcxxabi_static_lib) |*crt_file| {
19801980
crt_file.deinit(gpa);
19811981
}
1982-
self.compiler_rt_static_lib.deinit(gpa);
1982+
if (self.compiler_rt_lib) |*crt_file| {
1983+
crt_file.deinit(gpa);
1984+
}
19831985
if (self.compiler_rt_obj) |*crt_file| {
19841986
crt_file.deinit(gpa);
19851987
}
@@ -3139,7 +3141,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
31393141

31403142
compiler_rt.buildCompilerRtLib(
31413143
comp,
3142-
&comp.compiler_rt_static_lib,
3144+
&comp.compiler_rt_lib,
31433145
) catch |err| switch (err) {
31443146
error.OutOfMemory => return error.OutOfMemory,
31453147
error.SubCompilationFailed => return, // error reported already

src/compiler_rt.zig

Lines changed: 136 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,169 @@
11
const std = @import("std");
22
const builtin = @import("builtin");
3+
const build_options = @import("build_options");
34
const Allocator = std.mem.Allocator;
5+
const assert = std.debug.assert;
46
const mem = std.mem;
57
const tracy = @import("tracy.zig");
68
const trace = tracy.trace;
79

10+
const Cache = @import("Cache.zig");
811
const Compilation = @import("Compilation.zig");
912
const CRTFile = Compilation.CRTFile;
1013
const LinkObject = Compilation.LinkObject;
1114
const Package = @import("Package.zig");
1215

13-
pub const CompilerRtLib = struct {
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-
29-
pub fn buildCompilerRtLib(comp: *Compilation, compiler_rt_lib: *CompilerRtLib) !void {
16+
pub fn buildCompilerRtLib(comp: *Compilation, compiler_rt_lib: *?CRTFile) !void {
3017
const tracy_trace = trace(@src());
3118
defer tracy_trace.end();
3219

33-
var progress: std.Progress = .{ .dont_print_on_dumb = true };
34-
var progress_node = progress.start("Compile Compiler-RT", sources.len + 1);
35-
defer progress_node.end();
36-
if (comp.color == .off) progress.terminal = null;
20+
var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
21+
defer arena_allocator.deinit();
22+
const arena = arena_allocator.allocator();
3723

38-
progress_node.activate();
24+
const target = comp.getTarget();
3925

40-
var link_objects: [sources.len]LinkObject = undefined;
41-
for (sources) |source, i| {
42-
var obj_progress_node = progress_node.start(source, 0);
43-
obj_progress_node.activate();
44-
defer obj_progress_node.end();
26+
// Use the global cache directory.
27+
var cache_parent: Cache = .{
28+
.gpa = comp.gpa,
29+
.manifest_dir = try comp.global_cache_directory.handle.makeOpenPath("h", .{}),
30+
};
31+
defer cache_parent.manifest_dir.close();
4532

46-
try comp.buildOutputFromZig(source, .Obj, &compiler_rt_lib.crt_object_files[i], .compiler_rt);
47-
link_objects[i] = .{
48-
.path = compiler_rt_lib.crt_object_files[i].?.full_object_path,
49-
.must_link = true,
50-
};
33+
var cache = cache_parent.obtain();
34+
defer cache.deinit();
35+
36+
cache.hash.add(sources.len);
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);
5140
}
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);
56-
lib_progress_node.activate();
57-
defer lib_progress_node.end();
48+
const hit = try cache.hit();
49+
const digest = cache.final();
50+
const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });
5851

59-
const target = comp.getTarget();
60-
const basename = try std.zig.binNameAlloc(comp.gpa, .{
52+
var o_directory: Compilation.Directory = .{
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, .{
6169
.root_name = root_name,
6270
.target = target,
6371
.output_mode = .Lib,
6472
});
65-
errdefer comp.gpa.free(basename);
6673

67-
// TODO: This is extracted into a local variable to work around a stage1 miscompilation.
68-
const emit_bin = Compilation.EmitLoc{
69-
.directory = null, // Put it in the cache directory.
70-
.basename = basename,
71-
};
72-
const sub_compilation = try Compilation.create(comp.gpa, .{
73-
.local_cache_directory = comp.global_cache_directory,
74-
.global_cache_directory = comp.global_cache_directory,
75-
.zig_lib_directory = comp.zig_lib_directory,
76-
.cache_mode = .whole,
77-
.target = target,
78-
.root_name = root_name,
79-
.main_pkg = null,
80-
.output_mode = .Lib,
81-
.link_mode = .Static,
82-
.function_sections = true,
83-
.thread_pool = comp.thread_pool,
84-
.libc_installation = comp.bin_file.options.libc_installation,
85-
.emit_bin = emit_bin,
86-
.optimize_mode = comp.compilerRtOptMode(),
87-
.want_sanitize_c = false,
88-
.want_stack_check = false,
89-
.want_red_zone = comp.bin_file.options.red_zone,
90-
.omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
91-
.want_valgrind = false,
92-
.want_tsan = false,
93-
.want_pic = comp.bin_file.options.pic,
94-
.want_pie = comp.bin_file.options.pie,
95-
.want_lto = comp.bin_file.options.lto,
96-
.emit_h = null,
97-
.strip = comp.compilerRtStrip(),
98-
.is_native_os = comp.bin_file.options.is_native_os,
99-
.is_native_abi = comp.bin_file.options.is_native_abi,
100-
.self_exe_path = comp.self_exe_path,
101-
.link_objects = &link_objects,
102-
.verbose_cc = comp.verbose_cc,
103-
.verbose_link = comp.bin_file.options.verbose_link,
104-
.verbose_air = comp.verbose_air,
105-
.verbose_llvm_ir = comp.verbose_llvm_ir,
106-
.verbose_cimport = comp.verbose_cimport,
107-
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
108-
.clang_passthrough_mode = comp.clang_passthrough_mode,
109-
.skip_linker_dependencies = true,
110-
.parent_compilation_link_libc = comp.bin_file.options.link_libc,
111-
});
112-
defer sub_compilation.destroy();
74+
if (!actual_hit) {
75+
var progress: std.Progress = .{ .dont_print_on_dumb = true };
76+
var progress_node = progress.start("Compile Compiler-RT", sources.len + 1);
77+
defer progress_node.end();
78+
if (comp.color == .off) progress.terminal = null;
79+
80+
progress_node.activate();
81+
82+
var link_objects: [sources.len]LinkObject = undefined;
83+
for (sources) |source, i| {
84+
var obj_progress_node = progress_node.start(source, 0);
85+
obj_progress_node.activate();
86+
defer obj_progress_node.end();
87+
88+
var tmp_crt_file: ?CRTFile = null;
89+
defer if (tmp_crt_file) |*crt| crt.deinit(comp.gpa);
90+
try comp.buildOutputFromZig(source, .Obj, &tmp_crt_file, .compiler_rt);
91+
link_objects[i] = .{
92+
.path = try arena.dupe(u8, tmp_crt_file.?.full_object_path),
93+
.must_link = true,
94+
};
95+
}
96+
97+
var lib_progress_node = progress_node.start(root_name, 0);
98+
lib_progress_node.activate();
99+
defer lib_progress_node.end();
100+
101+
// TODO: This is extracted into a local variable to work around a stage1 miscompilation.
102+
const emit_bin = Compilation.EmitLoc{
103+
.directory = o_directory, // Put it in the cache directory.
104+
.basename = basename,
105+
};
106+
const sub_compilation = try Compilation.create(comp.gpa, .{
107+
.local_cache_directory = comp.global_cache_directory,
108+
.global_cache_directory = comp.global_cache_directory,
109+
.zig_lib_directory = comp.zig_lib_directory,
110+
.cache_mode = .whole,
111+
.target = target,
112+
.root_name = root_name,
113+
.main_pkg = null,
114+
.output_mode = .Lib,
115+
.link_mode = .Static,
116+
.function_sections = true,
117+
.thread_pool = comp.thread_pool,
118+
.libc_installation = comp.bin_file.options.libc_installation,
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 = .{
117-
.full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(comp.gpa, &[_][]const u8{
118-
sub_compilation.bin_file.options.emit.?.sub_path,
159+
assert(compiler_rt_lib.* == null);
160+
compiler_rt_lib.* = .{
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,
119165
}),
120-
.lock = sub_compilation.bin_file.toOwnedLock(),
166+
.lock = cache.toOwnedLock(),
121167
};
122168
}
123169

src/link/Coff.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1354,7 +1354,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !
13541354
}
13551355
// MSVC compiler_rt is missing some stuff, so we build it unconditionally but
13561356
// 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| {
13581358
try argv.append(lib.full_object_path);
13591359
}
13601360
}

src/link/Elf.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1272,7 +1272,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
12721272
const stack_size = self.base.options.stack_size_override orelse 16777216;
12731273
const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;
12741274
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;
12761276
if (comp.compiler_rt_obj) |x| break :blk x.full_object_path;
12771277
break :blk null;
12781278
};

src/link/MachO.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
738738
try positionals.append(p);
739739
}
740740

741-
if (comp.compiler_rt_static_lib.crt_lib_file) |lib| {
741+
if (comp.compiler_rt_lib) |lib| {
742742
try positionals.append(lib.full_object_path);
743743
}
744744

src/link/Wasm.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2255,7 +2255,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
22552255
const is_obj = self.base.options.output_mode == .Obj;
22562256

22572257
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_path
2258+
comp.compiler_rt_lib.?.full_object_path
22592259
else
22602260
null;
22612261

0 commit comments

Comments
 (0)