authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-17 18:34:11-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-17 18:34:11-07:00
loge4092d44426a471ee6097fae24069c72cffdc22a
treeaee6e1fdda76e737f40fe9c0baed36f86d909c3f
parent2064d86298cf4aefa28ace10d02307ac2f067cbb

stage2: rip out multi-compilation-unit compiler-rt

After doing performance testing, it seems that multi-compilation-unit compiler-rt did not bring the performance improvements that we expected it to. The idea is that it makes linking faster, however, it incurred a cost in the frontend that was not offset by any gains in linking. Furthermore, the single-object compiler-rt (with -ffunction-sections and --gc-sections) ends up being fewer bytes on disk and so it's actually the same or faster linking speed than the multi-compilation-unit version. So we are planning to keep using single-compilation-unit compiler-rt for the foreseeable future, but may experiment with this again in the future, in which case this commit can be reverted.

3 files changed, 10 insertions(+), 451 deletions(-)

CMakeLists.txt-1
...@@ -735,7 +735,6 @@ set(ZIG_STAGE2_SOURCES...@@ -735,7 +735,6 @@ set(ZIG_STAGE2_SOURCES
735 "${CMAKE_SOURCE_DIR}/src/codegen/c.zig"735 "${CMAKE_SOURCE_DIR}/src/codegen/c.zig"
736 "${CMAKE_SOURCE_DIR}/src/codegen/llvm.zig"736 "${CMAKE_SOURCE_DIR}/src/codegen/llvm.zig"
737 "${CMAKE_SOURCE_DIR}/src/codegen/llvm/bindings.zig"737 "${CMAKE_SOURCE_DIR}/src/codegen/llvm/bindings.zig"
738 "${CMAKE_SOURCE_DIR}/src/compiler_rt.zig"
739 "${CMAKE_SOURCE_DIR}/src/glibc.zig"738 "${CMAKE_SOURCE_DIR}/src/glibc.zig"
740 "${CMAKE_SOURCE_DIR}/src/introspect.zig"739 "${CMAKE_SOURCE_DIR}/src/introspect.zig"
741 "${CMAKE_SOURCE_DIR}/src/libc_installation.zig"740 "${CMAKE_SOURCE_DIR}/src/libc_installation.zig"
src/Compilation.zig+10-44
...@@ -23,7 +23,6 @@ const mingw = @import("mingw.zig");...@@ -23,7 +23,6 @@ const mingw = @import("mingw.zig");
23const libunwind = @import("libunwind.zig");23const libunwind = @import("libunwind.zig");
24const libcxx = @import("libcxx.zig");24const libcxx = @import("libcxx.zig");
25const wasi_libc = @import("wasi_libc.zig");25const wasi_libc = @import("wasi_libc.zig");
26const compiler_rt = @import("compiler_rt.zig");
27const fatal = @import("main.zig").fatal;26const fatal = @import("main.zig").fatal;
28const clangMain = @import("main.zig").clangMain;27const clangMain = @import("main.zig").clangMain;
29const Module = @import("Module.zig");28const Module = @import("Module.zig");
...@@ -2745,10 +2744,6 @@ pub fn performAllTheWork(...@@ -2745,10 +2744,6 @@ pub fn performAllTheWork(
2745 var embed_file_prog_node = main_progress_node.start("Detect @embedFile updates", comp.embed_file_work_queue.count);2744 var embed_file_prog_node = main_progress_node.start("Detect @embedFile updates", comp.embed_file_work_queue.count);
2746 defer embed_file_prog_node.end();2745 defer embed_file_prog_node.end();
27472746
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
2752 comp.work_queue_wait_group.reset();2747 comp.work_queue_wait_group.reset();
2753 defer comp.work_queue_wait_group.wait();2748 defer comp.work_queue_wait_group.wait();
27542749
...@@ -2796,28 +2791,6 @@ pub fn performAllTheWork(...@@ -2796,28 +2791,6 @@ pub fn performAllTheWork(
2796 comp, c_object, &c_obj_prog_node, &comp.work_queue_wait_group,2791 comp, c_object, &c_obj_prog_node, &comp.work_queue_wait_group,
2797 });2792 });
2798 }2793 }
2799
2800 if (comp.job_queued_compiler_rt_lib) {
2801 comp.job_queued_compiler_rt_lib = false;
2802
2803 // I have disabled the multi-threaded compiler-rt for now until
2804 // the threading deadlock is resolved.
2805 if (use_stage1 or true) {
2806 // stage1 LLVM backend uses the global context and thus cannot be used in
2807 // a multi-threaded context.
2808 buildCompilerRtOneShot(comp, .Lib, &comp.compiler_rt_lib);
2809 } else {
2810 comp.work_queue_wait_group.start();
2811 try comp.thread_pool.spawn(workerBuildCompilerRtLib, .{
2812 comp, &compiler_rt_prog_node, &comp.work_queue_wait_group,
2813 });
2814 }
2815 }
2816
2817 if (comp.job_queued_compiler_rt_obj) {
2818 comp.job_queued_compiler_rt_obj = false;
2819 buildCompilerRtOneShot(comp, .Obj, &comp.compiler_rt_obj);
2820 }
2821 }2794 }
28222795
2823 if (!use_stage1) {2796 if (!use_stage1) {
...@@ -2862,6 +2835,16 @@ pub fn performAllTheWork(...@@ -2862,6 +2835,16 @@ pub fn performAllTheWork(
2862 }2835 }
2863 break;2836 break;
2864 }2837 }
2838
2839 if (comp.job_queued_compiler_rt_lib) {
2840 comp.job_queued_compiler_rt_lib = false;
2841 buildCompilerRtOneShot(comp, .Lib, &comp.compiler_rt_lib);
2842 }
2843
2844 if (comp.job_queued_compiler_rt_obj) {
2845 comp.job_queued_compiler_rt_obj = false;
2846 buildCompilerRtOneShot(comp, .Obj, &comp.compiler_rt_obj);
2847 }
2865}2848}
28662849
2867fn processOneJob(comp: *Compilation, job: Job) !void {2850fn processOneJob(comp: *Compilation, job: Job) !void {
...@@ -3534,23 +3517,6 @@ fn buildCompilerRtOneShot(...@@ -3534,23 +3517,6 @@ fn buildCompilerRtOneShot(
3534 };3517 };
3535}3518}
35363519
3537fn workerBuildCompilerRtLib(
3538 comp: *Compilation,
3539 progress_node: *std.Progress.Node,
3540 wg: *WaitGroup,
3541) void {
3542 defer wg.finish();
3543
3544 compiler_rt.buildCompilerRtLib(comp, progress_node) catch |err| switch (err) {
3545 error.SubCompilationFailed => return, // error reported already
3546 else => comp.lockAndSetMiscFailure(
3547 .compiler_rt,
3548 "unable to build compiler_rt: {s}",
3549 .{@errorName(err)},
3550 ),
3551 };
3552}
3553
3554fn reportRetryableCObjectError(3520fn reportRetryableCObjectError(
3555 comp: *Compilation,3521 comp: *Compilation,
3556 c_object: *CObject,3522 c_object: *CObject,
src/compiler_rt.zig deleted-406
...@@ -1,406 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const build_options = @import("build_options");
4const Allocator = std.mem.Allocator;
5const assert = std.debug.assert;
6const mem = std.mem;
7const tracy = @import("tracy.zig");
8const trace = tracy.trace;
9
10const Cache = @import("Cache.zig");
11const Compilation = @import("Compilation.zig");
12const CRTFile = Compilation.CRTFile;
13const LinkObject = Compilation.LinkObject;
14const Package = @import("Package.zig");
15const WaitGroup = @import("WaitGroup.zig");
16
17pub fn buildCompilerRtLib(comp: *Compilation, progress_node: *std.Progress.Node) !void {
18 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
19 defer arena_allocator.deinit();
20 const arena = arena_allocator.allocator();
21
22 const target = comp.getTarget();
23
24 const root_name = "compiler_rt";
25 const basename = try std.zig.binNameAlloc(arena, .{
26 .root_name = root_name,
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 .function_sections = true,
73 .thread_pool = comp.thread_pool,
74 .libc_installation = comp.bin_file.options.libc_installation,
75 .emit_bin = emit_bin,
76 .optimize_mode = comp.compilerRtOptMode(),
77 .want_sanitize_c = false,
78 .want_stack_check = false,
79 .want_red_zone = comp.bin_file.options.red_zone,
80 .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
81 .want_valgrind = false,
82 .want_tsan = false,
83 .want_pic = comp.bin_file.options.pic,
84 .want_pie = comp.bin_file.options.pie,
85 .want_lto = comp.bin_file.options.lto,
86 .emit_h = null,
87 .strip = comp.compilerRtStrip(),
88 .is_native_os = comp.bin_file.options.is_native_os,
89 .is_native_abi = comp.bin_file.options.is_native_abi,
90 .self_exe_path = comp.self_exe_path,
91 .link_objects = &link_objects,
92 .verbose_cc = comp.verbose_cc,
93 .verbose_link = comp.bin_file.options.verbose_link,
94 .verbose_air = comp.verbose_air,
95 .verbose_llvm_ir = comp.verbose_llvm_ir,
96 .verbose_cimport = comp.verbose_cimport,
97 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
98 .clang_passthrough_mode = comp.clang_passthrough_mode,
99 .skip_linker_dependencies = true,
100 .parent_compilation_link_libc = comp.bin_file.options.link_libc,
101 });
102 defer sub_compilation.destroy();
103
104 try sub_compilation.updateSubCompilation();
105
106 assert(comp.compiler_rt_lib == null);
107 comp.compiler_rt_lib = .{
108 .full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(comp.gpa, &[_][]const u8{
109 sub_compilation.bin_file.options.emit.?.sub_path,
110 }),
111 .lock = sub_compilation.bin_file.toOwnedLock(),
112 };
113}
114
115fn deinitCrtFiles(comp: *Compilation, crt_files: [sources.len]?CRTFile) void {
116 const gpa = comp.gpa;
117
118 for (crt_files) |opt_crt_file| {
119 var crt_file = opt_crt_file orelse continue;
120 crt_file.deinit(gpa);
121 }
122}
123
124fn workerBuildObject(
125 comp: *Compilation,
126 progress_node: *std.Progress.Node,
127 wg: *WaitGroup,
128 src_basename: []const u8,
129 out: *?CRTFile,
130) void {
131 defer wg.finish();
132
133 var obj_progress_node = progress_node.start(src_basename, 0);
134 obj_progress_node.activate();
135 defer obj_progress_node.end();
136
137 buildObject(comp, src_basename, out) catch |err| switch (err) {
138 error.SubCompilationFailed => return, // error reported already
139 else => comp.lockAndSetMiscFailure(
140 .compiler_rt,
141 "unable to build compiler_rt: {s}",
142 .{@errorName(err)},
143 ),
144 };
145}
146
147fn buildObject(comp: *Compilation, src_basename: []const u8, out: *?CRTFile) !void {
148 const gpa = comp.gpa;
149
150 var root_src_path_buf: [64]u8 = undefined;
151 const root_src_path = std.fmt.bufPrint(
152 &root_src_path_buf,
153 "compiler_rt" ++ std.fs.path.sep_str ++ "{s}",
154 .{src_basename},
155 ) catch unreachable;
156
157 var main_pkg: Package = .{
158 .root_src_directory = comp.zig_lib_directory,
159 .root_src_path = root_src_path,
160 };
161 defer main_pkg.deinitTable(gpa);
162 const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len];
163 const target = comp.getTarget();
164 const output_mode: std.builtin.OutputMode = .Obj;
165 const bin_basename = try std.zig.binNameAlloc(gpa, .{
166 .root_name = root_name,
167 .target = target,
168 .output_mode = output_mode,
169 });
170 defer gpa.free(bin_basename);
171
172 const emit_bin = Compilation.EmitLoc{
173 .directory = null, // Put it in the cache directory.
174 .basename = bin_basename,
175 };
176 const sub_compilation = try Compilation.create(gpa, .{
177 .global_cache_directory = comp.global_cache_directory,
178 .local_cache_directory = comp.global_cache_directory,
179 .zig_lib_directory = comp.zig_lib_directory,
180 .cache_mode = .whole,
181 .target = target,
182 .root_name = root_name,
183 .main_pkg = &main_pkg,
184 .output_mode = output_mode,
185 .thread_pool = comp.thread_pool,
186 .libc_installation = comp.bin_file.options.libc_installation,
187 .emit_bin = emit_bin,
188 .optimize_mode = comp.compilerRtOptMode(),
189 .link_mode = .Static,
190 .function_sections = true,
191 .want_sanitize_c = false,
192 .want_stack_check = false,
193 .want_red_zone = comp.bin_file.options.red_zone,
194 .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
195 .want_valgrind = false,
196 .want_tsan = false,
197 .want_pic = comp.bin_file.options.pic,
198 .want_pie = comp.bin_file.options.pie,
199 .emit_h = null,
200 .strip = comp.compilerRtStrip(),
201 .is_native_os = comp.bin_file.options.is_native_os,
202 .is_native_abi = comp.bin_file.options.is_native_abi,
203 .self_exe_path = comp.self_exe_path,
204 .verbose_cc = comp.verbose_cc,
205 .verbose_link = comp.bin_file.options.verbose_link,
206 .verbose_air = comp.verbose_air,
207 .verbose_llvm_ir = comp.verbose_llvm_ir,
208 .verbose_cimport = comp.verbose_cimport,
209 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
210 .clang_passthrough_mode = comp.clang_passthrough_mode,
211 .skip_linker_dependencies = true,
212 .parent_compilation_link_libc = comp.bin_file.options.link_libc,
213 });
214 defer sub_compilation.destroy();
215
216 try sub_compilation.update();
217 // Look for compilation errors in this sub_compilation.
218 var keep_errors = false;
219 var errors = try sub_compilation.getAllErrorsAlloc();
220 defer if (!keep_errors) errors.deinit(sub_compilation.gpa);
221
222 if (errors.list.len != 0) {
223 const misc_task_tag: Compilation.MiscTask = .compiler_rt;
224
225 comp.mutex.lock();
226 defer comp.mutex.unlock();
227
228 try comp.misc_failures.ensureUnusedCapacity(gpa, 1);
229 comp.misc_failures.putAssumeCapacityNoClobber(misc_task_tag, .{
230 .msg = try std.fmt.allocPrint(gpa, "sub-compilation of {s} failed", .{
231 @tagName(misc_task_tag),
232 }),
233 .children = errors,
234 });
235 keep_errors = true;
236 return error.SubCompilationFailed;
237 }
238
239 assert(out.* == null);
240 out.* = Compilation.CRTFile{
241 .full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(gpa, &[_][]const u8{
242 sub_compilation.bin_file.options.emit.?.sub_path,
243 }),
244 .lock = sub_compilation.bin_file.toOwnedLock(),
245 };
246}
247
248pub const sources = &[_][]const u8{
249 "absvdi2.zig",
250 "absvsi2.zig",
251 "absvti2.zig",
252 "adddf3.zig",
253 "addo.zig",
254 "addsf3.zig",
255 "addtf3.zig",
256 "addxf3.zig",
257 "arm.zig",
258 "atomics.zig",
259 "aulldiv.zig",
260 "aullrem.zig",
261 "bswap.zig",
262 "ceil.zig",
263 "clear_cache.zig",
264 "cmp.zig",
265 "cmpdf2.zig",
266 "cmpsf2.zig",
267 "cmptf2.zig",
268 "cmpxf2.zig",
269 "cos.zig",
270 "count0bits.zig",
271 "divdf3.zig",
272 "divsf3.zig",
273 "divtf3.zig",
274 "divti3.zig",
275 "divxf3.zig",
276 "emutls.zig",
277 "exp.zig",
278 "exp2.zig",
279 "extenddftf2.zig",
280 "extenddfxf2.zig",
281 "extendhfsf2.zig",
282 "extendhftf2.zig",
283 "extendhfxf2.zig",
284 "extendsfdf2.zig",
285 "extendsftf2.zig",
286 "extendsfxf2.zig",
287 "extendxftf2.zig",
288 "fabs.zig",
289 "fixdfdi.zig",
290 "fixdfsi.zig",
291 "fixdfti.zig",
292 "fixhfdi.zig",
293 "fixhfsi.zig",
294 "fixhfti.zig",
295 "fixsfdi.zig",
296 "fixsfsi.zig",
297 "fixsfti.zig",
298 "fixtfdi.zig",
299 "fixtfsi.zig",
300 "fixtfti.zig",
301 "fixunsdfdi.zig",
302 "fixunsdfsi.zig",
303 "fixunsdfti.zig",
304 "fixunshfdi.zig",
305 "fixunshfsi.zig",
306 "fixunshfti.zig",
307 "fixunssfdi.zig",
308 "fixunssfsi.zig",
309 "fixunssfti.zig",
310 "fixunstfdi.zig",
311 "fixunstfsi.zig",
312 "fixunstfti.zig",
313 "fixunsxfdi.zig",
314 "fixunsxfsi.zig",
315 "fixunsxfti.zig",
316 "fixxfdi.zig",
317 "fixxfsi.zig",
318 "fixxfti.zig",
319 "floatdidf.zig",
320 "floatdihf.zig",
321 "floatdisf.zig",
322 "floatditf.zig",
323 "floatdixf.zig",
324 "floatsidf.zig",
325 "floatsihf.zig",
326 "floatsisf.zig",
327 "floatsitf.zig",
328 "floatsixf.zig",
329 "floattidf.zig",
330 "floattihf.zig",
331 "floattisf.zig",
332 "floattitf.zig",
333 "floattixf.zig",
334 "floatundidf.zig",
335 "floatundihf.zig",
336 "floatundisf.zig",
337 "floatunditf.zig",
338 "floatundixf.zig",
339 "floatunsidf.zig",
340 "floatunsihf.zig",
341 "floatunsisf.zig",
342 "floatunsitf.zig",
343 "floatunsixf.zig",
344 "floatuntidf.zig",
345 "floatuntihf.zig",
346 "floatuntisf.zig",
347 "floatuntitf.zig",
348 "floatuntixf.zig",
349 "floor.zig",
350 "fma.zig",
351 "fmax.zig",
352 "fmin.zig",
353 "fmod.zig",
354 "gedf2.zig",
355 "gesf2.zig",
356 "getf2.zig",
357 "gexf2.zig",
358 "int.zig",
359 "log.zig",
360 "log10.zig",
361 "log2.zig",
362 "modti3.zig",
363 "muldf3.zig",
364 "muldi3.zig",
365 "mulf3.zig",
366 "mulo.zig",
367 "mulsf3.zig",
368 "multf3.zig",
369 "multi3.zig",
370 "mulxf3.zig",
371 "negXf2.zig",
372 "negXi2.zig",
373 "negv.zig",
374 "os_version_check.zig",
375 "parity.zig",
376 "popcount.zig",
377 "round.zig",
378 "shift.zig",
379 "sin.zig",
380 "sincos.zig",
381 "sqrt.zig",
382 "stack_probe.zig",
383 "subdf3.zig",
384 "subo.zig",
385 "subsf3.zig",
386 "subtf3.zig",
387 "subxf3.zig",
388 "tan.zig",
389 "trunc.zig",
390 "truncdfhf2.zig",
391 "truncdfsf2.zig",
392 "truncsfhf2.zig",
393 "trunctfdf2.zig",
394 "trunctfhf2.zig",
395 "trunctfsf2.zig",
396 "trunctfxf2.zig",
397 "truncxfdf2.zig",
398 "truncxfhf2.zig",
399 "truncxfsf2.zig",
400 "udivmodti4.zig",
401 "udivti3.zig",
402 "umodti3.zig",
403 "unorddf2.zig",
404 "unordsf2.zig",
405 "unordtf2.zig",
406};