authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2024-04-06 12:40:49+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2024-04-06 13:37:41+02:00
log125d3324d982d13df02af5bbb3dfba3d07d65fff
treeb65e5162cfc88cef2cd0ed07fc4ea9c4dca250d6
parent3e388faecdb7100403d466df20086eb6781409e2
signaturebadge-check Signed by SSH key SHA256:ZS52FNyUv2WUXvO4njmVaFVO46RHojFuOrxRc4LuKzg

spirv: add link progression


4 files changed, 35 insertions(+), 8 deletions(-)

src/link/SpirV.zig+5-5
...@@ -245,7 +245,7 @@ pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: *std.Progress.Node...@@ -245,7 +245,7 @@ pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: *std.Progress.Node
245 const module = try spv.finalize(arena, target);245 const module = try spv.finalize(arena, target);
246 errdefer arena.free(module);246 errdefer arena.free(module);
247247
248 const linked_module = self.linkModule(arena, module) catch |err| switch (err) {248 const linked_module = self.linkModule(arena, module, &sub_prog_node) catch |err| switch (err) {
249 error.OutOfMemory => return error.OutOfMemory,249 error.OutOfMemory => return error.OutOfMemory,
250 else => |other| {250 else => |other| {
251 log.err("error while linking: {s}\n", .{@errorName(other)});251 log.err("error while linking: {s}\n", .{@errorName(other)});
...@@ -256,7 +256,7 @@ pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: *std.Progress.Node...@@ -256,7 +256,7 @@ pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: *std.Progress.Node
256 try self.base.file.?.writeAll(std.mem.sliceAsBytes(linked_module));256 try self.base.file.?.writeAll(std.mem.sliceAsBytes(linked_module));
257}257}
258258
259fn linkModule(self: *SpirV, a: Allocator, module: []Word) ![]Word {259fn linkModule(self: *SpirV, a: Allocator, module: []Word, progress: *std.Progress.Node) ![]Word {
260 _ = self;260 _ = self;
261261
262 const lower_invocation_globals = @import("SpirV/lower_invocation_globals.zig");262 const lower_invocation_globals = @import("SpirV/lower_invocation_globals.zig");
...@@ -267,9 +267,9 @@ fn linkModule(self: *SpirV, a: Allocator, module: []Word) ![]Word {...@@ -267,9 +267,9 @@ fn linkModule(self: *SpirV, a: Allocator, module: []Word) ![]Word {
267 defer parser.deinit();267 defer parser.deinit();
268 var binary = try parser.parse(module);268 var binary = try parser.parse(module);
269269
270 try lower_invocation_globals.run(&parser, &binary);270 try lower_invocation_globals.run(&parser, &binary, progress);
271 try prune_unused.run(&parser, &binary);271 try prune_unused.run(&parser, &binary, progress);
272 try dedup.run(&parser, &binary);272 try dedup.run(&parser, &binary, progress);
273273
274 return binary.finalize(a);274 return binary.finalize(a);
275}275}
src/link/SpirV/deduplicate.zig+10-1
...@@ -363,7 +363,11 @@ const EntityHashContext = struct {...@@ -363,7 +363,11 @@ const EntityHashContext = struct {
363 }363 }
364};364};
365365
366pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {366pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule, progress: *std.Progress.Node) !void {
367 var sub_node = progress.start("deduplicate", 0);
368 sub_node.activate();
369 defer sub_node.end();
370
367 var arena = std.heap.ArenaAllocator.init(parser.a);371 var arena = std.heap.ArenaAllocator.init(parser.a);
368 defer arena.deinit();372 defer arena.deinit();
369 const a = arena.allocator();373 const a = arena.allocator();
...@@ -376,6 +380,7 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {...@@ -376,6 +380,7 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {
376 .info = &info,380 .info = &info,
377 .binary = binary,381 .binary = binary,
378 };382 };
383
379 for (info.entities.keys()) |id| {384 for (info.entities.keys()) |id| {
380 _ = try ctx.hash(id);385 _ = try ctx.hash(id);
381 }386 }
...@@ -395,6 +400,8 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {...@@ -395,6 +400,8 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {
395 }400 }
396 }401 }
397402
403 sub_node.setEstimatedTotalItems(binary.instructions.len);
404
398 // Now process the module, and replace instructions where needed.405 // Now process the module, and replace instructions where needed.
399 var section = Section{};406 var section = Section{};
400 var it = binary.iterateInstructions();407 var it = binary.iterateInstructions();
...@@ -402,6 +409,8 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {...@@ -402,6 +409,8 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {
402 var new_operands = std.ArrayList(u32).init(a);409 var new_operands = std.ArrayList(u32).init(a);
403 var emitted_ptrs = std.AutoHashMap(ResultId, void).init(a);410 var emitted_ptrs = std.AutoHashMap(ResultId, void).init(a);
404 while (it.next()) |inst| {411 while (it.next()) |inst| {
412 defer sub_node.setCompletedItems(inst.offset);
413
405 // Result-id can only be the first or second operand414 // Result-id can only be the first or second operand
406 const inst_spec = parser.getInstSpec(inst.opcode).?;415 const inst_spec = parser.getInstSpec(inst.opcode).?;
407416
src/link/SpirV/lower_invocation_globals.zig+11-1
...@@ -682,7 +682,11 @@ const ModuleBuilder = struct {...@@ -682,7 +682,11 @@ const ModuleBuilder = struct {
682 }682 }
683};683};
684684
685pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {685pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule, progress: *std.Progress.Node) !void {
686 var sub_node = progress.start("Lower invocation globals", 6);
687 sub_node.activate();
688 defer sub_node.end();
689
686 var arena = std.heap.ArenaAllocator.init(parser.a);690 var arena = std.heap.ArenaAllocator.init(parser.a);
687 defer arena.deinit();691 defer arena.deinit();
688 const a = arena.allocator();692 const a = arena.allocator();
...@@ -691,10 +695,16 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {...@@ -691,10 +695,16 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {
691 try info.resolve(a);695 try info.resolve(a);
692696
693 var builder = try ModuleBuilder.init(a, binary.*, info);697 var builder = try ModuleBuilder.init(a, binary.*, info);
698 sub_node.completeOne();
694 try builder.deriveNewFnInfo(info);699 try builder.deriveNewFnInfo(info);
700 sub_node.completeOne();
695 try builder.processPreamble(binary.*, info);701 try builder.processPreamble(binary.*, info);
702 sub_node.completeOne();
696 try builder.emitFunctionTypes(info);703 try builder.emitFunctionTypes(info);
704 sub_node.completeOne();
697 try builder.rewriteFunctions(parser, binary.*, info);705 try builder.rewriteFunctions(parser, binary.*, info);
706 sub_node.completeOne();
698 try builder.emitNewEntryPoints(info);707 try builder.emitNewEntryPoints(info);
708 sub_node.completeOne();
699 try builder.finalize(parser.a, binary);709 try builder.finalize(parser.a, binary);
700}710}
src/link/SpirV/prune_unused.zig+9-1
...@@ -255,7 +255,11 @@ fn removeIdsFromMap(a: Allocator, map: anytype, info: ModuleInfo, alive_marker:...@@ -255,7 +255,11 @@ fn removeIdsFromMap(a: Allocator, map: anytype, info: ModuleInfo, alive_marker:
255 }255 }
256}256}
257257
258pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {258pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule, progress: *std.Progress.Node) !void {
259 var sub_node = progress.start("Prune unused IDs", 0);
260 sub_node.activate();
261 defer sub_node.end();
262
259 var arena = std.heap.ArenaAllocator.init(parser.a);263 var arena = std.heap.ArenaAllocator.init(parser.a);
260 defer arena.deinit();264 defer arena.deinit();
261 const a = arena.allocator();265 const a = arena.allocator();
...@@ -285,9 +289,13 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {...@@ -285,9 +289,13 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {
285289
286 var section = Section{};290 var section = Section{};
287291
292 sub_node.setEstimatedTotalItems(binary.instructions.len);
293
288 var new_functions_section: ?usize = null;294 var new_functions_section: ?usize = null;
289 var it = binary.iterateInstructions();295 var it = binary.iterateInstructions();
290 skip: while (it.next()) |inst| {296 skip: while (it.next()) |inst| {
297 defer sub_node.setCompletedItems(inst.offset);
298
291 const inst_spec = parser.getInstSpec(inst.opcode).?;299 const inst_spec = parser.getInstSpec(inst.opcode).?;
292300
293 reemit: {301 reemit: {