stage2: Enable compiler-rt when LLVM is existant

Rather than checking if the user wants to use LLVM for the current compilation,
check for the existance of LLVM as part of the compiler. This is temporarily,
until other backends gain the ability to compiler LLVM themselves.
This means that when a user passed `-fno-LLVM` we will use the native
backend for the user's code, but use LLVM for compiler-rt.

This also fixes emitting names for symbols in the Wasm linker,
by deduplicating symbol names when multiple symbols point the same object.
This commit is contained in:
Luuk de Gram 2022-05-31 19:13:08 +02:00
parent 9015efe405
commit a6747d328c
3 changed files with 19 additions and 11 deletions

View File

@ -1914,13 +1914,12 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
try comp.work_queue.writeItem(.libtsan);
}
// The `use_stage1` condition is here only because stage2 cannot yet build compiler-rt.
// Once it is capable this condition should be removed. When removing this condition,
// also test the use case of `build-obj -fcompiler-rt` with the self-hosted compiler
// and make sure the compiler-rt symbols are emitted. Currently this is hooked up for
// stage1 but not stage2.
const capable_of_building_compiler_rt = comp.bin_file.options.use_stage1 or
comp.bin_file.options.use_llvm;
// The `have_llvm` condition is here only because native backends cannot yet build compiler-rt.
// Once they are capable this condition could be removed. When removing this condition,
// also test the use case of `build-obj -fcompiler-rt` with the native backends
// and make sure the compiler-rt symbols are emitted.
const capable_of_building_compiler_rt = build_options.have_llvm;
const capable_of_building_zig_libc = comp.bin_file.options.use_stage1 or
comp.bin_file.options.use_llvm;
const capable_of_building_ssp = comp.bin_file.options.use_stage1;

View File

@ -2286,7 +2286,9 @@ fn emitNameSection(self: *Wasm, file: fs.File, arena: Allocator) !void {
}
};
var funcs = try std.ArrayList(Name).initCapacity(arena, self.functions.count() + self.imported_functions_count);
// we must de-duplicate symbols that point to the same function
var funcs = std.AutoArrayHashMap(u32, Name).init(arena);
try funcs.ensureUnusedCapacity(self.functions.count() + self.imported_functions_count);
var globals = try std.ArrayList(Name).initCapacity(arena, self.wasm_globals.items.len + self.imported_globals_count);
var segments = try std.ArrayList(Name).initCapacity(arena, self.data_segments.count());
@ -2296,7 +2298,12 @@ fn emitNameSection(self: *Wasm, file: fs.File, arena: Allocator) !void {
break :blk self.string_table.get(self.imports.get(sym_loc).?.name);
} else sym_loc.getName(self);
switch (symbol.tag) {
.function => try funcs.append(.{ .index = symbol.index, .name = name }),
.function => {
const gop = funcs.getOrPutAssumeCapacity(symbol.index);
if (!gop.found_existing) {
gop.value_ptr.* = .{ .index = symbol.index, .name = name };
}
},
.global => globals.appendAssumeCapacity(.{ .index = symbol.index, .name = name }),
else => {},
}
@ -2306,7 +2313,7 @@ fn emitNameSection(self: *Wasm, file: fs.File, arena: Allocator) !void {
segments.appendAssumeCapacity(.{ .index = @intCast(u32, index), .name = key });
}
std.sort.sort(Name, funcs.items, {}, Name.lessThan);
std.sort.sort(Name, funcs.values(), {}, Name.lessThan);
std.sort.sort(Name, globals.items, {}, Name.lessThan);
const header_offset = try reserveCustomSectionHeader(file);
@ -2314,7 +2321,7 @@ fn emitNameSection(self: *Wasm, file: fs.File, arena: Allocator) !void {
try leb.writeULEB128(writer, @intCast(u32, "name".len));
try writer.writeAll("name");
try self.emitNameSubsection(.function, funcs.items, writer);
try self.emitNameSubsection(.function, funcs.values(), writer);
try self.emitNameSubsection(.global, globals.items, writer);
try self.emitNameSubsection(.data_segment, segments.items, writer);

View File

@ -192,6 +192,7 @@ pub const Feature = struct {
sign_ext,
simd128,
tail_call,
shared_mem,
};
pub const Prefix = enum(u8) {
@ -229,4 +230,5 @@ pub const known_features = std.ComptimeStringMap(Feature.Tag, .{
.{ "sign-ext", .sign_ext },
.{ "simd128", .simd128 },
.{ "tail-call", .tail_call },
.{ "shared-mem", .shared_mem },
});