mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
SPIR-V: DeclGen constructor/destructor
This commit is contained in:
parent
46184ab85e
commit
e3be1a1e88
@ -157,6 +157,45 @@ pub const DeclGen = struct {
|
||||
class: Class,
|
||||
};
|
||||
|
||||
/// Initialize the common resources of a DeclGen. Some fields are left uninitialized, only set when `gen` is called.
|
||||
pub fn init(gpa: *Allocator, module: *Module, spv: *SPIRVModule) DeclGen {
|
||||
return .{
|
||||
.module = module,
|
||||
.spv = spv,
|
||||
.args = std.ArrayList(ResultId).init(gpa),
|
||||
.next_arg_index = undefined,
|
||||
.inst_results = InstMap.init(gpa),
|
||||
.blocks = BlockMap.init(gpa),
|
||||
.current_block_label_id = undefined,
|
||||
.decl = undefined,
|
||||
.error_msg = undefined,
|
||||
};
|
||||
}
|
||||
|
||||
/// Generate the code for `decl`. If a reportable error occured during code generation,
|
||||
/// a message is returned by this function. Callee owns the memory. If this function returns such
|
||||
/// a reportable error, it is valid to be called again for a different decl.
|
||||
pub fn gen(self: *DeclGen, decl: *Decl) !?*Module.ErrorMsg {
|
||||
// Reset internal resources, we don't want to re-allocate these.
|
||||
self.args.items.len = 0;
|
||||
self.next_arg_index = 0;
|
||||
self.inst_results.clearRetainingCapacity();
|
||||
self.blocks.clearRetainingCapacity();
|
||||
self.current_block_label_id = undefined;
|
||||
self.decl = decl;
|
||||
self.error_msg = null;
|
||||
|
||||
try self.genDecl();
|
||||
return self.error_msg;
|
||||
}
|
||||
|
||||
/// Free resources owned by the DeclGen.
|
||||
pub fn deinit(self: *DeclGen) void {
|
||||
self.args.deinit();
|
||||
self.inst_results.deinit();
|
||||
self.blocks.deinit();
|
||||
}
|
||||
|
||||
fn fail(self: *DeclGen, src: LazySrcLoc, comptime format: []const u8, args: anytype) Error {
|
||||
@setCold(true);
|
||||
const src_loc = src.toSrcLocWithDecl(self.decl);
|
||||
@ -476,7 +515,7 @@ pub const DeclGen = struct {
|
||||
return result_id;
|
||||
}
|
||||
|
||||
pub fn gen(self: *DeclGen) !void {
|
||||
fn genDecl(self: *DeclGen) !void {
|
||||
const decl = self.decl;
|
||||
const result_id = decl.fn_link.spirv.id;
|
||||
|
||||
|
||||
@ -152,45 +152,17 @@ pub fn flushModule(self: *SpirV, comp: *Compilation) !void {
|
||||
|
||||
// Now, actually generate the code for all declarations.
|
||||
{
|
||||
// We are just going to re-use this same DeclGen for every Decl, and we are just going to
|
||||
// change the decl. Otherwise, we would have to keep a separate `args` and `types`, and re-construct this
|
||||
// structure every time.
|
||||
var decl_gen = codegen.DeclGen{
|
||||
.module = module,
|
||||
.spv = &spv,
|
||||
.args = std.ArrayList(codegen.Word).init(self.base.allocator),
|
||||
.next_arg_index = undefined,
|
||||
.inst_results = codegen.InstMap.init(self.base.allocator),
|
||||
.blocks = codegen.BlockMap.init(self.base.allocator),
|
||||
.current_block_label_id = undefined,
|
||||
.decl = undefined,
|
||||
.error_msg = undefined,
|
||||
};
|
||||
|
||||
defer decl_gen.inst_results.deinit();
|
||||
defer decl_gen.args.deinit();
|
||||
defer decl_gen.blocks.deinit();
|
||||
var decl_gen = codegen.DeclGen.init(self.base.allocator, module, &spv);
|
||||
defer decl_gen.deinit();
|
||||
|
||||
for (self.decl_table.items()) |entry| {
|
||||
const decl = entry.key;
|
||||
if (!decl.has_tv) continue;
|
||||
|
||||
// Reset the decl_gen, but retain allocated resources.
|
||||
decl_gen.args.items.len = 0;
|
||||
decl_gen.next_arg_index = 0;
|
||||
decl_gen.inst_results.clearRetainingCapacity();
|
||||
decl_gen.blocks.clearRetainingCapacity();
|
||||
decl_gen.current_block_label_id = undefined;
|
||||
decl_gen.decl = decl;
|
||||
decl_gen.error_msg = null;
|
||||
|
||||
decl_gen.gen() catch |err| switch (err) {
|
||||
error.AnalysisFail => {
|
||||
try module.failed_decls.put(module.gpa, decl, decl_gen.error_msg.?);
|
||||
return;
|
||||
},
|
||||
else => |e| return e,
|
||||
};
|
||||
if (try decl_gen.gen(decl)) |msg| {
|
||||
try module.failed_decls.put(module.gpa, decl, msg);
|
||||
return; // TODO: Attempt to generate more decls?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user