| author | |
| committer | |
| log | 5cd548e53081428d0e6b4a6b5a305317052c133a |
| tree | 4beb45ef87a73007a11e004a2fc52e35d8a6dc8e |
| parent | b4f3e69342d176ad7a2572cf4fee704094faaada |
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, |
| 93 | test_evented_io: bool, | 93 | test_evented_io: bool, |
| 94 | debug_compiler_runtime_libs: bool, | 94 | debug_compiler_runtime_libs: bool, |
| 95 | debug_compile_errors: bool, | 95 | debug_compile_errors: bool, |
| 96 | job_queued_compiler_rt_lib: bool = false, | ||
| 97 | job_queued_compiler_rt_obj: bool = false, | ||
| 98 | alloc_failure_occurred: bool = false, | ||
| 96 | 99 | ||
| 97 | c_source_files: []const CSourceFile, | 100 | c_source_files: []const CSourceFile, |
| 98 | clang_argv: []const []const u8, | 101 | clang_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 queue | 133 | /// 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(). |
| 132 | libc_static_lib: ?CRTFile = null, | 135 | libc_static_lib: ?CRTFile = null, |
| 133 | /// Populated when we build the libcompiler_rt static library. A Job to build this is placed in the queue | 136 | /// 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(). |
| 135 | compiler_rt_lib: ?CRTFile = null, | 138 | compiler_rt_lib: ?CRTFile = null, |
| 136 | /// Populated when we build the compiler_rt_obj object. A Job to build this is placed in the queue | 139 | /// 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(). |
| 138 | compiler_rt_obj: ?CRTFile = null, | 141 | compiler_rt_obj: ?CRTFile = null, |
| 139 | 142 | ||
| 140 | glibc_so_files: ?glibc.BuiltSharedObjects = null, | 143 | glibc_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 generates | 230 | /// 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 specially | 1932 | // 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 ask | 1933 | // 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 | } |
| 2022 | 2023 | ||
| 2023 | pub fn clearMiscFailures(comp: *Compilation) void { | 2024 | pub 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 | } |
| 2535 | 2537 | ||
| 2538 | /// This function is temporally single-threaded. | ||
| 2536 | pub fn totalErrorCount(self: *Compilation) usize { | 2539 | pub 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); | ||
| 2538 | 2542 | ||
| 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 | } |
| 2593 | 2597 | ||
| 2598 | /// This function is temporally single-threaded. | ||
| 2594 | pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors { | 2599 | pub 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(); |
| 2739 | 2747 | ||
| 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(); |
| 2742 | 2754 | ||
| 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 | } |
| 2786 | 2820 | ||
| 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 { |
| 3012 | 3045 | ||
| 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 { |
| 3023 | 3056 | ||
| 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 { |
| 3036 | 3069 | ||
| 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 { |
| 3049 | 3082 | ||
| 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 { |
| 3076 | 3109 | ||
| 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 { |
| 3089 | 3122 | ||
| 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 { |
| 3102 | 3135 | ||
| 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 { |
| 3115 | 3148 | ||
| 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 { |
| 3128 | 3161 | ||
| 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 already | 3182 | 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 already | 3201 | 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( |
| 3306 | 3303 | ||
| 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 | } |
| 3316 | 3309 | ||
| ... | @@ -3524,6 +3517,38 @@ fn workerUpdateCObject( | ... | @@ -3524,6 +3517,38 @@ fn workerUpdateCObject( |
| 3524 | }; | 3517 | }; |
| 3525 | } | 3518 | } |
| 3526 | 3519 | ||
| 3520 | fn 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 | |||
| 3535 | fn 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 | |||
| 3527 | fn reportRetryableCObjectError( | 3552 | fn 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 | } |
| 4624 | 4649 | ||
| 4625 | fn setMiscFailure( | 4650 | fn 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`. | ||
| 4657 | pub 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 | } |
| 4639 | 4671 | ||
| 4672 | /// See also `setMiscFailure`. | ||
| 4673 | pub 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 | |||
| 4640 | pub fn dump_argv(argv: []const []const u8) void { | 4685 | pub 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 | } |
| 4898 | 4943 | ||
| 4899 | pub fn buildOutputFromZig( | 4944 | fn 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); |
| 4916 | 4961 | 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 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const ThreadPool = @This(); | 3 | const ThreadPool = @This(); |
| 4 | const WaitGroup = @import("WaitGroup.zig"); | ||
| 4 | 5 | ||
| 5 | mutex: std.Thread.Mutex = .{}, | 6 | mutex: std.Thread.Mutex = .{}, |
| 6 | cond: std.Thread.Condition = .{}, | 7 | cond: 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 | }; |
| 21 | 22 | ||
| 22 | pub fn init(self: *ThreadPool, allocator: std.mem.Allocator) !void { | 23 | pub 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 | } |
| 31 | 32 | ||
| 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); |
| 35 | 36 | ||
| 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); |
| 39 | 40 | ||
| 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 | } |
| 45 | 46 | ||
| 46 | pub fn deinit(self: *ThreadPool) void { | 47 | pub 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 | } |
| 50 | 51 | ||
| 51 | fn join(self: *ThreadPool, spawned: usize) void { | 52 | fn join(pool: *ThreadPool, spawned: usize) void { |
| 52 | if (builtin.single_threaded) { | 53 | if (builtin.single_threaded) { |
| 53 | return; | 54 | return; |
| 54 | } | 55 | } |
| 55 | 56 | ||
| 56 | { | 57 | { |
| 57 | self.mutex.lock(); | 58 | pool.mutex.lock(); |
| 58 | defer self.mutex.unlock(); | 59 | defer pool.mutex.unlock(); |
| 59 | 60 | ||
| 60 | // ensure future worker threads exit the dequeue loop | 61 | // ensure future worker threads exit the dequeue loop |
| 61 | self.is_running = false; | 62 | pool.is_running = false; |
| 62 | } | 63 | } |
| 63 | 64 | ||
| 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 | } |
| 70 | 71 | ||
| 71 | self.allocator.free(self.threads); | 72 | pool.allocator.free(pool.threads); |
| 72 | } | 73 | } |
| 73 | 74 | ||
| 74 | pub fn spawn(self: *ThreadPool, comptime func: anytype, args: anytype) !void { | 75 | pub 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 | }; |
| 99 | 100 | ||
| 100 | { | 101 | { |
| 101 | self.mutex.lock(); | 102 | pool.mutex.lock(); |
| 102 | defer self.mutex.unlock(); | 103 | defer pool.mutex.unlock(); |
| 103 | 104 | ||
| 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 | }; |
| 109 | 110 | ||
| 110 | self.run_queue.prepend(&closure.run_node); | 111 | pool.run_queue.prepend(&closure.run_node); |
| 111 | } | 112 | } |
| 112 | 113 | ||
| 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 | } |
| 116 | 117 | ||
| 117 | fn worker(self: *ThreadPool) void { | 118 | fn worker(pool: *ThreadPool) void { |
| 118 | self.mutex.lock(); | 119 | pool.mutex.lock(); |
| 119 | defer self.mutex.unlock(); | 120 | defer pool.mutex.unlock(); |
| 120 | 121 | ||
| 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_node | 124 | // 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(); |
| 126 | 127 | ||
| 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 | } |
| 130 | 131 | ||
| 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 | |||
| 141 | pub 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 | |||
| 41 | pub 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"); |
| 12 | const CRTFile = Compilation.CRTFile; | 12 | const CRTFile = Compilation.CRTFile; |
| 13 | const LinkObject = Compilation.LinkObject; | 13 | const LinkObject = Compilation.LinkObject; |
| 14 | const Package = @import("Package.zig"); | 14 | const Package = @import("Package.zig"); |
| 15 | const WaitGroup = @import("WaitGroup.zig"); | ||
| 15 | 16 | ||
| 16 | pub fn buildCompilerRtLib(comp: *Compilation, compiler_rt_lib: *?CRTFile) !void { | 17 | pub 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(); |
| 23 | 21 | ||
| 24 | const target = comp.getTarget(); | 22 | const target = comp.getTarget(); |
| 25 | 23 | ||
| 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 | } |
| 32 | 113 | ||
| 33 | var cache = cache_parent.obtain(); | 114 | fn deinitCrtFiles(comp: *Compilation, crt_files: [sources.len]?CRTFile) void { |
| 34 | defer cache.deinit(); | 115 | const gpa = comp.gpa; |
| 35 | 116 | ||
| 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 | } | ||
| 41 | 122 | ||
| 42 | cache.hash.addBytes(build_options.version); | 123 | fn 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(); | ||
| 47 | 131 | ||
| 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(); |
| 51 | 135 | ||
| 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 | } |
| 57 | 145 | ||
| 58 | const ok_basename = "ok"; | 146 | fn 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; | ||
| 66 | 148 | ||
| 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); | ||
| 73 | 170 | ||
| 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, .{ |
| 79 | 176 | .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(); | ||
| 81 | 213 | ||
| 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); |
| 87 | 219 | ||
| 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 | } | ||
| 96 | 222 | ||
| 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(); | ||
| 100 | 225 | ||
| 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; |
| 146 | 234 | 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 | } |
| 155 | 236 | ||
| 156 | try cache.writeManifest(); | 237 | assert(out.* == null); |
| 157 | 238 | 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 | } |
| 168 | 245 | ||
| 169 | const sources = &[_][]const u8{ | 246 | pub 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 | }; |