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.
This commit is contained in:
@@ -735,7 +735,6 @@ set(ZIG_STAGE2_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/c.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/llvm.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/llvm/bindings.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/compiler_rt.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/glibc.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/introspect.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/libc_installation.zig"
|
||||
|
||||
@@ -23,7 +23,6 @@ const mingw = @import("mingw.zig");
|
||||
const libunwind = @import("libunwind.zig");
|
||||
const libcxx = @import("libcxx.zig");
|
||||
const wasi_libc = @import("wasi_libc.zig");
|
||||
const compiler_rt = @import("compiler_rt.zig");
|
||||
const fatal = @import("main.zig").fatal;
|
||||
const clangMain = @import("main.zig").clangMain;
|
||||
const Module = @import("Module.zig");
|
||||
@@ -2745,10 +2744,6 @@ pub fn performAllTheWork(
|
||||
var embed_file_prog_node = main_progress_node.start("Detect @embedFile updates", comp.embed_file_work_queue.count);
|
||||
defer embed_file_prog_node.end();
|
||||
|
||||
// +1 for the link step
|
||||
var compiler_rt_prog_node = main_progress_node.start("compiler_rt", compiler_rt.sources.len + 1);
|
||||
defer compiler_rt_prog_node.end();
|
||||
|
||||
comp.work_queue_wait_group.reset();
|
||||
defer comp.work_queue_wait_group.wait();
|
||||
|
||||
@@ -2796,28 +2791,6 @@ pub fn performAllTheWork(
|
||||
comp, c_object, &c_obj_prog_node, &comp.work_queue_wait_group,
|
||||
});
|
||||
}
|
||||
|
||||
if (comp.job_queued_compiler_rt_lib) {
|
||||
comp.job_queued_compiler_rt_lib = false;
|
||||
|
||||
// I have disabled the multi-threaded compiler-rt for now until
|
||||
// the threading deadlock is resolved.
|
||||
if (use_stage1 or true) {
|
||||
// stage1 LLVM backend uses the global context and thus cannot be used in
|
||||
// a multi-threaded context.
|
||||
buildCompilerRtOneShot(comp, .Lib, &comp.compiler_rt_lib);
|
||||
} else {
|
||||
comp.work_queue_wait_group.start();
|
||||
try comp.thread_pool.spawn(workerBuildCompilerRtLib, .{
|
||||
comp, &compiler_rt_prog_node, &comp.work_queue_wait_group,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (comp.job_queued_compiler_rt_obj) {
|
||||
comp.job_queued_compiler_rt_obj = false;
|
||||
buildCompilerRtOneShot(comp, .Obj, &comp.compiler_rt_obj);
|
||||
}
|
||||
}
|
||||
|
||||
if (!use_stage1) {
|
||||
@@ -2862,6 +2835,16 @@ pub fn performAllTheWork(
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (comp.job_queued_compiler_rt_lib) {
|
||||
comp.job_queued_compiler_rt_lib = false;
|
||||
buildCompilerRtOneShot(comp, .Lib, &comp.compiler_rt_lib);
|
||||
}
|
||||
|
||||
if (comp.job_queued_compiler_rt_obj) {
|
||||
comp.job_queued_compiler_rt_obj = false;
|
||||
buildCompilerRtOneShot(comp, .Obj, &comp.compiler_rt_obj);
|
||||
}
|
||||
}
|
||||
|
||||
fn processOneJob(comp: *Compilation, job: Job) !void {
|
||||
@@ -3534,23 +3517,6 @@ fn buildCompilerRtOneShot(
|
||||
};
|
||||
}
|
||||
|
||||
fn workerBuildCompilerRtLib(
|
||||
comp: *Compilation,
|
||||
progress_node: *std.Progress.Node,
|
||||
wg: *WaitGroup,
|
||||
) void {
|
||||
defer wg.finish();
|
||||
|
||||
compiler_rt.buildCompilerRtLib(comp, progress_node) catch |err| switch (err) {
|
||||
error.SubCompilationFailed => return, // error reported already
|
||||
else => comp.lockAndSetMiscFailure(
|
||||
.compiler_rt,
|
||||
"unable to build compiler_rt: {s}",
|
||||
.{@errorName(err)},
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
fn reportRetryableCObjectError(
|
||||
comp: *Compilation,
|
||||
c_object: *CObject,
|
||||
|
||||
@@ -1,406 +0,0 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const build_options = @import("build_options");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const assert = std.debug.assert;
|
||||
const mem = std.mem;
|
||||
const tracy = @import("tracy.zig");
|
||||
const trace = tracy.trace;
|
||||
|
||||
const Cache = @import("Cache.zig");
|
||||
const Compilation = @import("Compilation.zig");
|
||||
const CRTFile = Compilation.CRTFile;
|
||||
const LinkObject = Compilation.LinkObject;
|
||||
const Package = @import("Package.zig");
|
||||
const WaitGroup = @import("WaitGroup.zig");
|
||||
|
||||
pub fn buildCompilerRtLib(comp: *Compilation, progress_node: *std.Progress.Node) !void {
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
|
||||
defer arena_allocator.deinit();
|
||||
const arena = arena_allocator.allocator();
|
||||
|
||||
const target = comp.getTarget();
|
||||
|
||||
const root_name = "compiler_rt";
|
||||
const basename = try std.zig.binNameAlloc(arena, .{
|
||||
.root_name = root_name,
|
||||
.target = target,
|
||||
.output_mode = .Lib,
|
||||
});
|
||||
|
||||
var link_objects: [sources.len]LinkObject = undefined;
|
||||
var crt_files = [1]?CRTFile{null} ** sources.len;
|
||||
defer deinitCrtFiles(comp, crt_files);
|
||||
|
||||
{
|
||||
var wg: WaitGroup = .{};
|
||||
defer comp.thread_pool.waitAndWork(&wg);
|
||||
|
||||
for (sources) |source, i| {
|
||||
wg.start();
|
||||
try comp.thread_pool.spawn(workerBuildObject, .{
|
||||
comp, progress_node, &wg, source, &crt_files[i],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (link_objects) |*link_object, i| {
|
||||
link_object.* = .{
|
||||
.path = crt_files[i].?.full_object_path,
|
||||
};
|
||||
}
|
||||
|
||||
var link_progress_node = progress_node.start("link", 0);
|
||||
link_progress_node.activate();
|
||||
defer link_progress_node.end();
|
||||
|
||||
// TODO: This is extracted into a local variable to work around a stage1 miscompilation.
|
||||
const emit_bin = Compilation.EmitLoc{
|
||||
.directory = null, // Put it in the cache directory.
|
||||
.basename = basename,
|
||||
};
|
||||
const sub_compilation = try Compilation.create(comp.gpa, .{
|
||||
.local_cache_directory = comp.global_cache_directory,
|
||||
.global_cache_directory = comp.global_cache_directory,
|
||||
.zig_lib_directory = comp.zig_lib_directory,
|
||||
.cache_mode = .whole,
|
||||
.target = target,
|
||||
.root_name = root_name,
|
||||
.main_pkg = null,
|
||||
.output_mode = .Lib,
|
||||
.link_mode = .Static,
|
||||
.function_sections = true,
|
||||
.thread_pool = comp.thread_pool,
|
||||
.libc_installation = comp.bin_file.options.libc_installation,
|
||||
.emit_bin = emit_bin,
|
||||
.optimize_mode = comp.compilerRtOptMode(),
|
||||
.want_sanitize_c = false,
|
||||
.want_stack_check = false,
|
||||
.want_red_zone = comp.bin_file.options.red_zone,
|
||||
.omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
|
||||
.want_valgrind = false,
|
||||
.want_tsan = false,
|
||||
.want_pic = comp.bin_file.options.pic,
|
||||
.want_pie = comp.bin_file.options.pie,
|
||||
.want_lto = comp.bin_file.options.lto,
|
||||
.emit_h = null,
|
||||
.strip = comp.compilerRtStrip(),
|
||||
.is_native_os = comp.bin_file.options.is_native_os,
|
||||
.is_native_abi = comp.bin_file.options.is_native_abi,
|
||||
.self_exe_path = comp.self_exe_path,
|
||||
.link_objects = &link_objects,
|
||||
.verbose_cc = comp.verbose_cc,
|
||||
.verbose_link = comp.bin_file.options.verbose_link,
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
.skip_linker_dependencies = true,
|
||||
.parent_compilation_link_libc = comp.bin_file.options.link_libc,
|
||||
});
|
||||
defer sub_compilation.destroy();
|
||||
|
||||
try sub_compilation.updateSubCompilation();
|
||||
|
||||
assert(comp.compiler_rt_lib == null);
|
||||
comp.compiler_rt_lib = .{
|
||||
.full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(comp.gpa, &[_][]const u8{
|
||||
sub_compilation.bin_file.options.emit.?.sub_path,
|
||||
}),
|
||||
.lock = sub_compilation.bin_file.toOwnedLock(),
|
||||
};
|
||||
}
|
||||
|
||||
fn deinitCrtFiles(comp: *Compilation, crt_files: [sources.len]?CRTFile) void {
|
||||
const gpa = comp.gpa;
|
||||
|
||||
for (crt_files) |opt_crt_file| {
|
||||
var crt_file = opt_crt_file orelse continue;
|
||||
crt_file.deinit(gpa);
|
||||
}
|
||||
}
|
||||
|
||||
fn workerBuildObject(
|
||||
comp: *Compilation,
|
||||
progress_node: *std.Progress.Node,
|
||||
wg: *WaitGroup,
|
||||
src_basename: []const u8,
|
||||
out: *?CRTFile,
|
||||
) void {
|
||||
defer wg.finish();
|
||||
|
||||
var obj_progress_node = progress_node.start(src_basename, 0);
|
||||
obj_progress_node.activate();
|
||||
defer obj_progress_node.end();
|
||||
|
||||
buildObject(comp, src_basename, out) catch |err| switch (err) {
|
||||
error.SubCompilationFailed => return, // error reported already
|
||||
else => comp.lockAndSetMiscFailure(
|
||||
.compiler_rt,
|
||||
"unable to build compiler_rt: {s}",
|
||||
.{@errorName(err)},
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
fn buildObject(comp: *Compilation, src_basename: []const u8, out: *?CRTFile) !void {
|
||||
const gpa = comp.gpa;
|
||||
|
||||
var root_src_path_buf: [64]u8 = undefined;
|
||||
const root_src_path = std.fmt.bufPrint(
|
||||
&root_src_path_buf,
|
||||
"compiler_rt" ++ std.fs.path.sep_str ++ "{s}",
|
||||
.{src_basename},
|
||||
) catch unreachable;
|
||||
|
||||
var main_pkg: Package = .{
|
||||
.root_src_directory = comp.zig_lib_directory,
|
||||
.root_src_path = root_src_path,
|
||||
};
|
||||
defer main_pkg.deinitTable(gpa);
|
||||
const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len];
|
||||
const target = comp.getTarget();
|
||||
const output_mode: std.builtin.OutputMode = .Obj;
|
||||
const bin_basename = try std.zig.binNameAlloc(gpa, .{
|
||||
.root_name = root_name,
|
||||
.target = target,
|
||||
.output_mode = output_mode,
|
||||
});
|
||||
defer gpa.free(bin_basename);
|
||||
|
||||
const emit_bin = Compilation.EmitLoc{
|
||||
.directory = null, // Put it in the cache directory.
|
||||
.basename = bin_basename,
|
||||
};
|
||||
const sub_compilation = try Compilation.create(gpa, .{
|
||||
.global_cache_directory = comp.global_cache_directory,
|
||||
.local_cache_directory = comp.global_cache_directory,
|
||||
.zig_lib_directory = comp.zig_lib_directory,
|
||||
.cache_mode = .whole,
|
||||
.target = target,
|
||||
.root_name = root_name,
|
||||
.main_pkg = &main_pkg,
|
||||
.output_mode = output_mode,
|
||||
.thread_pool = comp.thread_pool,
|
||||
.libc_installation = comp.bin_file.options.libc_installation,
|
||||
.emit_bin = emit_bin,
|
||||
.optimize_mode = comp.compilerRtOptMode(),
|
||||
.link_mode = .Static,
|
||||
.function_sections = true,
|
||||
.want_sanitize_c = false,
|
||||
.want_stack_check = false,
|
||||
.want_red_zone = comp.bin_file.options.red_zone,
|
||||
.omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
|
||||
.want_valgrind = false,
|
||||
.want_tsan = false,
|
||||
.want_pic = comp.bin_file.options.pic,
|
||||
.want_pie = comp.bin_file.options.pie,
|
||||
.emit_h = null,
|
||||
.strip = comp.compilerRtStrip(),
|
||||
.is_native_os = comp.bin_file.options.is_native_os,
|
||||
.is_native_abi = comp.bin_file.options.is_native_abi,
|
||||
.self_exe_path = comp.self_exe_path,
|
||||
.verbose_cc = comp.verbose_cc,
|
||||
.verbose_link = comp.bin_file.options.verbose_link,
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
.skip_linker_dependencies = true,
|
||||
.parent_compilation_link_libc = comp.bin_file.options.link_libc,
|
||||
});
|
||||
defer sub_compilation.destroy();
|
||||
|
||||
try sub_compilation.update();
|
||||
// Look for compilation errors in this sub_compilation.
|
||||
var keep_errors = false;
|
||||
var errors = try sub_compilation.getAllErrorsAlloc();
|
||||
defer if (!keep_errors) errors.deinit(sub_compilation.gpa);
|
||||
|
||||
if (errors.list.len != 0) {
|
||||
const misc_task_tag: Compilation.MiscTask = .compiler_rt;
|
||||
|
||||
comp.mutex.lock();
|
||||
defer comp.mutex.unlock();
|
||||
|
||||
try comp.misc_failures.ensureUnusedCapacity(gpa, 1);
|
||||
comp.misc_failures.putAssumeCapacityNoClobber(misc_task_tag, .{
|
||||
.msg = try std.fmt.allocPrint(gpa, "sub-compilation of {s} failed", .{
|
||||
@tagName(misc_task_tag),
|
||||
}),
|
||||
.children = errors,
|
||||
});
|
||||
keep_errors = true;
|
||||
return error.SubCompilationFailed;
|
||||
}
|
||||
|
||||
assert(out.* == null);
|
||||
out.* = Compilation.CRTFile{
|
||||
.full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(gpa, &[_][]const u8{
|
||||
sub_compilation.bin_file.options.emit.?.sub_path,
|
||||
}),
|
||||
.lock = sub_compilation.bin_file.toOwnedLock(),
|
||||
};
|
||||
}
|
||||
|
||||
pub const sources = &[_][]const u8{
|
||||
"absvdi2.zig",
|
||||
"absvsi2.zig",
|
||||
"absvti2.zig",
|
||||
"adddf3.zig",
|
||||
"addo.zig",
|
||||
"addsf3.zig",
|
||||
"addtf3.zig",
|
||||
"addxf3.zig",
|
||||
"arm.zig",
|
||||
"atomics.zig",
|
||||
"aulldiv.zig",
|
||||
"aullrem.zig",
|
||||
"bswap.zig",
|
||||
"ceil.zig",
|
||||
"clear_cache.zig",
|
||||
"cmp.zig",
|
||||
"cmpdf2.zig",
|
||||
"cmpsf2.zig",
|
||||
"cmptf2.zig",
|
||||
"cmpxf2.zig",
|
||||
"cos.zig",
|
||||
"count0bits.zig",
|
||||
"divdf3.zig",
|
||||
"divsf3.zig",
|
||||
"divtf3.zig",
|
||||
"divti3.zig",
|
||||
"divxf3.zig",
|
||||
"emutls.zig",
|
||||
"exp.zig",
|
||||
"exp2.zig",
|
||||
"extenddftf2.zig",
|
||||
"extenddfxf2.zig",
|
||||
"extendhfsf2.zig",
|
||||
"extendhftf2.zig",
|
||||
"extendhfxf2.zig",
|
||||
"extendsfdf2.zig",
|
||||
"extendsftf2.zig",
|
||||
"extendsfxf2.zig",
|
||||
"extendxftf2.zig",
|
||||
"fabs.zig",
|
||||
"fixdfdi.zig",
|
||||
"fixdfsi.zig",
|
||||
"fixdfti.zig",
|
||||
"fixhfdi.zig",
|
||||
"fixhfsi.zig",
|
||||
"fixhfti.zig",
|
||||
"fixsfdi.zig",
|
||||
"fixsfsi.zig",
|
||||
"fixsfti.zig",
|
||||
"fixtfdi.zig",
|
||||
"fixtfsi.zig",
|
||||
"fixtfti.zig",
|
||||
"fixunsdfdi.zig",
|
||||
"fixunsdfsi.zig",
|
||||
"fixunsdfti.zig",
|
||||
"fixunshfdi.zig",
|
||||
"fixunshfsi.zig",
|
||||
"fixunshfti.zig",
|
||||
"fixunssfdi.zig",
|
||||
"fixunssfsi.zig",
|
||||
"fixunssfti.zig",
|
||||
"fixunstfdi.zig",
|
||||
"fixunstfsi.zig",
|
||||
"fixunstfti.zig",
|
||||
"fixunsxfdi.zig",
|
||||
"fixunsxfsi.zig",
|
||||
"fixunsxfti.zig",
|
||||
"fixxfdi.zig",
|
||||
"fixxfsi.zig",
|
||||
"fixxfti.zig",
|
||||
"floatdidf.zig",
|
||||
"floatdihf.zig",
|
||||
"floatdisf.zig",
|
||||
"floatditf.zig",
|
||||
"floatdixf.zig",
|
||||
"floatsidf.zig",
|
||||
"floatsihf.zig",
|
||||
"floatsisf.zig",
|
||||
"floatsitf.zig",
|
||||
"floatsixf.zig",
|
||||
"floattidf.zig",
|
||||
"floattihf.zig",
|
||||
"floattisf.zig",
|
||||
"floattitf.zig",
|
||||
"floattixf.zig",
|
||||
"floatundidf.zig",
|
||||
"floatundihf.zig",
|
||||
"floatundisf.zig",
|
||||
"floatunditf.zig",
|
||||
"floatundixf.zig",
|
||||
"floatunsidf.zig",
|
||||
"floatunsihf.zig",
|
||||
"floatunsisf.zig",
|
||||
"floatunsitf.zig",
|
||||
"floatunsixf.zig",
|
||||
"floatuntidf.zig",
|
||||
"floatuntihf.zig",
|
||||
"floatuntisf.zig",
|
||||
"floatuntitf.zig",
|
||||
"floatuntixf.zig",
|
||||
"floor.zig",
|
||||
"fma.zig",
|
||||
"fmax.zig",
|
||||
"fmin.zig",
|
||||
"fmod.zig",
|
||||
"gedf2.zig",
|
||||
"gesf2.zig",
|
||||
"getf2.zig",
|
||||
"gexf2.zig",
|
||||
"int.zig",
|
||||
"log.zig",
|
||||
"log10.zig",
|
||||
"log2.zig",
|
||||
"modti3.zig",
|
||||
"muldf3.zig",
|
||||
"muldi3.zig",
|
||||
"mulf3.zig",
|
||||
"mulo.zig",
|
||||
"mulsf3.zig",
|
||||
"multf3.zig",
|
||||
"multi3.zig",
|
||||
"mulxf3.zig",
|
||||
"negXf2.zig",
|
||||
"negXi2.zig",
|
||||
"negv.zig",
|
||||
"os_version_check.zig",
|
||||
"parity.zig",
|
||||
"popcount.zig",
|
||||
"round.zig",
|
||||
"shift.zig",
|
||||
"sin.zig",
|
||||
"sincos.zig",
|
||||
"sqrt.zig",
|
||||
"stack_probe.zig",
|
||||
"subdf3.zig",
|
||||
"subo.zig",
|
||||
"subsf3.zig",
|
||||
"subtf3.zig",
|
||||
"subxf3.zig",
|
||||
"tan.zig",
|
||||
"trunc.zig",
|
||||
"truncdfhf2.zig",
|
||||
"truncdfsf2.zig",
|
||||
"truncsfhf2.zig",
|
||||
"trunctfdf2.zig",
|
||||
"trunctfhf2.zig",
|
||||
"trunctfsf2.zig",
|
||||
"trunctfxf2.zig",
|
||||
"truncxfdf2.zig",
|
||||
"truncxfhf2.zig",
|
||||
"truncxfsf2.zig",
|
||||
"udivmodti4.zig",
|
||||
"udivti3.zig",
|
||||
"umodti3.zig",
|
||||
"unorddf2.zig",
|
||||
"unordsf2.zig",
|
||||
"unordtf2.zig",
|
||||
};
|
||||
Reference in New Issue
Block a user