authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-05-31 19:13:08+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-06-24 08:12:17+02:00
loga6747d328cad831ceb07fb47cd0fa3647da21afb
tree1d91b7a8b7df925681d798177c5c0c5f86799aa2
parent9015efe4059b7e8448a9c09c3a116cb6b2550957

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.

3 files changed, 19 insertions(+), 11 deletions(-)

src/Compilation.zig+6-7
...@@ -1914,13 +1914,12 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1914,13 +1914,12 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1914 try comp.work_queue.writeItem(.libtsan);1914 try comp.work_queue.writeItem(.libtsan);
1915 }1915 }
19161916
1917 // The `use_stage1` condition is here only because stage2 cannot yet build compiler-rt.1917 // The `have_llvm` condition is here only because native backends cannot yet build compiler-rt.
1918 // Once it is capable this condition should be removed. When removing this condition,1918 // Once they are capable this condition could be removed. When removing this condition,
1919 // also test the use case of `build-obj -fcompiler-rt` with the self-hosted compiler1919 // also test the use case of `build-obj -fcompiler-rt` with the native backends
1920 // and make sure the compiler-rt symbols are emitted. Currently this is hooked up for1920 // and make sure the compiler-rt symbols are emitted.
1921 // stage1 but not stage2.1921 const capable_of_building_compiler_rt = build_options.have_llvm;
1922 const capable_of_building_compiler_rt = comp.bin_file.options.use_stage1 or1922
1923 comp.bin_file.options.use_llvm;
1924 const capable_of_building_zig_libc = comp.bin_file.options.use_stage1 or1923 const capable_of_building_zig_libc = comp.bin_file.options.use_stage1 or
1925 comp.bin_file.options.use_llvm;1924 comp.bin_file.options.use_llvm;
1926 const capable_of_building_ssp = comp.bin_file.options.use_stage1;1925 const capable_of_building_ssp = comp.bin_file.options.use_stage1;
src/link/Wasm.zig+11-4
...@@ -2286,7 +2286,9 @@ fn emitNameSection(self: *Wasm, file: fs.File, arena: Allocator) !void {...@@ -2286,7 +2286,9 @@ fn emitNameSection(self: *Wasm, file: fs.File, arena: Allocator) !void {
2286 }2286 }
2287 };2287 };
22882288
2289 var funcs = try std.ArrayList(Name).initCapacity(arena, self.functions.count() + self.imported_functions_count);2289 // we must de-duplicate symbols that point to the same function
2290 var funcs = std.AutoArrayHashMap(u32, Name).init(arena);
2291 try funcs.ensureUnusedCapacity(self.functions.count() + self.imported_functions_count);
2290 var globals = try std.ArrayList(Name).initCapacity(arena, self.wasm_globals.items.len + self.imported_globals_count);2292 var globals = try std.ArrayList(Name).initCapacity(arena, self.wasm_globals.items.len + self.imported_globals_count);
2291 var segments = try std.ArrayList(Name).initCapacity(arena, self.data_segments.count());2293 var segments = try std.ArrayList(Name).initCapacity(arena, self.data_segments.count());
22922294
...@@ -2296,7 +2298,12 @@ fn emitNameSection(self: *Wasm, file: fs.File, arena: Allocator) !void {...@@ -2296,7 +2298,12 @@ fn emitNameSection(self: *Wasm, file: fs.File, arena: Allocator) !void {
2296 break :blk self.string_table.get(self.imports.get(sym_loc).?.name);2298 break :blk self.string_table.get(self.imports.get(sym_loc).?.name);
2297 } else sym_loc.getName(self);2299 } else sym_loc.getName(self);
2298 switch (symbol.tag) {2300 switch (symbol.tag) {
2299 .function => try funcs.append(.{ .index = symbol.index, .name = name }),2301 .function => {
2302 const gop = funcs.getOrPutAssumeCapacity(symbol.index);
2303 if (!gop.found_existing) {
2304 gop.value_ptr.* = .{ .index = symbol.index, .name = name };
2305 }
2306 },
2300 .global => globals.appendAssumeCapacity(.{ .index = symbol.index, .name = name }),2307 .global => globals.appendAssumeCapacity(.{ .index = symbol.index, .name = name }),
2301 else => {},2308 else => {},
2302 }2309 }
...@@ -2306,7 +2313,7 @@ fn emitNameSection(self: *Wasm, file: fs.File, arena: Allocator) !void {...@@ -2306,7 +2313,7 @@ fn emitNameSection(self: *Wasm, file: fs.File, arena: Allocator) !void {
2306 segments.appendAssumeCapacity(.{ .index = @intCast(u32, index), .name = key });2313 segments.appendAssumeCapacity(.{ .index = @intCast(u32, index), .name = key });
2307 }2314 }
23082315
2309 std.sort.sort(Name, funcs.items, {}, Name.lessThan);2316 std.sort.sort(Name, funcs.values(), {}, Name.lessThan);
2310 std.sort.sort(Name, globals.items, {}, Name.lessThan);2317 std.sort.sort(Name, globals.items, {}, Name.lessThan);
23112318
2312 const header_offset = try reserveCustomSectionHeader(file);2319 const header_offset = try reserveCustomSectionHeader(file);
...@@ -2314,7 +2321,7 @@ fn emitNameSection(self: *Wasm, file: fs.File, arena: Allocator) !void {...@@ -2314,7 +2321,7 @@ fn emitNameSection(self: *Wasm, file: fs.File, arena: Allocator) !void {
2314 try leb.writeULEB128(writer, @intCast(u32, "name".len));2321 try leb.writeULEB128(writer, @intCast(u32, "name".len));
2315 try writer.writeAll("name");2322 try writer.writeAll("name");
23162323
2317 try self.emitNameSubsection(.function, funcs.items, writer);2324 try self.emitNameSubsection(.function, funcs.values(), writer);
2318 try self.emitNameSubsection(.global, globals.items, writer);2325 try self.emitNameSubsection(.global, globals.items, writer);
2319 try self.emitNameSubsection(.data_segment, segments.items, writer);2326 try self.emitNameSubsection(.data_segment, segments.items, writer);
23202327
src/link/Wasm/types.zig+2
...@@ -192,6 +192,7 @@ pub const Feature = struct {...@@ -192,6 +192,7 @@ pub const Feature = struct {
192 sign_ext,192 sign_ext,
193 simd128,193 simd128,
194 tail_call,194 tail_call,
195 shared_mem,
195 };196 };
196197
197 pub const Prefix = enum(u8) {198 pub const Prefix = enum(u8) {
...@@ -229,4 +230,5 @@ pub const known_features = std.ComptimeStringMap(Feature.Tag, .{...@@ -229,4 +230,5 @@ pub const known_features = std.ComptimeStringMap(Feature.Tag, .{
229 .{ "sign-ext", .sign_ext },230 .{ "sign-ext", .sign_ext },
230 .{ "simd128", .simd128 },231 .{ "simd128", .simd128 },
231 .{ "tail-call", .tail_call },232 .{ "tail-call", .tail_call },
233 .{ "shared-mem", .shared_mem },
232});234});