authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-16 20:23:22-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-17 16:38:59-07:00
log5cd548e53081428d0e6b4a6b5a305317052c133a
tree4beb45ef87a73007a11e004a2fc52e35d8a6dc8e
parentb4f3e69342d176ad7a2572cf4fee704094faaada

Compilation: multi-thread compiler-rt

compiler_rt_lib and compiler_rt_obj are extracted from the generic JobQueue into simple boolean flags, and then handled explicitly inside performAllTheWork(). Introduced generic handling of allocation failure and made setMiscFailure not return a possible error. Building the compiler-rt static library now takes advantage of Compilation's ThreadPool. This introduced a problem, however, because now each of the object files of compiler-rt all perform AstGen for the full standard library and compiler-rt files. Even though all of them end up being cache hits except for the first ones, this is wasteful - O(N*M) where N is number of compilation units inside compiler-rt and M is the number of .zig files in the standard library and compiler-rt combined. More importantly, however, it causes a deadlock, because each thread interacts with a file system lock for doing AstGen on files, and threads end up waiting for each other. This will need to be handled with a process-level file caching system, or some other creative solution.

4 files changed, 528 insertions(+), 390 deletions(-)

src/Compilation.zig+115-78
...@@ -93,6 +93,9 @@ unwind_tables: bool,...@@ -93,6 +93,9 @@ unwind_tables: bool,
93test_evented_io: bool,93test_evented_io: bool,
94debug_compiler_runtime_libs: bool,94debug_compiler_runtime_libs: bool,
95debug_compile_errors: bool,95debug_compile_errors: bool,
96job_queued_compiler_rt_lib: bool = false,
97job_queued_compiler_rt_obj: bool = false,
98alloc_failure_occurred: bool = false,
9699
97c_source_files: []const CSourceFile,100c_source_files: []const CSourceFile,
98clang_argv: []const []const u8,101clang_argv: []const []const u8,
...@@ -130,11 +133,11 @@ libssp_static_lib: ?CRTFile = null,...@@ -130,11 +133,11 @@ libssp_static_lib: ?CRTFile = null,
130/// Populated when we build the libc static library. A Job to build this is placed in the queue133/// Populated when we build the libc static library. A Job to build this is placed in the queue
131/// and resolved before calling linker.flush().134/// and resolved before calling linker.flush().
132libc_static_lib: ?CRTFile = null,135libc_static_lib: ?CRTFile = null,
133/// Populated when we build the libcompiler_rt static library. A Job to build this is placed in the queue136/// Populated when we build the libcompiler_rt static library. A Job to build this is indicated
134/// and resolved before calling linker.flush().137/// by setting `job_queued_compiler_rt_lib` and resolved before calling linker.flush().
135compiler_rt_lib: ?CRTFile = null,138compiler_rt_lib: ?CRTFile = null,
136/// Populated when we build the compiler_rt_obj object. A Job to build this is placed in the queue139/// Populated when we build the compiler_rt_obj object. A Job to build this is indicated
137/// and resolved before calling linker.flush().140/// by setting `job_queued_compiler_rt_obj` and resolved before calling linker.flush().
138compiler_rt_obj: ?CRTFile = null,141compiler_rt_obj: ?CRTFile = null,
139142
140glibc_so_files: ?glibc.BuiltSharedObjects = null,143glibc_so_files: ?glibc.BuiltSharedObjects = null,
...@@ -224,8 +227,6 @@ const Job = union(enum) {...@@ -224,8 +227,6 @@ const Job = union(enum) {
224 libcxxabi: void,227 libcxxabi: void,
225 libtsan: void,228 libtsan: void,
226 libssp: void,229 libssp: void,
227 compiler_rt_lib: void,
228 compiler_rt_obj: void,
229 /// needed when not linking libc and using LLVM for code generation because it generates230 /// needed when not linking libc and using LLVM for code generation because it generates
230 /// calls to, for example, memcpy and memset.231 /// calls to, for example, memcpy and memset.
231 zig_libc: void,232 zig_libc: void,
...@@ -1925,13 +1926,13 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1925,13 +1926,13 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1925 if (comp.bin_file.options.include_compiler_rt and capable_of_building_compiler_rt) {1926 if (comp.bin_file.options.include_compiler_rt and capable_of_building_compiler_rt) {
1926 if (is_exe_or_dyn_lib) {1927 if (is_exe_or_dyn_lib) {
1927 log.debug("queuing a job to build compiler_rt_lib", .{});1928 log.debug("queuing a job to build compiler_rt_lib", .{});
1928 try comp.work_queue.writeItem(.{ .compiler_rt_lib = {} });1929 comp.job_queued_compiler_rt_lib = true;
1929 } else if (options.output_mode != .Obj) {1930 } else if (options.output_mode != .Obj) {
1930 log.debug("queuing a job to build compiler_rt_obj", .{});1931 log.debug("queuing a job to build compiler_rt_obj", .{});
1931 // If build-obj with -fcompiler-rt is requested, that is handled specially1932 // If build-obj with -fcompiler-rt is requested, that is handled specially
1932 // elsewhere. In this case we are making a static library, so we ask1933 // elsewhere. In this case we are making a static library, so we ask
1933 // for a compiler-rt object to put in it.1934 // for a compiler-rt object to put in it.
1934 try comp.work_queue.writeItem(.{ .compiler_rt_obj = {} });1935 comp.job_queued_compiler_rt_obj = true;
1935 }1936 }
1936 }1937 }
1937 if (needs_c_symbols) {1938 if (needs_c_symbols) {
...@@ -2021,6 +2022,7 @@ pub fn destroy(self: *Compilation) void {...@@ -2021,6 +2022,7 @@ pub fn destroy(self: *Compilation) void {
2021}2022}
20222023
2023pub fn clearMiscFailures(comp: *Compilation) void {2024pub fn clearMiscFailures(comp: *Compilation) void {
2025 comp.alloc_failure_occurred = false;
2024 for (comp.misc_failures.values()) |*value| {2026 for (comp.misc_failures.values()) |*value| {
2025 value.deinit(comp.gpa);2027 value.deinit(comp.gpa);
2026 }2028 }
...@@ -2533,8 +2535,10 @@ pub fn makeBinFileWritable(self: *Compilation) !void {...@@ -2533,8 +2535,10 @@ pub fn makeBinFileWritable(self: *Compilation) !void {
2533 return self.bin_file.makeWritable();2535 return self.bin_file.makeWritable();
2534}2536}
25352537
2538/// This function is temporally single-threaded.
2536pub fn totalErrorCount(self: *Compilation) usize {2539pub fn totalErrorCount(self: *Compilation) usize {
2537 var total: usize = self.failed_c_objects.count() + self.misc_failures.count();2540 var total: usize = self.failed_c_objects.count() + self.misc_failures.count() +
2541 @boolToInt(self.alloc_failure_occurred);
25382542
2539 if (self.bin_file.options.module) |module| {2543 if (self.bin_file.options.module) |module| {
2540 total += module.failed_exports.count();2544 total += module.failed_exports.count();
...@@ -2591,6 +2595,7 @@ pub fn totalErrorCount(self: *Compilation) usize {...@@ -2591,6 +2595,7 @@ pub fn totalErrorCount(self: *Compilation) usize {
2591 return total;2595 return total;
2592}2596}
25932597
2598/// This function is temporally single-threaded.
2594pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {2599pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
2595 var arena = std.heap.ArenaAllocator.init(self.gpa);2600 var arena = std.heap.ArenaAllocator.init(self.gpa);
2596 errdefer arena.deinit();2601 errdefer arena.deinit();
...@@ -2623,6 +2628,9 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {...@@ -2623,6 +2628,9 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
2623 for (self.misc_failures.values()) |*value| {2628 for (self.misc_failures.values()) |*value| {
2624 try AllErrors.addPlainWithChildren(&arena, &errors, value.msg, value.children);2629 try AllErrors.addPlainWithChildren(&arena, &errors, value.msg, value.children);
2625 }2630 }
2631 if (self.alloc_failure_occurred) {
2632 try AllErrors.addPlain(&arena, &errors, "memory allocation failure");
2633 }
2626 if (self.bin_file.options.module) |module| {2634 if (self.bin_file.options.module) |module| {
2627 {2635 {
2628 var it = module.failed_files.iterator();2636 var it = module.failed_files.iterator();
...@@ -2737,9 +2745,15 @@ pub fn performAllTheWork(...@@ -2737,9 +2745,15 @@ pub fn performAllTheWork(
2737 var embed_file_prog_node = main_progress_node.start("Detect @embedFile updates", comp.embed_file_work_queue.count);2745 var embed_file_prog_node = main_progress_node.start("Detect @embedFile updates", comp.embed_file_work_queue.count);
2738 defer embed_file_prog_node.end();2746 defer embed_file_prog_node.end();
27392747
2748 // +1 for the link step
2749 var compiler_rt_prog_node = main_progress_node.start("compiler_rt", compiler_rt.sources.len + 1);
2750 defer compiler_rt_prog_node.end();
2751
2740 comp.work_queue_wait_group.reset();2752 comp.work_queue_wait_group.reset();
2741 defer comp.work_queue_wait_group.wait();2753 defer comp.work_queue_wait_group.wait();
27422754
2755 const use_stage1 = build_options.is_stage1 and comp.bin_file.options.use_stage1;
2756
2743 {2757 {
2744 const astgen_frame = tracy.namedFrame("astgen");2758 const astgen_frame = tracy.namedFrame("astgen");
2745 defer astgen_frame.end();2759 defer astgen_frame.end();
...@@ -2782,9 +2796,28 @@ pub fn performAllTheWork(...@@ -2782,9 +2796,28 @@ pub fn performAllTheWork(
2782 comp, c_object, &c_obj_prog_node, &comp.work_queue_wait_group,2796 comp, c_object, &c_obj_prog_node, &comp.work_queue_wait_group,
2783 });2797 });
2784 }2798 }
2799
2800 if (comp.job_queued_compiler_rt_lib) {
2801 comp.job_queued_compiler_rt_lib = false;
2802
2803 if (use_stage1) {
2804 // stage1 LLVM backend uses the global context and thus cannot be used in
2805 // a multi-threaded context.
2806 buildCompilerRtOneShot(comp, .Lib, &comp.compiler_rt_lib);
2807 } else {
2808 comp.work_queue_wait_group.start();
2809 try comp.thread_pool.spawn(workerBuildCompilerRtLib, .{
2810 comp, &compiler_rt_prog_node, &comp.work_queue_wait_group,
2811 });
2812 }
2813 }
2814
2815 if (comp.job_queued_compiler_rt_obj) {
2816 comp.job_queued_compiler_rt_obj = false;
2817 buildCompilerRtOneShot(comp, .Obj, &comp.compiler_rt_obj);
2818 }
2785 }2819 }
27862820
2787 const use_stage1 = build_options.is_stage1 and comp.bin_file.options.use_stage1;
2788 if (!use_stage1) {2821 if (!use_stage1) {
2789 const outdated_and_deleted_decls_frame = tracy.namedFrame("outdated_and_deleted_decls");2822 const outdated_and_deleted_decls_frame = tracy.namedFrame("outdated_and_deleted_decls");
2790 defer outdated_and_deleted_decls_frame.end();2823 defer outdated_and_deleted_decls_frame.end();
...@@ -2997,7 +3030,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -2997,7 +3030,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
2997 module.semaPkg(pkg) catch |err| switch (err) {3030 module.semaPkg(pkg) catch |err| switch (err) {
2998 error.CurrentWorkingDirectoryUnlinked,3031 error.CurrentWorkingDirectoryUnlinked,
2999 error.Unexpected,3032 error.Unexpected,
3000 => try comp.setMiscFailure(3033 => comp.lockAndSetMiscFailure(
3001 .analyze_pkg,3034 .analyze_pkg,
3002 "unexpected problem analyzing package '{s}'",3035 "unexpected problem analyzing package '{s}'",
3003 .{pkg.root_src_path},3036 .{pkg.root_src_path},
...@@ -3012,7 +3045,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -3012,7 +3045,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
30123045
3013 glibc.buildCRTFile(comp, crt_file) catch |err| {3046 glibc.buildCRTFile(comp, crt_file) catch |err| {
3014 // TODO Surface more error details.3047 // TODO Surface more error details.
3015 try comp.setMiscFailure(.glibc_crt_file, "unable to build glibc CRT file: {s}", .{3048 comp.lockAndSetMiscFailure(.glibc_crt_file, "unable to build glibc CRT file: {s}", .{
3016 @errorName(err),3049 @errorName(err),
3017 });3050 });
3018 };3051 };
...@@ -3023,7 +3056,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -3023,7 +3056,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
30233056
3024 glibc.buildSharedObjects(comp) catch |err| {3057 glibc.buildSharedObjects(comp) catch |err| {
3025 // TODO Surface more error details.3058 // TODO Surface more error details.
3026 try comp.setMiscFailure(3059 comp.lockAndSetMiscFailure(
3027 .glibc_shared_objects,3060 .glibc_shared_objects,
3028 "unable to build glibc shared objects: {s}",3061 "unable to build glibc shared objects: {s}",
3029 .{@errorName(err)},3062 .{@errorName(err)},
...@@ -3036,7 +3069,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -3036,7 +3069,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
30363069
3037 musl.buildCRTFile(comp, crt_file) catch |err| {3070 musl.buildCRTFile(comp, crt_file) catch |err| {
3038 // TODO Surface more error details.3071 // TODO Surface more error details.
3039 try comp.setMiscFailure(3072 comp.lockAndSetMiscFailure(
3040 .musl_crt_file,3073 .musl_crt_file,
3041 "unable to build musl CRT file: {s}",3074 "unable to build musl CRT file: {s}",
3042 .{@errorName(err)},3075 .{@errorName(err)},
...@@ -3049,7 +3082,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -3049,7 +3082,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
30493082
3050 mingw.buildCRTFile(comp, crt_file) catch |err| {3083 mingw.buildCRTFile(comp, crt_file) catch |err| {
3051 // TODO Surface more error details.3084 // TODO Surface more error details.
3052 try comp.setMiscFailure(3085 comp.lockAndSetMiscFailure(
3053 .mingw_crt_file,3086 .mingw_crt_file,
3054 "unable to build mingw-w64 CRT file: {s}",3087 "unable to build mingw-w64 CRT file: {s}",
3055 .{@errorName(err)},3088 .{@errorName(err)},
...@@ -3063,7 +3096,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -3063,7 +3096,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
3063 const link_lib = comp.bin_file.options.system_libs.keys()[index];3096 const link_lib = comp.bin_file.options.system_libs.keys()[index];
3064 mingw.buildImportLib(comp, link_lib) catch |err| {3097 mingw.buildImportLib(comp, link_lib) catch |err| {
3065 // TODO Surface more error details.3098 // TODO Surface more error details.
3066 try comp.setMiscFailure(3099 comp.lockAndSetMiscFailure(
3067 .windows_import_lib,3100 .windows_import_lib,
3068 "unable to generate DLL import .lib file: {s}",3101 "unable to generate DLL import .lib file: {s}",
3069 .{@errorName(err)},3102 .{@errorName(err)},
...@@ -3076,7 +3109,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -3076,7 +3109,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
30763109
3077 libunwind.buildStaticLib(comp) catch |err| {3110 libunwind.buildStaticLib(comp) catch |err| {
3078 // TODO Surface more error details.3111 // TODO Surface more error details.
3079 try comp.setMiscFailure(3112 comp.lockAndSetMiscFailure(
3080 .libunwind,3113 .libunwind,
3081 "unable to build libunwind: {s}",3114 "unable to build libunwind: {s}",
3082 .{@errorName(err)},3115 .{@errorName(err)},
...@@ -3089,7 +3122,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -3089,7 +3122,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
30893122
3090 libcxx.buildLibCXX(comp) catch |err| {3123 libcxx.buildLibCXX(comp) catch |err| {
3091 // TODO Surface more error details.3124 // TODO Surface more error details.
3092 try comp.setMiscFailure(3125 comp.lockAndSetMiscFailure(
3093 .libcxx,3126 .libcxx,
3094 "unable to build libcxx: {s}",3127 "unable to build libcxx: {s}",
3095 .{@errorName(err)},3128 .{@errorName(err)},
...@@ -3102,7 +3135,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -3102,7 +3135,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
31023135
3103 libcxx.buildLibCXXABI(comp) catch |err| {3136 libcxx.buildLibCXXABI(comp) catch |err| {
3104 // TODO Surface more error details.3137 // TODO Surface more error details.
3105 try comp.setMiscFailure(3138 comp.lockAndSetMiscFailure(
3106 .libcxxabi,3139 .libcxxabi,
3107 "unable to build libcxxabi: {s}",3140 "unable to build libcxxabi: {s}",
3108 .{@errorName(err)},3141 .{@errorName(err)},
...@@ -3115,7 +3148,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -3115,7 +3148,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
31153148
3116 libtsan.buildTsan(comp) catch |err| {3149 libtsan.buildTsan(comp) catch |err| {
3117 // TODO Surface more error details.3150 // TODO Surface more error details.
3118 try comp.setMiscFailure(3151 comp.lockAndSetMiscFailure(
3119 .libtsan,3152 .libtsan,
3120 "unable to build TSAN library: {s}",3153 "unable to build TSAN library: {s}",
3121 .{@errorName(err)},3154 .{@errorName(err)},
...@@ -3128,49 +3161,13 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -3128,49 +3161,13 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
31283161
3129 wasi_libc.buildCRTFile(comp, crt_file) catch |err| {3162 wasi_libc.buildCRTFile(comp, crt_file) catch |err| {
3130 // TODO Surface more error details.3163 // TODO Surface more error details.
3131 try comp.setMiscFailure(3164 comp.lockAndSetMiscFailure(
3132 .wasi_libc_crt_file,3165 .wasi_libc_crt_file,
3133 "unable to build WASI libc CRT file: {s}",3166 "unable to build WASI libc CRT file: {s}",
3134 .{@errorName(err)},3167 .{@errorName(err)},
3135 );3168 );
3136 };3169 };
3137 },3170 },
3138 .compiler_rt_lib => {
3139 const named_frame = tracy.namedFrame("compiler_rt_lib");
3140 defer named_frame.end();
3141
3142 compiler_rt.buildCompilerRtLib(
3143 comp,
3144 &comp.compiler_rt_lib,
3145 ) catch |err| switch (err) {
3146 error.OutOfMemory => return error.OutOfMemory,
3147 error.SubCompilationFailed => return, // error reported already
3148 else => try comp.setMiscFailure(
3149 .compiler_rt,
3150 "unable to build compiler_rt: {s}",
3151 .{@errorName(err)},
3152 ),
3153 };
3154 },
3155 .compiler_rt_obj => {
3156 const named_frame = tracy.namedFrame("compiler_rt_obj");
3157 defer named_frame.end();
3158
3159 comp.buildOutputFromZig(
3160 "compiler_rt.zig",
3161 .Obj,
3162 &comp.compiler_rt_obj,
3163 .compiler_rt,
3164 ) catch |err| switch (err) {
3165 error.OutOfMemory => return error.OutOfMemory,
3166 error.SubCompilationFailed => return, // error reported already
3167 else => try comp.setMiscFailure(
3168 .compiler_rt,
3169 "unable to build compiler_rt: {s}",
3170 .{@errorName(err)},
3171 ),
3172 };
3173 },
3174 .libssp => {3171 .libssp => {
3175 const named_frame = tracy.namedFrame("libssp");3172 const named_frame = tracy.namedFrame("libssp");
3176 defer named_frame.end();3173 defer named_frame.end();
...@@ -3183,7 +3180,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -3183,7 +3180,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
3183 ) catch |err| switch (err) {3180 ) catch |err| switch (err) {
3184 error.OutOfMemory => return error.OutOfMemory,3181 error.OutOfMemory => return error.OutOfMemory,
3185 error.SubCompilationFailed => return, // error reported already3182 error.SubCompilationFailed => return, // error reported already
3186 else => try comp.setMiscFailure(3183 else => comp.lockAndSetMiscFailure(
3187 .libssp,3184 .libssp,
3188 "unable to build libssp: {s}",3185 "unable to build libssp: {s}",
3189 .{@errorName(err)},3186 .{@errorName(err)},
...@@ -3202,7 +3199,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -3202,7 +3199,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
3202 ) catch |err| switch (err) {3199 ) catch |err| switch (err) {
3203 error.OutOfMemory => return error.OutOfMemory,3200 error.OutOfMemory => return error.OutOfMemory,
3204 error.SubCompilationFailed => return, // error reported already3201 error.SubCompilationFailed => return, // error reported already
3205 else => try comp.setMiscFailure(3202 else => comp.lockAndSetMiscFailure(
3206 .zig_libc,3203 .zig_libc,
3207 "unable to build zig's multitarget libc: {s}",3204 "unable to build zig's multitarget libc: {s}",
3208 .{@errorName(err)},3205 .{@errorName(err)},
...@@ -3306,11 +3303,7 @@ fn workerUpdateBuiltinZigFile(...@@ -3306,11 +3303,7 @@ fn workerUpdateBuiltinZigFile(
33063303
3307 comp.setMiscFailure(.write_builtin_zig, "unable to write builtin.zig to {s}: {s}", .{3304 comp.setMiscFailure(.write_builtin_zig, "unable to write builtin.zig to {s}: {s}", .{
3308 dir_path, @errorName(err),3305 dir_path, @errorName(err),
3309 }) catch |oom| switch (oom) {3306 });
3310 error.OutOfMemory => log.err("unable to write builtin.zig to {s}: {s}", .{
3311 dir_path, @errorName(err),
3312 }),
3313 };
3314 };3307 };
3315}3308}
33163309
...@@ -3524,6 +3517,38 @@ fn workerUpdateCObject(...@@ -3524,6 +3517,38 @@ fn workerUpdateCObject(
3524 };3517 };
3525}3518}
35263519
3520fn buildCompilerRtOneShot(
3521 comp: *Compilation,
3522 output_mode: std.builtin.OutputMode,
3523 out: *?CRTFile,
3524) void {
3525 comp.buildOutputFromZig("compiler_rt.zig", output_mode, out, .compiler_rt) catch |err| switch (err) {
3526 error.SubCompilationFailed => return, // error reported already
3527 else => comp.lockAndSetMiscFailure(
3528 .compiler_rt,
3529 "unable to build compiler_rt: {s}",
3530 .{@errorName(err)},
3531 ),
3532 };
3533}
3534
3535fn workerBuildCompilerRtLib(
3536 comp: *Compilation,
3537 progress_node: *std.Progress.Node,
3538 wg: *WaitGroup,
3539) void {
3540 defer wg.finish();
3541
3542 compiler_rt.buildCompilerRtLib(comp, progress_node) catch |err| switch (err) {
3543 error.SubCompilationFailed => return, // error reported already
3544 else => comp.lockAndSetMiscFailure(
3545 .compiler_rt,
3546 "unable to build compiler_rt: {s}",
3547 .{@errorName(err)},
3548 ),
3549 };
3550}
3551
3527fn reportRetryableCObjectError(3552fn reportRetryableCObjectError(
3528 comp: *Compilation,3553 comp: *Compilation,
3529 c_object: *CObject,3554 c_object: *CObject,
...@@ -4622,14 +4647,21 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {...@@ -4622,14 +4647,21 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {
4622 comp.bin_file.options.object_format != .c;4647 comp.bin_file.options.object_format != .c;
4623}4648}
46244649
4625fn setMiscFailure(4650fn setAllocFailure(comp: *Compilation) void {
4651 log.debug("memory allocation failure", .{});
4652 comp.alloc_failure_occurred = true;
4653}
4654
4655/// Assumes that Compilation mutex is locked.
4656/// See also `lockAndSetMiscFailure`.
4657pub fn setMiscFailure(
4626 comp: *Compilation,4658 comp: *Compilation,
4627 tag: MiscTask,4659 tag: MiscTask,
4628 comptime format: []const u8,4660 comptime format: []const u8,
4629 args: anytype,4661 args: anytype,
4630) Allocator.Error!void {4662) void {
4631 try comp.misc_failures.ensureUnusedCapacity(comp.gpa, 1);4663 comp.misc_failures.ensureUnusedCapacity(comp.gpa, 1) catch return comp.setAllocFailure();
4632 const msg = try std.fmt.allocPrint(comp.gpa, format, args);4664 const msg = std.fmt.allocPrint(comp.gpa, format, args) catch return comp.setAllocFailure();
4633 const gop = comp.misc_failures.getOrPutAssumeCapacity(tag);4665 const gop = comp.misc_failures.getOrPutAssumeCapacity(tag);
4634 if (gop.found_existing) {4666 if (gop.found_existing) {
4635 gop.value_ptr.deinit(comp.gpa);4667 gop.value_ptr.deinit(comp.gpa);
...@@ -4637,6 +4669,19 @@ fn setMiscFailure(...@@ -4637,6 +4669,19 @@ fn setMiscFailure(
4637 gop.value_ptr.* = .{ .msg = msg };4669 gop.value_ptr.* = .{ .msg = msg };
4638}4670}
46394671
4672/// See also `setMiscFailure`.
4673pub fn lockAndSetMiscFailure(
4674 comp: *Compilation,
4675 tag: MiscTask,
4676 comptime format: []const u8,
4677 args: anytype,
4678) void {
4679 comp.mutex.lock();
4680 defer comp.mutex.unlock();
4681
4682 return setMiscFailure(comp, tag, format, args);
4683}
4684
4640pub fn dump_argv(argv: []const []const u8) void {4685pub fn dump_argv(argv: []const []const u8) void {
4641 for (argv[0 .. argv.len - 1]) |arg| {4686 for (argv[0 .. argv.len - 1]) |arg| {
4642 std.debug.print("{s} ", .{arg});4687 std.debug.print("{s} ", .{arg});
...@@ -4896,7 +4941,7 @@ pub fn updateSubCompilation(sub_compilation: *Compilation) !void {...@@ -4896,7 +4941,7 @@ pub fn updateSubCompilation(sub_compilation: *Compilation) !void {
4896 }4941 }
4897}4942}
48984943
4899pub fn buildOutputFromZig(4944fn buildOutputFromZig(
4900 comp: *Compilation,4945 comp: *Compilation,
4901 src_basename: []const u8,4946 src_basename: []const u8,
4902 output_mode: std.builtin.OutputMode,4947 output_mode: std.builtin.OutputMode,
...@@ -4913,15 +4958,7 @@ pub fn buildOutputFromZig(...@@ -4913,15 +4958,7 @@ pub fn buildOutputFromZig(
4913 .root_src_path = src_basename,4958 .root_src_path = src_basename,
4914 };4959 };
4915 defer main_pkg.deinitTable(comp.gpa);4960 defer main_pkg.deinitTable(comp.gpa);
49164961 const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len];
4917 const root_name = root_name: {
4918 const basename = if (std.fs.path.dirname(src_basename)) |dirname|
4919 src_basename[dirname.len + 1 ..]
4920 else
4921 src_basename;
4922 const root_name = basename[0 .. basename.len - std.fs.path.extension(basename).len];
4923 break :root_name root_name;
4924 };
4925 const target = comp.getTarget();4962 const target = comp.getTarget();
4926 const bin_basename = try std.zig.binNameAlloc(comp.gpa, .{4963 const bin_basename = try std.zig.binNameAlloc(comp.gpa, .{
4927 .root_name = root_name,4964 .root_name = root_name,
src/ThreadPool.zig+49-32
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const ThreadPool = @This();3const ThreadPool = @This();
4const WaitGroup = @import("WaitGroup.zig");
45
5mutex: std.Thread.Mutex = .{},6mutex: std.Thread.Mutex = .{},
6cond: std.Thread.Condition = .{},7cond: std.Thread.Condition = .{},
...@@ -19,8 +20,8 @@ const RunProto = switch (builtin.zig_backend) {...@@ -19,8 +20,8 @@ const RunProto = switch (builtin.zig_backend) {
19 else => *const fn (*Runnable) void,20 else => *const fn (*Runnable) void,
20};21};
2122
22pub fn init(self: *ThreadPool, allocator: std.mem.Allocator) !void {23pub fn init(pool: *ThreadPool, allocator: std.mem.Allocator) !void {
23 self.* = .{24 pool.* = .{
24 .allocator = allocator,25 .allocator = allocator,
25 .threads = &[_]std.Thread{},26 .threads = &[_]std.Thread{},
26 };27 };
...@@ -30,48 +31,48 @@ pub fn init(self: *ThreadPool, allocator: std.mem.Allocator) !void {...@@ -30,48 +31,48 @@ pub fn init(self: *ThreadPool, allocator: std.mem.Allocator) !void {
30 }31 }
3132
32 const thread_count = std.math.max(1, std.Thread.getCpuCount() catch 1);33 const thread_count = std.math.max(1, std.Thread.getCpuCount() catch 1);
33 self.threads = try allocator.alloc(std.Thread, thread_count);34 pool.threads = try allocator.alloc(std.Thread, thread_count);
34 errdefer allocator.free(self.threads);35 errdefer allocator.free(pool.threads);
3536
36 // kill and join any threads we spawned previously on error.37 // kill and join any threads we spawned previously on error.
37 var spawned: usize = 0;38 var spawned: usize = 0;
38 errdefer self.join(spawned);39 errdefer pool.join(spawned);
3940
40 for (self.threads) |*thread| {41 for (pool.threads) |*thread| {
41 thread.* = try std.Thread.spawn(.{}, worker, .{self});42 thread.* = try std.Thread.spawn(.{}, worker, .{pool});
42 spawned += 1;43 spawned += 1;
43 }44 }
44}45}
4546
46pub fn deinit(self: *ThreadPool) void {47pub fn deinit(pool: *ThreadPool) void {
47 self.join(self.threads.len); // kill and join all threads.48 pool.join(pool.threads.len); // kill and join all threads.
48 self.* = undefined;49 pool.* = undefined;
49}50}
5051
51fn join(self: *ThreadPool, spawned: usize) void {52fn join(pool: *ThreadPool, spawned: usize) void {
52 if (builtin.single_threaded) {53 if (builtin.single_threaded) {
53 return;54 return;
54 }55 }
5556
56 {57 {
57 self.mutex.lock();58 pool.mutex.lock();
58 defer self.mutex.unlock();59 defer pool.mutex.unlock();
5960
60 // ensure future worker threads exit the dequeue loop61 // ensure future worker threads exit the dequeue loop
61 self.is_running = false;62 pool.is_running = false;
62 }63 }
6364
64 // wake up any sleeping threads (this can be done outside the mutex)65 // wake up any sleeping threads (this can be done outside the mutex)
65 // then wait for all the threads we know are spawned to complete.66 // then wait for all the threads we know are spawned to complete.
66 self.cond.broadcast();67 pool.cond.broadcast();
67 for (self.threads[0..spawned]) |thread| {68 for (pool.threads[0..spawned]) |thread| {
68 thread.join();69 thread.join();
69 }70 }
7071
71 self.allocator.free(self.threads);72 pool.allocator.free(pool.threads);
72}73}
7374
74pub fn spawn(self: *ThreadPool, comptime func: anytype, args: anytype) !void {75pub fn spawn(pool: *ThreadPool, comptime func: anytype, args: anytype) !void {
75 if (builtin.single_threaded) {76 if (builtin.single_threaded) {
76 @call(.{}, func, args);77 @call(.{}, func, args);
77 return;78 return;
...@@ -98,41 +99,57 @@ pub fn spawn(self: *ThreadPool, comptime func: anytype, args: anytype) !void {...@@ -98,41 +99,57 @@ pub fn spawn(self: *ThreadPool, comptime func: anytype, args: anytype) !void {
98 };99 };
99100
100 {101 {
101 self.mutex.lock();102 pool.mutex.lock();
102 defer self.mutex.unlock();103 defer pool.mutex.unlock();
103104
104 const closure = try self.allocator.create(Closure);105 const closure = try pool.allocator.create(Closure);
105 closure.* = .{106 closure.* = .{
106 .arguments = args,107 .arguments = args,
107 .pool = self,108 .pool = pool,
108 };109 };
109110
110 self.run_queue.prepend(&closure.run_node);111 pool.run_queue.prepend(&closure.run_node);
111 }112 }
112113
113 // Notify waiting threads outside the lock to try and keep the critical section small.114 // Notify waiting threads outside the lock to try and keep the critical section small.
114 self.cond.signal();115 pool.cond.signal();
115}116}
116117
117fn worker(self: *ThreadPool) void {118fn worker(pool: *ThreadPool) void {
118 self.mutex.lock();119 pool.mutex.lock();
119 defer self.mutex.unlock();120 defer pool.mutex.unlock();
120121
121 while (true) {122 while (true) {
122 while (self.run_queue.popFirst()) |run_node| {123 while (pool.run_queue.popFirst()) |run_node| {
123 // Temporarily unlock the mutex in order to execute the run_node124 // Temporarily unlock the mutex in order to execute the run_node
124 self.mutex.unlock();125 pool.mutex.unlock();
125 defer self.mutex.lock();126 defer pool.mutex.lock();
126127
127 const runFn = run_node.data.runFn;128 const runFn = run_node.data.runFn;
128 runFn(&run_node.data);129 runFn(&run_node.data);
129 }130 }
130131
131 // Stop executing instead of waiting if the thread pool is no longer running.132 // Stop executing instead of waiting if the thread pool is no longer running.
132 if (self.is_running) {133 if (pool.is_running) {
133 self.cond.wait(&self.mutex);134 pool.cond.wait(&pool.mutex);
134 } else {135 } else {
135 break;136 break;
136 }137 }
137 }138 }
138}139}
140
141pub fn waitAndWork(pool: *ThreadPool, wait_group: *WaitGroup) void {
142 while (!wait_group.isDone()) {
143 if (blk: {
144 pool.mutex.lock();
145 defer pool.mutex.unlock();
146 break :blk pool.run_queue.popFirst();
147 }) |run_node| {
148 run_node.data.runFn(&run_node.data);
149 continue;
150 }
151
152 wait_group.wait();
153 return;
154 }
155}
src/WaitGroup.zig+7
...@@ -37,3 +37,10 @@ pub fn reset(self: *WaitGroup) void {...@@ -37,3 +37,10 @@ pub fn reset(self: *WaitGroup) void {
37 self.state.store(0, .Monotonic);37 self.state.store(0, .Monotonic);
38 self.event.reset();38 self.event.reset();
39}39}
40
41pub fn isDone(wg: *WaitGroup) bool {
42 const state = wg.state.load(.Acquire);
43 assert(state & is_waiting == 0);
44
45 return (state / one_pending) == 0;
46}
src/compiler_rt.zig+357-280
...@@ -12,316 +12,393 @@ const Compilation = @import("Compilation.zig");...@@ -12,316 +12,393 @@ const Compilation = @import("Compilation.zig");
12const CRTFile = Compilation.CRTFile;12const CRTFile = Compilation.CRTFile;
13const LinkObject = Compilation.LinkObject;13const LinkObject = Compilation.LinkObject;
14const Package = @import("Package.zig");14const Package = @import("Package.zig");
15const WaitGroup = @import("WaitGroup.zig");
1516
16pub fn buildCompilerRtLib(comp: *Compilation, compiler_rt_lib: *?CRTFile) !void {17pub fn buildCompilerRtLib(comp: *Compilation, progress_node: *std.Progress.Node) !void {
17 const tracy_trace = trace(@src());
18 defer tracy_trace.end();
19
20 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);18 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
21 defer arena_allocator.deinit();19 defer arena_allocator.deinit();
22 const arena = arena_allocator.allocator();20 const arena = arena_allocator.allocator();
2321
24 const target = comp.getTarget();22 const target = comp.getTarget();
2523
26 // Use the global cache directory.24 const root_name = "compiler_rt";
27 var cache_parent: Cache = .{25 const basename = try std.zig.binNameAlloc(arena, .{
28 .gpa = comp.gpa,26 .root_name = root_name,
29 .manifest_dir = try comp.global_cache_directory.handle.makeOpenPath("h", .{}),27 .target = target,
28 .output_mode = .Lib,
29 });
30
31 var link_objects: [sources.len]LinkObject = undefined;
32 var crt_files = [1]?CRTFile{null} ** sources.len;
33 defer deinitCrtFiles(comp, crt_files);
34
35 {
36 var wg: WaitGroup = .{};
37 defer comp.thread_pool.waitAndWork(&wg);
38
39 for (sources) |source, i| {
40 wg.start();
41 try comp.thread_pool.spawn(workerBuildObject, .{
42 comp, progress_node, &wg, source, &crt_files[i],
43 });
44 }
45 }
46
47 for (link_objects) |*link_object, i| {
48 link_object.* = .{
49 .path = crt_files[i].?.full_object_path,
50 };
51 }
52
53 var link_progress_node = progress_node.start("link", 0);
54 link_progress_node.activate();
55 defer link_progress_node.end();
56
57 // TODO: This is extracted into a local variable to work around a stage1 miscompilation.
58 const emit_bin = Compilation.EmitLoc{
59 .directory = null, // Put it in the cache directory.
60 .basename = basename,
61 };
62 const sub_compilation = try Compilation.create(comp.gpa, .{
63 .local_cache_directory = comp.global_cache_directory,
64 .global_cache_directory = comp.global_cache_directory,
65 .zig_lib_directory = comp.zig_lib_directory,
66 .cache_mode = .whole,
67 .target = target,
68 .root_name = root_name,
69 .main_pkg = null,
70 .output_mode = .Lib,
71 .link_mode = .Static,
72 .thread_pool = comp.thread_pool,
73 .libc_installation = comp.bin_file.options.libc_installation,
74 .emit_bin = emit_bin,
75 .optimize_mode = comp.compilerRtOptMode(),
76 .want_sanitize_c = false,
77 .want_stack_check = false,
78 .want_red_zone = comp.bin_file.options.red_zone,
79 .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
80 .want_valgrind = false,
81 .want_tsan = false,
82 .want_pic = comp.bin_file.options.pic,
83 .want_pie = comp.bin_file.options.pie,
84 .want_lto = comp.bin_file.options.lto,
85 .emit_h = null,
86 .strip = comp.compilerRtStrip(),
87 .is_native_os = comp.bin_file.options.is_native_os,
88 .is_native_abi = comp.bin_file.options.is_native_abi,
89 .self_exe_path = comp.self_exe_path,
90 .link_objects = &link_objects,
91 .verbose_cc = comp.verbose_cc,
92 .verbose_link = comp.bin_file.options.verbose_link,
93 .verbose_air = comp.verbose_air,
94 .verbose_llvm_ir = comp.verbose_llvm_ir,
95 .verbose_cimport = comp.verbose_cimport,
96 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
97 .clang_passthrough_mode = comp.clang_passthrough_mode,
98 .skip_linker_dependencies = true,
99 .parent_compilation_link_libc = comp.bin_file.options.link_libc,
100 });
101 defer sub_compilation.destroy();
102
103 try sub_compilation.updateSubCompilation();
104
105 assert(comp.compiler_rt_lib == null);
106 comp.compiler_rt_lib = .{
107 .full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(comp.gpa, &[_][]const u8{
108 sub_compilation.bin_file.options.emit.?.sub_path,
109 }),
110 .lock = sub_compilation.bin_file.toOwnedLock(),
30 };111 };
31 defer cache_parent.manifest_dir.close();112}
32113
33 var cache = cache_parent.obtain();114fn deinitCrtFiles(comp: *Compilation, crt_files: [sources.len]?CRTFile) void {
34 defer cache.deinit();115 const gpa = comp.gpa;
35116
36 cache.hash.add(sources.len);117 for (crt_files) |opt_crt_file| {
37 for (sources) |source| {118 var crt_file = opt_crt_file orelse continue;
38 const full_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{source});119 crt_file.deinit(gpa);
39 _ = try cache.addFile(full_path, null);
40 }120 }
121}
41122
42 cache.hash.addBytes(build_options.version);123fn workerBuildObject(
43 cache.hash.addBytes(comp.zig_lib_directory.path orelse ".");124 comp: *Compilation,
44 cache.hash.add(target.cpu.arch);125 progress_node: *std.Progress.Node,
45 cache.hash.add(target.os.tag);126 wg: *WaitGroup,
46 cache.hash.add(target.abi);127 src_basename: []const u8,
128 out: *?CRTFile,
129) void {
130 defer wg.finish();
47131
48 const hit = try cache.hit();132 var obj_progress_node = progress_node.start(src_basename, 0);
49 const digest = cache.final();133 obj_progress_node.activate();
50 const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });134 defer obj_progress_node.end();
51135
52 var o_directory: Compilation.Directory = .{136 buildObject(comp, src_basename, out) catch |err| switch (err) {
53 .handle = try comp.global_cache_directory.handle.makeOpenPath(o_sub_path, .{}),137 error.SubCompilationFailed => return, // error reported already
54 .path = try std.fs.path.join(arena, &[_][]const u8{ comp.global_cache_directory.path.?, o_sub_path }),138 else => comp.lockAndSetMiscFailure(
139 .compiler_rt,
140 "unable to build compiler_rt: {s}",
141 .{@errorName(err)},
142 ),
55 };143 };
56 defer o_directory.handle.close();144}
57145
58 const ok_basename = "ok";146fn buildObject(comp: *Compilation, src_basename: []const u8, out: *?CRTFile) !void {
59 const actual_hit = if (hit) blk: {147 const gpa = comp.gpa;
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;
66148
67 const root_name = "compiler_rt";149 var root_src_path_buf: [64]u8 = undefined;
68 const basename = try std.zig.binNameAlloc(arena, .{150 const root_src_path = std.fmt.bufPrint(
151 &root_src_path_buf,
152 "compiler_rt" ++ std.fs.path.sep_str ++ "{s}",
153 .{src_basename},
154 ) catch unreachable;
155
156 var main_pkg: Package = .{
157 .root_src_directory = comp.zig_lib_directory,
158 .root_src_path = root_src_path,
159 };
160 defer main_pkg.deinitTable(gpa);
161 const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len];
162 const target = comp.getTarget();
163 const output_mode: std.builtin.OutputMode = .Obj;
164 const bin_basename = try std.zig.binNameAlloc(gpa, .{
69 .root_name = root_name,165 .root_name = root_name,
70 .target = target,166 .target = target,
71 .output_mode = .Lib,167 .output_mode = output_mode,
72 });168 });
169 defer gpa.free(bin_basename);
73170
74 if (!actual_hit) {171 const emit_bin = Compilation.EmitLoc{
75 var progress: std.Progress = .{ .dont_print_on_dumb = true };172 .directory = null, // Put it in the cache directory.
76 var progress_node = progress.start("Compile Compiler-RT", sources.len + 1);173 .basename = bin_basename,
77 defer progress_node.end();174 };
78 if (comp.color == .off) progress.terminal = null;175 const sub_compilation = try Compilation.create(gpa, .{
79176 .global_cache_directory = comp.global_cache_directory,
80 progress_node.activate();177 .local_cache_directory = comp.global_cache_directory,
178 .zig_lib_directory = comp.zig_lib_directory,
179 .cache_mode = .whole,
180 .target = target,
181 .root_name = root_name,
182 .main_pkg = &main_pkg,
183 .output_mode = output_mode,
184 .thread_pool = comp.thread_pool,
185 .libc_installation = comp.bin_file.options.libc_installation,
186 .emit_bin = emit_bin,
187 .optimize_mode = comp.compilerRtOptMode(),
188 .link_mode = .Static,
189 .want_sanitize_c = false,
190 .want_stack_check = false,
191 .want_red_zone = comp.bin_file.options.red_zone,
192 .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
193 .want_valgrind = false,
194 .want_tsan = false,
195 .want_pic = comp.bin_file.options.pic,
196 .want_pie = comp.bin_file.options.pie,
197 .emit_h = null,
198 .strip = comp.compilerRtStrip(),
199 .is_native_os = comp.bin_file.options.is_native_os,
200 .is_native_abi = comp.bin_file.options.is_native_abi,
201 .self_exe_path = comp.self_exe_path,
202 .verbose_cc = comp.verbose_cc,
203 .verbose_link = comp.bin_file.options.verbose_link,
204 .verbose_air = comp.verbose_air,
205 .verbose_llvm_ir = comp.verbose_llvm_ir,
206 .verbose_cimport = comp.verbose_cimport,
207 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
208 .clang_passthrough_mode = comp.clang_passthrough_mode,
209 .skip_linker_dependencies = true,
210 .parent_compilation_link_libc = comp.bin_file.options.link_libc,
211 });
212 defer sub_compilation.destroy();
81213
82 var link_objects: [sources.len]LinkObject = undefined;214 try sub_compilation.update();
83 for (sources) |source, i| {215 // Look for compilation errors in this sub_compilation.
84 var obj_progress_node = progress_node.start(source, 0);216 var keep_errors = false;
85 obj_progress_node.activate();217 var errors = try sub_compilation.getAllErrorsAlloc();
86 defer obj_progress_node.end();218 defer if (!keep_errors) errors.deinit(sub_compilation.gpa);
87219
88 var tmp_crt_file: ?CRTFile = null;220 if (errors.list.len != 0) {
89 defer if (tmp_crt_file) |*crt| crt.deinit(comp.gpa);221 const misc_task_tag: Compilation.MiscTask = .compiler_rt;
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 }
96222
97 var lib_progress_node = progress_node.start(root_name, 0);223 comp.mutex.lock();
98 lib_progress_node.activate();224 defer comp.mutex.unlock();
99 defer lib_progress_node.end();
100225
101 // TODO: This is extracted into a local variable to work around a stage1 miscompilation.226 try comp.misc_failures.ensureUnusedCapacity(gpa, 1);
102 const emit_bin = Compilation.EmitLoc{227 comp.misc_failures.putAssumeCapacityNoClobber(misc_task_tag, .{
103 .directory = o_directory, // Put it in the cache directory.228 .msg = try std.fmt.allocPrint(gpa, "sub-compilation of {s} failed", .{
104 .basename = basename,229 @tagName(misc_task_tag),
105 };230 }),
106 const sub_compilation = try Compilation.create(comp.gpa, .{231 .children = errors,
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 .thread_pool = comp.thread_pool,
117 .libc_installation = comp.bin_file.options.libc_installation,
118 .emit_bin = emit_bin,
119 .optimize_mode = comp.compilerRtOptMode(),
120 .want_sanitize_c = false,
121 .want_stack_check = false,
122 .want_red_zone = comp.bin_file.options.red_zone,
123 .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
124 .want_valgrind = false,
125 .want_tsan = false,
126 .want_pic = comp.bin_file.options.pic,
127 .want_pie = comp.bin_file.options.pie,
128 .want_lto = comp.bin_file.options.lto,
129 .emit_h = null,
130 .strip = comp.compilerRtStrip(),
131 .is_native_os = comp.bin_file.options.is_native_os,
132 .is_native_abi = comp.bin_file.options.is_native_abi,
133 .self_exe_path = comp.self_exe_path,
134 .link_objects = &link_objects,
135 .verbose_cc = comp.verbose_cc,
136 .verbose_link = comp.bin_file.options.verbose_link,
137 .verbose_air = comp.verbose_air,
138 .verbose_llvm_ir = comp.verbose_llvm_ir,
139 .verbose_cimport = comp.verbose_cimport,
140 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
141 .clang_passthrough_mode = comp.clang_passthrough_mode,
142 .skip_linker_dependencies = true,
143 .parent_compilation_link_libc = comp.bin_file.options.link_libc,
144 });232 });
145 defer sub_compilation.destroy();233 keep_errors = true;
146234 return error.SubCompilationFailed;
147 try sub_compilation.updateSubCompilation();
148
149 if (o_directory.handle.createFile(ok_basename, .{})) |file| {
150 file.close();
151 } else |err| {
152 std.log.warn("compiler-rt lib: failed to mark completion: {s}", .{@errorName(err)});
153 }
154 }235 }
155236
156 try cache.writeManifest();237 assert(out.* == null);
157238 out.* = Compilation.CRTFile{
158 assert(compiler_rt_lib.* == null);239 .full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(gpa, &[_][]const u8{
159 compiler_rt_lib.* = .{240 sub_compilation.bin_file.options.emit.?.sub_path,
160 .full_object_path = try std.fs.path.join(comp.gpa, &[_][]const u8{
161 comp.global_cache_directory.path.?,
162 o_sub_path,
163 basename,
164 }),241 }),
165 .lock = cache.toOwnedLock(),242 .lock = sub_compilation.bin_file.toOwnedLock(),
166 };243 };
167}244}
168245
169const sources = &[_][]const u8{246pub const sources = &[_][]const u8{
170 "compiler_rt/absvdi2.zig",247 "absvdi2.zig",
171 "compiler_rt/absvsi2.zig",248 "absvsi2.zig",
172 "compiler_rt/absvti2.zig",249 "absvti2.zig",
173 "compiler_rt/adddf3.zig",250 "adddf3.zig",
174 "compiler_rt/addo.zig",251 "addo.zig",
175 "compiler_rt/addsf3.zig",252 "addsf3.zig",
176 "compiler_rt/addtf3.zig",253 "addtf3.zig",
177 "compiler_rt/addxf3.zig",254 "addxf3.zig",
178 "compiler_rt/arm.zig",255 "arm.zig",
179 "compiler_rt/atomics.zig",256 "atomics.zig",
180 "compiler_rt/aulldiv.zig",257 "aulldiv.zig",
181 "compiler_rt/aullrem.zig",258 "aullrem.zig",
182 "compiler_rt/bswap.zig",259 "bswap.zig",
183 "compiler_rt/ceil.zig",260 "ceil.zig",
184 "compiler_rt/clear_cache.zig",261 "clear_cache.zig",
185 "compiler_rt/cmp.zig",262 "cmp.zig",
186 "compiler_rt/cmpdf2.zig",263 "cmpdf2.zig",
187 "compiler_rt/cmpsf2.zig",264 "cmpsf2.zig",
188 "compiler_rt/cmptf2.zig",265 "cmptf2.zig",
189 "compiler_rt/cmpxf2.zig",266 "cmpxf2.zig",
190 "compiler_rt/cos.zig",267 "cos.zig",
191 "compiler_rt/count0bits.zig",268 "count0bits.zig",
192 "compiler_rt/divdf3.zig",269 "divdf3.zig",
193 "compiler_rt/divsf3.zig",270 "divsf3.zig",
194 "compiler_rt/divtf3.zig",271 "divtf3.zig",
195 "compiler_rt/divti3.zig",272 "divti3.zig",
196 "compiler_rt/divxf3.zig",273 "divxf3.zig",
197 "compiler_rt/emutls.zig",274 "emutls.zig",
198 "compiler_rt/exp.zig",275 "exp.zig",
199 "compiler_rt/exp2.zig",276 "exp2.zig",
200 "compiler_rt/extenddftf2.zig",277 "extenddftf2.zig",
201 "compiler_rt/extenddfxf2.zig",278 "extenddfxf2.zig",
202 "compiler_rt/extendhfsf2.zig",279 "extendhfsf2.zig",
203 "compiler_rt/extendhftf2.zig",280 "extendhftf2.zig",
204 "compiler_rt/extendhfxf2.zig",281 "extendhfxf2.zig",
205 "compiler_rt/extendsfdf2.zig",282 "extendsfdf2.zig",
206 "compiler_rt/extendsftf2.zig",283 "extendsftf2.zig",
207 "compiler_rt/extendsfxf2.zig",284 "extendsfxf2.zig",
208 "compiler_rt/extendxftf2.zig",285 "extendxftf2.zig",
209 "compiler_rt/fabs.zig",286 "fabs.zig",
210 "compiler_rt/fixdfdi.zig",287 "fixdfdi.zig",
211 "compiler_rt/fixdfsi.zig",288 "fixdfsi.zig",
212 "compiler_rt/fixdfti.zig",289 "fixdfti.zig",
213 "compiler_rt/fixhfdi.zig",290 "fixhfdi.zig",
214 "compiler_rt/fixhfsi.zig",291 "fixhfsi.zig",
215 "compiler_rt/fixhfti.zig",292 "fixhfti.zig",
216 "compiler_rt/fixsfdi.zig",293 "fixsfdi.zig",
217 "compiler_rt/fixsfsi.zig",294 "fixsfsi.zig",
218 "compiler_rt/fixsfti.zig",295 "fixsfti.zig",
219 "compiler_rt/fixtfdi.zig",296 "fixtfdi.zig",
220 "compiler_rt/fixtfsi.zig",297 "fixtfsi.zig",
221 "compiler_rt/fixtfti.zig",298 "fixtfti.zig",
222 "compiler_rt/fixunsdfdi.zig",299 "fixunsdfdi.zig",
223 "compiler_rt/fixunsdfsi.zig",300 "fixunsdfsi.zig",
224 "compiler_rt/fixunsdfti.zig",301 "fixunsdfti.zig",
225 "compiler_rt/fixunshfdi.zig",302 "fixunshfdi.zig",
226 "compiler_rt/fixunshfsi.zig",303 "fixunshfsi.zig",
227 "compiler_rt/fixunshfti.zig",304 "fixunshfti.zig",
228 "compiler_rt/fixunssfdi.zig",305 "fixunssfdi.zig",
229 "compiler_rt/fixunssfsi.zig",306 "fixunssfsi.zig",
230 "compiler_rt/fixunssfti.zig",307 "fixunssfti.zig",
231 "compiler_rt/fixunstfdi.zig",308 "fixunstfdi.zig",
232 "compiler_rt/fixunstfsi.zig",309 "fixunstfsi.zig",
233 "compiler_rt/fixunstfti.zig",310 "fixunstfti.zig",
234 "compiler_rt/fixunsxfdi.zig",311 "fixunsxfdi.zig",
235 "compiler_rt/fixunsxfsi.zig",312 "fixunsxfsi.zig",
236 "compiler_rt/fixunsxfti.zig",313 "fixunsxfti.zig",
237 "compiler_rt/fixxfdi.zig",314 "fixxfdi.zig",
238 "compiler_rt/fixxfsi.zig",315 "fixxfsi.zig",
239 "compiler_rt/fixxfti.zig",316 "fixxfti.zig",
240 "compiler_rt/floatdidf.zig",317 "floatdidf.zig",
241 "compiler_rt/floatdihf.zig",318 "floatdihf.zig",
242 "compiler_rt/floatdisf.zig",319 "floatdisf.zig",
243 "compiler_rt/floatditf.zig",320 "floatditf.zig",
244 "compiler_rt/floatdixf.zig",321 "floatdixf.zig",
245 "compiler_rt/floatsidf.zig",322 "floatsidf.zig",
246 "compiler_rt/floatsihf.zig",323 "floatsihf.zig",
247 "compiler_rt/floatsisf.zig",324 "floatsisf.zig",
248 "compiler_rt/floatsitf.zig",325 "floatsitf.zig",
249 "compiler_rt/floatsixf.zig",326 "floatsixf.zig",
250 "compiler_rt/floattidf.zig",327 "floattidf.zig",
251 "compiler_rt/floattihf.zig",328 "floattihf.zig",
252 "compiler_rt/floattisf.zig",329 "floattisf.zig",
253 "compiler_rt/floattitf.zig",330 "floattitf.zig",
254 "compiler_rt/floattixf.zig",331 "floattixf.zig",
255 "compiler_rt/floatundidf.zig",332 "floatundidf.zig",
256 "compiler_rt/floatundihf.zig",333 "floatundihf.zig",
257 "compiler_rt/floatundisf.zig",334 "floatundisf.zig",
258 "compiler_rt/floatunditf.zig",335 "floatunditf.zig",
259 "compiler_rt/floatundixf.zig",336 "floatundixf.zig",
260 "compiler_rt/floatunsidf.zig",337 "floatunsidf.zig",
261 "compiler_rt/floatunsihf.zig",338 "floatunsihf.zig",
262 "compiler_rt/floatunsisf.zig",339 "floatunsisf.zig",
263 "compiler_rt/floatunsitf.zig",340 "floatunsitf.zig",
264 "compiler_rt/floatunsixf.zig",341 "floatunsixf.zig",
265 "compiler_rt/floatuntidf.zig",342 "floatuntidf.zig",
266 "compiler_rt/floatuntihf.zig",343 "floatuntihf.zig",
267 "compiler_rt/floatuntisf.zig",344 "floatuntisf.zig",
268 "compiler_rt/floatuntitf.zig",345 "floatuntitf.zig",
269 "compiler_rt/floatuntixf.zig",346 "floatuntixf.zig",
270 "compiler_rt/floor.zig",347 "floor.zig",
271 "compiler_rt/fma.zig",348 "fma.zig",
272 "compiler_rt/fmax.zig",349 "fmax.zig",
273 "compiler_rt/fmin.zig",350 "fmin.zig",
274 "compiler_rt/fmod.zig",351 "fmod.zig",
275 "compiler_rt/gedf2.zig",352 "gedf2.zig",
276 "compiler_rt/gesf2.zig",353 "gesf2.zig",
277 "compiler_rt/getf2.zig",354 "getf2.zig",
278 "compiler_rt/gexf2.zig",355 "gexf2.zig",
279 "compiler_rt/int.zig",356 "int.zig",
280 "compiler_rt/log.zig",357 "log.zig",
281 "compiler_rt/log10.zig",358 "log10.zig",
282 "compiler_rt/log2.zig",359 "log2.zig",
283 "compiler_rt/modti3.zig",360 "modti3.zig",
284 "compiler_rt/muldf3.zig",361 "muldf3.zig",
285 "compiler_rt/muldi3.zig",362 "muldi3.zig",
286 "compiler_rt/mulf3.zig",363 "mulf3.zig",
287 "compiler_rt/mulo.zig",364 "mulo.zig",
288 "compiler_rt/mulsf3.zig",365 "mulsf3.zig",
289 "compiler_rt/multf3.zig",366 "multf3.zig",
290 "compiler_rt/multi3.zig",367 "multi3.zig",
291 "compiler_rt/mulxf3.zig",368 "mulxf3.zig",
292 "compiler_rt/negXf2.zig",369 "negXf2.zig",
293 "compiler_rt/negXi2.zig",370 "negXi2.zig",
294 "compiler_rt/negv.zig",371 "negv.zig",
295 "compiler_rt/os_version_check.zig",372 "os_version_check.zig",
296 "compiler_rt/parity.zig",373 "parity.zig",
297 "compiler_rt/popcount.zig",374 "popcount.zig",
298 "compiler_rt/round.zig",375 "round.zig",
299 "compiler_rt/shift.zig",376 "shift.zig",
300 "compiler_rt/sin.zig",377 "sin.zig",
301 "compiler_rt/sincos.zig",378 "sincos.zig",
302 "compiler_rt/sqrt.zig",379 "sqrt.zig",
303 "compiler_rt/stack_probe.zig",380 "stack_probe.zig",
304 "compiler_rt/subdf3.zig",381 "subdf3.zig",
305 "compiler_rt/subo.zig",382 "subo.zig",
306 "compiler_rt/subsf3.zig",383 "subsf3.zig",
307 "compiler_rt/subtf3.zig",384 "subtf3.zig",
308 "compiler_rt/subxf3.zig",385 "subxf3.zig",
309 "compiler_rt/tan.zig",386 "tan.zig",
310 "compiler_rt/trunc.zig",387 "trunc.zig",
311 "compiler_rt/truncdfhf2.zig",388 "truncdfhf2.zig",
312 "compiler_rt/truncdfsf2.zig",389 "truncdfsf2.zig",
313 "compiler_rt/truncsfhf2.zig",390 "truncsfhf2.zig",
314 "compiler_rt/trunctfdf2.zig",391 "trunctfdf2.zig",
315 "compiler_rt/trunctfhf2.zig",392 "trunctfhf2.zig",
316 "compiler_rt/trunctfsf2.zig",393 "trunctfsf2.zig",
317 "compiler_rt/trunctfxf2.zig",394 "trunctfxf2.zig",
318 "compiler_rt/truncxfdf2.zig",395 "truncxfdf2.zig",
319 "compiler_rt/truncxfhf2.zig",396 "truncxfhf2.zig",
320 "compiler_rt/truncxfsf2.zig",397 "truncxfsf2.zig",
321 "compiler_rt/udivmodti4.zig",398 "udivmodti4.zig",
322 "compiler_rt/udivti3.zig",399 "udivti3.zig",
323 "compiler_rt/umodti3.zig",400 "umodti3.zig",
324 "compiler_rt/unorddf2.zig",401 "unorddf2.zig",
325 "compiler_rt/unordsf2.zig",402 "unordsf2.zig",
326 "compiler_rt/unordtf2.zig",403 "unordtf2.zig",
327};404};