authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-05-20 20:35:52+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-05-22 16:11:56+02:00
loge3be1a1e88bc76d5886122048e44673b692e6db6
tree9025dcd08cb45889353e7905e3d2b0fc83c2aff5
parent46184ab85eaf32be6e6fcbaac2202a2d58a37cf7

SPIR-V: DeclGen constructor/destructor


2 files changed, 46 insertions(+), 35 deletions(-)

src/codegen/spirv.zig+40-1
......@@ -157,6 +157,45 @@ pub const DeclGen = struct {
157157 class: Class,
158158 };
159159
160 /// Initialize the common resources of a DeclGen. Some fields are left uninitialized, only set when `gen` is called.
161 pub fn init(gpa: *Allocator, module: *Module, spv: *SPIRVModule) DeclGen {
162 return .{
163 .module = module,
164 .spv = spv,
165 .args = std.ArrayList(ResultId).init(gpa),
166 .next_arg_index = undefined,
167 .inst_results = InstMap.init(gpa),
168 .blocks = BlockMap.init(gpa),
169 .current_block_label_id = undefined,
170 .decl = undefined,
171 .error_msg = undefined,
172 };
173 }
174
175 /// Generate the code for `decl`. If a reportable error occured during code generation,
176 /// a message is returned by this function. Callee owns the memory. If this function returns such
177 /// a reportable error, it is valid to be called again for a different decl.
178 pub fn gen(self: *DeclGen, decl: *Decl) !?*Module.ErrorMsg {
179 // Reset internal resources, we don't want to re-allocate these.
180 self.args.items.len = 0;
181 self.next_arg_index = 0;
182 self.inst_results.clearRetainingCapacity();
183 self.blocks.clearRetainingCapacity();
184 self.current_block_label_id = undefined;
185 self.decl = decl;
186 self.error_msg = null;
187
188 try self.genDecl();
189 return self.error_msg;
190 }
191
192 /// Free resources owned by the DeclGen.
193 pub fn deinit(self: *DeclGen) void {
194 self.args.deinit();
195 self.inst_results.deinit();
196 self.blocks.deinit();
197 }
198
160199 fn fail(self: *DeclGen, src: LazySrcLoc, comptime format: []const u8, args: anytype) Error {
161200 @setCold(true);
162201 const src_loc = src.toSrcLocWithDecl(self.decl);
......@@ -476,7 +515,7 @@ pub const DeclGen = struct {
476515 return result_id;
477516 }
478517
479 pub fn gen(self: *DeclGen) !void {
518 fn genDecl(self: *DeclGen) !void {
480519 const decl = self.decl;
481520 const result_id = decl.fn_link.spirv.id;
482521
src/link/SpirV.zig+6-34
......@@ -152,45 +152,17 @@ pub fn flushModule(self: *SpirV, comp: *Compilation) !void {
152152
153153 // Now, actually generate the code for all declarations.
154154 {
155 // We are just going to re-use this same DeclGen for every Decl, and we are just going to
156 // change the decl. Otherwise, we would have to keep a separate `args` and `types`, and re-construct this
157 // structure every time.
158 var decl_gen = codegen.DeclGen{
159 .module = module,
160 .spv = &spv,
161 .args = std.ArrayList(codegen.Word).init(self.base.allocator),
162 .next_arg_index = undefined,
163 .inst_results = codegen.InstMap.init(self.base.allocator),
164 .blocks = codegen.BlockMap.init(self.base.allocator),
165 .current_block_label_id = undefined,
166 .decl = undefined,
167 .error_msg = undefined,
168 };
169
170 defer decl_gen.inst_results.deinit();
171 defer decl_gen.args.deinit();
172 defer decl_gen.blocks.deinit();
155 var decl_gen = codegen.DeclGen.init(self.base.allocator, module, &spv);
156 defer decl_gen.deinit();
173157
174158 for (self.decl_table.items()) |entry| {
175159 const decl = entry.key;
176160 if (!decl.has_tv) continue;
177161
178 // Reset the decl_gen, but retain allocated resources.
179 decl_gen.args.items.len = 0;
180 decl_gen.next_arg_index = 0;
181 decl_gen.inst_results.clearRetainingCapacity();
182 decl_gen.blocks.clearRetainingCapacity();
183 decl_gen.current_block_label_id = undefined;
184 decl_gen.decl = decl;
185 decl_gen.error_msg = null;
186
187 decl_gen.gen() catch |err| switch (err) {
188 error.AnalysisFail => {
189 try module.failed_decls.put(module.gpa, decl, decl_gen.error_msg.?);
190 return;
191 },
192 else => |e| return e,
193 };
162 if (try decl_gen.gen(decl)) |msg| {
163 try module.failed_decls.put(module.gpa, decl, msg);
164 return; // TODO: Attempt to generate more decls?
165 }
194166 }
195167 }
196168