spirv: add link progression

This commit is contained in:
Robin Voetter 2024-04-06 12:40:49 +02:00
parent 3e388faecd
commit 125d3324d9
No known key found for this signature in database
4 changed files with 35 additions and 8 deletions

View File

@ -245,7 +245,7 @@ pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: *std.Progress.Node
const module = try spv.finalize(arena, target);
errdefer arena.free(module);
const linked_module = self.linkModule(arena, module) catch |err| switch (err) {
const linked_module = self.linkModule(arena, module, &sub_prog_node) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
else => |other| {
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
try self.base.file.?.writeAll(std.mem.sliceAsBytes(linked_module));
}
fn linkModule(self: *SpirV, a: Allocator, module: []Word) ![]Word {
fn linkModule(self: *SpirV, a: Allocator, module: []Word, progress: *std.Progress.Node) ![]Word {
_ = self;
const lower_invocation_globals = @import("SpirV/lower_invocation_globals.zig");
@ -267,9 +267,9 @@ fn linkModule(self: *SpirV, a: Allocator, module: []Word) ![]Word {
defer parser.deinit();
var binary = try parser.parse(module);
try lower_invocation_globals.run(&parser, &binary);
try prune_unused.run(&parser, &binary);
try dedup.run(&parser, &binary);
try lower_invocation_globals.run(&parser, &binary, progress);
try prune_unused.run(&parser, &binary, progress);
try dedup.run(&parser, &binary, progress);
return binary.finalize(a);
}

View File

@ -363,7 +363,11 @@ const EntityHashContext = struct {
}
};
pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {
pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule, progress: *std.Progress.Node) !void {
var sub_node = progress.start("deduplicate", 0);
sub_node.activate();
defer sub_node.end();
var arena = std.heap.ArenaAllocator.init(parser.a);
defer arena.deinit();
const a = arena.allocator();
@ -376,6 +380,7 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {
.info = &info,
.binary = binary,
};
for (info.entities.keys()) |id| {
_ = try ctx.hash(id);
}
@ -395,6 +400,8 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {
}
}
sub_node.setEstimatedTotalItems(binary.instructions.len);
// Now process the module, and replace instructions where needed.
var section = Section{};
var it = binary.iterateInstructions();
@ -402,6 +409,8 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {
var new_operands = std.ArrayList(u32).init(a);
var emitted_ptrs = std.AutoHashMap(ResultId, void).init(a);
while (it.next()) |inst| {
defer sub_node.setCompletedItems(inst.offset);
// Result-id can only be the first or second operand
const inst_spec = parser.getInstSpec(inst.opcode).?;

View File

@ -682,7 +682,11 @@ const ModuleBuilder = struct {
}
};
pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {
pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule, progress: *std.Progress.Node) !void {
var sub_node = progress.start("Lower invocation globals", 6);
sub_node.activate();
defer sub_node.end();
var arena = std.heap.ArenaAllocator.init(parser.a);
defer arena.deinit();
const a = arena.allocator();
@ -691,10 +695,16 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {
try info.resolve(a);
var builder = try ModuleBuilder.init(a, binary.*, info);
sub_node.completeOne();
try builder.deriveNewFnInfo(info);
sub_node.completeOne();
try builder.processPreamble(binary.*, info);
sub_node.completeOne();
try builder.emitFunctionTypes(info);
sub_node.completeOne();
try builder.rewriteFunctions(parser, binary.*, info);
sub_node.completeOne();
try builder.emitNewEntryPoints(info);
sub_node.completeOne();
try builder.finalize(parser.a, binary);
}

View File

@ -255,7 +255,11 @@ fn removeIdsFromMap(a: Allocator, map: anytype, info: ModuleInfo, alive_marker:
}
}
pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {
pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule, progress: *std.Progress.Node) !void {
var sub_node = progress.start("Prune unused IDs", 0);
sub_node.activate();
defer sub_node.end();
var arena = std.heap.ArenaAllocator.init(parser.a);
defer arena.deinit();
const a = arena.allocator();
@ -285,9 +289,13 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void {
var section = Section{};
sub_node.setEstimatedTotalItems(binary.instructions.len);
var new_functions_section: ?usize = null;
var it = binary.iterateInstructions();
skip: while (it.next()) |inst| {
defer sub_node.setCompletedItems(inst.offset);
const inst_spec = parser.getInstSpec(inst.opcode).?;
reemit: {