| author | |
| committer | |
| log | e3be1a1e88bc76d5886122048e44673b692e6db6 |
| tree | 9025dcd08cb45889353e7905e3d2b0fc83c2aff5 |
| parent | 46184ab85eaf32be6e6fcbaac2202a2d58a37cf7 |
2 files changed, 46 insertions(+), 35 deletions(-)
src/codegen/spirv.zig+40-1| ... | ... | @@ -157,6 +157,45 @@ pub const DeclGen = struct { |
| 157 | 157 | class: Class, |
| 158 | 158 | }; |
| 159 | 159 | |
| 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 | ||
| 160 | 199 | fn fail(self: *DeclGen, src: LazySrcLoc, comptime format: []const u8, args: anytype) Error { |
| 161 | 200 | @setCold(true); |
| 162 | 201 | const src_loc = src.toSrcLocWithDecl(self.decl); |
| ... | ... | @@ -476,7 +515,7 @@ pub const DeclGen = struct { |
| 476 | 515 | return result_id; |
| 477 | 516 | } |
| 478 | 517 | |
| 479 | pub fn gen(self: *DeclGen) !void { | |
| 518 | fn genDecl(self: *DeclGen) !void { | |
| 480 | 519 | const decl = self.decl; |
| 481 | 520 | const result_id = decl.fn_link.spirv.id; |
| 482 | 521 |
src/link/SpirV.zig+6-34| ... | ... | @@ -152,45 +152,17 @@ pub fn flushModule(self: *SpirV, comp: *Compilation) !void { |
| 152 | 152 | |
| 153 | 153 | // Now, actually generate the code for all declarations. |
| 154 | 154 | { |
| 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(); | |
| 173 | 157 | |
| 174 | 158 | for (self.decl_table.items()) |entry| { |
| 175 | 159 | const decl = entry.key; |
| 176 | 160 | if (!decl.has_tv) continue; |
| 177 | 161 | |
| 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 | } | |
| 194 | 166 | } |
| 195 | 167 | } |
| 196 | 168 |