| author | |
| committer | |
| log | e0f3975fc8a7afd8a613802321fd46e64d8970d5 |
| tree | 4dabff13e809b7cdc4f460410762e93d372349a0 |
| parent | 5de2aae63cd75322e58204a6be8df49754e4851a |
4 files changed, 30 insertions(+), 39 deletions(-)
src/Module.zig+3-16| ... | ... | @@ -5183,20 +5183,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err |
| 5183 | 5183 | decl.zir_decl_index = @intCast(u32, decl_sub_index); |
| 5184 | 5184 | if (decl.getFunction()) |_| { |
| 5185 | 5185 | switch (comp.bin_file.tag) { |
| 5186 | .coff => { | |
| 5187 | // TODO Implement for COFF | |
| 5188 | }, | |
| 5189 | .elf => { | |
| 5190 | // TODO Look into detecting when this would be unnecessary by storing enough state | |
| 5191 | // in `Decl` to notice that the line number did not change. | |
| 5192 | comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index }); | |
| 5193 | }, | |
| 5194 | .macho => { | |
| 5195 | // TODO Look into detecting when this would be unnecessary by storing enough state | |
| 5196 | // in `Decl` to notice that the line number did not change. | |
| 5197 | comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index }); | |
| 5198 | }, | |
| 5199 | .plan9 => { | |
| 5186 | .coff, .elf, .macho, .plan9 => { | |
| 5200 | 5187 | // TODO Look into detecting when this would be unnecessary by storing enough state |
| 5201 | 5188 | // in `Decl` to notice that the line number did not change. |
| 5202 | 5189 | comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index }); |
| ... | ... | @@ -5290,7 +5277,7 @@ pub fn clearDecl( |
| 5290 | 5277 | .plan9 => .{ .plan9 = {} }, |
| 5291 | 5278 | .c => .{ .c = {} }, |
| 5292 | 5279 | .wasm => .{ .wasm = link.File.Wasm.FnData.empty }, |
| 5293 | .spirv => .{ .spirv = .{} }, | |
| 5280 | .spirv => .{ .spirv = {} }, | |
| 5294 | 5281 | .nvptx => .{ .nvptx = {} }, |
| 5295 | 5282 | }; |
| 5296 | 5283 | } |
| ... | ... | @@ -5710,7 +5697,7 @@ pub fn allocateNewDecl( |
| 5710 | 5697 | .plan9 => .{ .plan9 = {} }, |
| 5711 | 5698 | .c => .{ .c = {} }, |
| 5712 | 5699 | .wasm => .{ .wasm = link.File.Wasm.FnData.empty }, |
| 5713 | .spirv => .{ .spirv = .{} }, | |
| 5700 | .spirv => .{ .spirv = {} }, | |
| 5714 | 5701 | .nvptx => .{ .nvptx = {} }, |
| 5715 | 5702 | }, |
| 5716 | 5703 | .generation = 0, |
src/codegen/spirv.zig+19-11| ... | ... | @@ -49,7 +49,7 @@ pub const DeclGen = struct { |
| 49 | 49 | spv: *SpvModule, |
| 50 | 50 | |
| 51 | 51 | /// The decl we are currently generating code for. |
| 52 | decl: *Decl, | |
| 52 | decl_index: Decl.Index, | |
| 53 | 53 | |
| 54 | 54 | /// The intermediate code of the declaration we are currently generating. Note: If |
| 55 | 55 | /// the declaration is not a function, this value will be undefined! |
| ... | ... | @@ -59,6 +59,8 @@ pub const DeclGen = struct { |
| 59 | 59 | /// Note: If the declaration is not a function, this value will be undefined! |
| 60 | 60 | liveness: Liveness, |
| 61 | 61 | |
| 62 | ids: *const std.AutoHashMap(Decl.Index, IdResult), | |
| 63 | ||
| 62 | 64 | /// An array of function argument result-ids. Each index corresponds with the |
| 63 | 65 | /// function argument of the same index. |
| 64 | 66 | args: std.ArrayListUnmanaged(IdRef) = .{}, |
| ... | ... | @@ -133,14 +135,20 @@ pub const DeclGen = struct { |
| 133 | 135 | |
| 134 | 136 | /// Initialize the common resources of a DeclGen. Some fields are left uninitialized, |
| 135 | 137 | /// only set when `gen` is called. |
| 136 | pub fn init(allocator: Allocator, module: *Module, spv: *SpvModule) DeclGen { | |
| 138 | pub fn init( | |
| 139 | allocator: Allocator, | |
| 140 | module: *Module, | |
| 141 | spv: *SpvModule, | |
| 142 | ids: *const std.AutoHashMap(Decl.Index, IdResult), | |
| 143 | ) DeclGen { | |
| 137 | 144 | return .{ |
| 138 | 145 | .gpa = allocator, |
| 139 | 146 | .module = module, |
| 140 | 147 | .spv = spv, |
| 141 | .decl = undefined, | |
| 148 | .decl_index = undefined, | |
| 142 | 149 | .air = undefined, |
| 143 | 150 | .liveness = undefined, |
| 151 | .ids = ids, | |
| 144 | 152 | .next_arg_index = undefined, |
| 145 | 153 | .current_block_label_id = undefined, |
| 146 | 154 | .error_msg = undefined, |
| ... | ... | @@ -150,9 +158,9 @@ pub const DeclGen = struct { |
| 150 | 158 | /// Generate the code for `decl`. If a reportable error occurred during code generation, |
| 151 | 159 | /// a message is returned by this function. Callee owns the memory. If this function |
| 152 | 160 | /// returns such a reportable error, it is valid to be called again for a different decl. |
| 153 | pub fn gen(self: *DeclGen, decl: *Decl, air: Air, liveness: Liveness) !?*Module.ErrorMsg { | |
| 161 | pub fn gen(self: *DeclGen, decl_index: Decl.Index, air: Air, liveness: Liveness) !?*Module.ErrorMsg { | |
| 154 | 162 | // Reset internal resources, we don't want to re-allocate these. |
| 155 | self.decl = decl; | |
| 163 | self.decl_index = decl_index; | |
| 156 | 164 | self.air = air; |
| 157 | 165 | self.liveness = liveness; |
| 158 | 166 | self.args.items.len = 0; |
| ... | ... | @@ -194,7 +202,7 @@ pub const DeclGen = struct { |
| 194 | 202 | pub fn fail(self: *DeclGen, comptime format: []const u8, args: anytype) Error { |
| 195 | 203 | @setCold(true); |
| 196 | 204 | const src = LazySrcLoc.nodeOffset(0); |
| 197 | const src_loc = src.toSrcLoc(self.decl); | |
| 205 | const src_loc = src.toSrcLoc(self.module.declPtr(self.decl_index)); | |
| 198 | 206 | assert(self.error_msg == null); |
| 199 | 207 | self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, format, args); |
| 200 | 208 | return error.CodegenFail; |
| ... | ... | @@ -332,7 +340,7 @@ pub const DeclGen = struct { |
| 332 | 340 | }; |
| 333 | 341 | const decl = self.module.declPtr(fn_decl_index); |
| 334 | 342 | self.module.markDeclAlive(decl); |
| 335 | return decl.fn_link.spirv.id.toRef(); | |
| 343 | return self.ids.get(fn_decl_index).?.toRef(); | |
| 336 | 344 | } |
| 337 | 345 | |
| 338 | 346 | const target = self.getTarget(); |
| ... | ... | @@ -553,8 +561,8 @@ pub const DeclGen = struct { |
| 553 | 561 | } |
| 554 | 562 | |
| 555 | 563 | fn genDecl(self: *DeclGen) !void { |
| 556 | const decl = self.decl; | |
| 557 | const result_id = decl.fn_link.spirv.id; | |
| 564 | const result_id = self.ids.get(self.decl_index).?; | |
| 565 | const decl = self.module.declPtr(self.decl_index); | |
| 558 | 566 | |
| 559 | 567 | if (decl.val.castTag(.function)) |_| { |
| 560 | 568 | assert(decl.ty.zigTypeTag() == .Fn); |
| ... | ... | @@ -945,7 +953,7 @@ pub const DeclGen = struct { |
| 945 | 953 | |
| 946 | 954 | fn airDbgStmt(self: *DeclGen, inst: Air.Inst.Index) !void { |
| 947 | 955 | const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt; |
| 948 | const src_fname_id = try self.spv.resolveSourceFileName(self.decl); | |
| 956 | const src_fname_id = try self.spv.resolveSourceFileName(self.module.declPtr(self.decl_index)); | |
| 949 | 957 | try self.func.body.emit(self.spv.gpa, .OpLine, .{ |
| 950 | 958 | .file = src_fname_id, |
| 951 | 959 | .line = dbg_stmt.line, |
| ... | ... | @@ -1106,7 +1114,7 @@ pub const DeclGen = struct { |
| 1106 | 1114 | assert(as.errors.items.len != 0); |
| 1107 | 1115 | assert(self.error_msg == null); |
| 1108 | 1116 | const loc = LazySrcLoc.nodeOffset(0); |
| 1109 | const src_loc = loc.toSrcLoc(self.decl); | |
| 1117 | const src_loc = loc.toSrcLoc(self.module.declPtr(self.decl_index)); | |
| 1110 | 1118 | self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, "failed to assemble SPIR-V inline assembly", .{}); |
| 1111 | 1119 | const notes = try self.module.gpa.alloc(Module.ErrorMsg, as.errors.items.len); |
| 1112 | 1120 |
src/link.zig+1-1| ... | ... | @@ -279,7 +279,7 @@ pub const File = struct { |
| 279 | 279 | plan9: void, |
| 280 | 280 | c: void, |
| 281 | 281 | wasm: Wasm.FnData, |
| 282 | spirv: SpirV.FnData, | |
| 282 | spirv: void, | |
| 283 | 283 | nvptx: void, |
| 284 | 284 | }; |
| 285 | 285 |
src/link/SpirV.zig+7-11| ... | ... | @@ -42,13 +42,6 @@ const SpvModule = @import("../codegen/spirv/Module.zig"); |
| 42 | 42 | const spec = @import("../codegen/spirv/spec.zig"); |
| 43 | 43 | const IdResult = spec.IdResult; |
| 44 | 44 | |
| 45 | // TODO: Should this struct be used at all rather than just a hashmap of aux data for every decl? | |
| 46 | pub const FnData = struct { | |
| 47 | // We're going to fill these in flushModule, and we're going to fill them unconditionally, | |
| 48 | // so just set it to undefined. | |
| 49 | id: IdResult = undefined, | |
| 50 | }; | |
| 51 | ||
| 52 | 45 | base: link.File, |
| 53 | 46 | |
| 54 | 47 | /// This linker backend does not try to incrementally link output SPIR-V code. |
| ... | ... | @@ -209,16 +202,19 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No |
| 209 | 202 | // so that we can access them before processing them. |
| 210 | 203 | // TODO: We're allocating an ID unconditionally now, are there |
| 211 | 204 | // declarations which don't generate a result? |
| 212 | // TODO: fn_link is used here, but thats probably not the right field. It will work anyway though. | |
| 205 | var ids = std.AutoHashMap(Module.Decl.Index, IdResult).init(self.base.allocator); | |
| 206 | defer ids.deinit(); | |
| 207 | try ids.ensureTotalCapacity(@intCast(u32, self.decl_table.count())); | |
| 208 | ||
| 213 | 209 | for (self.decl_table.keys()) |decl_index| { |
| 214 | 210 | const decl = module.declPtr(decl_index); |
| 215 | 211 | if (decl.has_tv) { |
| 216 | decl.fn_link.spirv.id = spv.allocId(); | |
| 212 | ids.putAssumeCapacityNoClobber(decl_index, spv.allocId()); | |
| 217 | 213 | } |
| 218 | 214 | } |
| 219 | 215 | |
| 220 | 216 | // Now, actually generate the code for all declarations. |
| 221 | var decl_gen = codegen.DeclGen.init(self.base.allocator, module, &spv); | |
| 217 | var decl_gen = codegen.DeclGen.init(self.base.allocator, module, &spv, &ids); | |
| 222 | 218 | defer decl_gen.deinit(); |
| 223 | 219 | |
| 224 | 220 | var it = self.decl_table.iterator(); |
| ... | ... | @@ -231,7 +227,7 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No |
| 231 | 227 | const liveness = entry.value_ptr.liveness; |
| 232 | 228 | |
| 233 | 229 | // Note, if `decl` is not a function, air/liveness may be undefined. |
| 234 | if (try decl_gen.gen(decl, air, liveness)) |msg| { | |
| 230 | if (try decl_gen.gen(decl_index, air, liveness)) |msg| { | |
| 235 | 231 | try module.failed_decls.put(module.gpa, decl_index, msg); |
| 236 | 232 | return; // TODO: Attempt to generate more decls? |
| 237 | 233 | } |