From 2f5892671e49850070064f689a7d8f93d6a7a0dd Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 31 Jan 2023 14:56:35 -0700 Subject: move compiler's CType logic to std.Target This API only depends on std.Target and is extremely useful in build scripts when populating configure files. --- src/codegen/c.zig | 1 - src/codegen/llvm.zig | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src/codegen') diff --git a/src/codegen/c.zig b/src/codegen/c.zig index eb0ae1b1f6..2f721e1b4b 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -16,7 +16,6 @@ const trace = @import("../tracy.zig").trace; const LazySrcLoc = Module.LazySrcLoc; const Air = @import("../Air.zig"); const Liveness = @import("../Liveness.zig"); -const CType = @import("../type.zig").CType; const target_util = @import("../target.zig"); const libcFloatPrefix = target_util.libcFloatPrefix; diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index c528abdd7c..e19c70f322 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -19,7 +19,6 @@ const Liveness = @import("../Liveness.zig"); const Value = @import("../value.zig").Value; const Type = @import("../type.zig").Type; const LazySrcLoc = Module.LazySrcLoc; -const CType = @import("../type.zig").CType; const x86_64_abi = @import("../arch/x86_64/abi.zig"); const wasm_c_abi = @import("../arch/wasm/abi.zig"); const aarch64_c_abi = @import("../arch/aarch64/abi.zig"); @@ -11043,8 +11042,8 @@ fn backendSupportsF128(target: std.Target) bool { fn intrinsicsAllowed(scalar_ty: Type, target: std.Target) bool { return switch (scalar_ty.tag()) { .f16 => backendSupportsF16(target), - .f80 => (CType.longdouble.sizeInBits(target) == 80) and backendSupportsF80(target), - .f128 => (CType.longdouble.sizeInBits(target) == 128) and backendSupportsF128(target), + .f80 => (target.c_type_bit_size(.longdouble) == 80) and backendSupportsF80(target), + .f128 => (target.c_type_bit_size(.longdouble) == 128) and backendSupportsF128(target), else => true, }; } -- cgit v1.2.3 From e0f3975fc8a7afd8a613802321fd46e64d8970d5 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 1 Feb 2023 16:01:43 +0100 Subject: link: make SpirV atoms fully owned by the linker --- src/Module.zig | 19 +++---------------- src/codegen/spirv.zig | 30 +++++++++++++++++++----------- src/link.zig | 2 +- src/link/SpirV.zig | 18 +++++++----------- 4 files changed, 30 insertions(+), 39 deletions(-) (limited to 'src/codegen') diff --git a/src/Module.zig b/src/Module.zig index eb947a6977..bfeeea51e8 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -5183,20 +5183,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err decl.zir_decl_index = @intCast(u32, decl_sub_index); if (decl.getFunction()) |_| { switch (comp.bin_file.tag) { - .coff => { - // TODO Implement for COFF - }, - .elf => { - // TODO Look into detecting when this would be unnecessary by storing enough state - // in `Decl` to notice that the line number did not change. - comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index }); - }, - .macho => { - // TODO Look into detecting when this would be unnecessary by storing enough state - // in `Decl` to notice that the line number did not change. - comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index }); - }, - .plan9 => { + .coff, .elf, .macho, .plan9 => { // TODO Look into detecting when this would be unnecessary by storing enough state // in `Decl` to notice that the line number did not change. comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index }); @@ -5290,7 +5277,7 @@ pub fn clearDecl( .plan9 => .{ .plan9 = {} }, .c => .{ .c = {} }, .wasm => .{ .wasm = link.File.Wasm.FnData.empty }, - .spirv => .{ .spirv = .{} }, + .spirv => .{ .spirv = {} }, .nvptx => .{ .nvptx = {} }, }; } @@ -5710,7 +5697,7 @@ pub fn allocateNewDecl( .plan9 => .{ .plan9 = {} }, .c => .{ .c = {} }, .wasm => .{ .wasm = link.File.Wasm.FnData.empty }, - .spirv => .{ .spirv = .{} }, + .spirv => .{ .spirv = {} }, .nvptx => .{ .nvptx = {} }, }, .generation = 0, diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index e1af8c847f..c5a3d57d07 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -49,7 +49,7 @@ pub const DeclGen = struct { spv: *SpvModule, /// The decl we are currently generating code for. - decl: *Decl, + decl_index: Decl.Index, /// The intermediate code of the declaration we are currently generating. Note: If /// the declaration is not a function, this value will be undefined! @@ -59,6 +59,8 @@ pub const DeclGen = struct { /// Note: If the declaration is not a function, this value will be undefined! liveness: Liveness, + ids: *const std.AutoHashMap(Decl.Index, IdResult), + /// An array of function argument result-ids. Each index corresponds with the /// function argument of the same index. args: std.ArrayListUnmanaged(IdRef) = .{}, @@ -133,14 +135,20 @@ pub const DeclGen = struct { /// Initialize the common resources of a DeclGen. Some fields are left uninitialized, /// only set when `gen` is called. - pub fn init(allocator: Allocator, module: *Module, spv: *SpvModule) DeclGen { + pub fn init( + allocator: Allocator, + module: *Module, + spv: *SpvModule, + ids: *const std.AutoHashMap(Decl.Index, IdResult), + ) DeclGen { return .{ .gpa = allocator, .module = module, .spv = spv, - .decl = undefined, + .decl_index = undefined, .air = undefined, .liveness = undefined, + .ids = ids, .next_arg_index = undefined, .current_block_label_id = undefined, .error_msg = undefined, @@ -150,9 +158,9 @@ pub const DeclGen = struct { /// Generate the code for `decl`. If a reportable error occurred 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, air: Air, liveness: Liveness) !?*Module.ErrorMsg { + pub fn gen(self: *DeclGen, decl_index: Decl.Index, air: Air, liveness: Liveness) !?*Module.ErrorMsg { // Reset internal resources, we don't want to re-allocate these. - self.decl = decl; + self.decl_index = decl_index; self.air = air; self.liveness = liveness; self.args.items.len = 0; @@ -194,7 +202,7 @@ pub const DeclGen = struct { pub fn fail(self: *DeclGen, comptime format: []const u8, args: anytype) Error { @setCold(true); const src = LazySrcLoc.nodeOffset(0); - const src_loc = src.toSrcLoc(self.decl); + const src_loc = src.toSrcLoc(self.module.declPtr(self.decl_index)); assert(self.error_msg == null); self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, format, args); return error.CodegenFail; @@ -332,7 +340,7 @@ pub const DeclGen = struct { }; const decl = self.module.declPtr(fn_decl_index); self.module.markDeclAlive(decl); - return decl.fn_link.spirv.id.toRef(); + return self.ids.get(fn_decl_index).?.toRef(); } const target = self.getTarget(); @@ -553,8 +561,8 @@ pub const DeclGen = struct { } fn genDecl(self: *DeclGen) !void { - const decl = self.decl; - const result_id = decl.fn_link.spirv.id; + const result_id = self.ids.get(self.decl_index).?; + const decl = self.module.declPtr(self.decl_index); if (decl.val.castTag(.function)) |_| { assert(decl.ty.zigTypeTag() == .Fn); @@ -945,7 +953,7 @@ pub const DeclGen = struct { fn airDbgStmt(self: *DeclGen, inst: Air.Inst.Index) !void { const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt; - const src_fname_id = try self.spv.resolveSourceFileName(self.decl); + const src_fname_id = try self.spv.resolveSourceFileName(self.module.declPtr(self.decl_index)); try self.func.body.emit(self.spv.gpa, .OpLine, .{ .file = src_fname_id, .line = dbg_stmt.line, @@ -1106,7 +1114,7 @@ pub const DeclGen = struct { assert(as.errors.items.len != 0); assert(self.error_msg == null); const loc = LazySrcLoc.nodeOffset(0); - const src_loc = loc.toSrcLoc(self.decl); + const src_loc = loc.toSrcLoc(self.module.declPtr(self.decl_index)); self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, "failed to assemble SPIR-V inline assembly", .{}); const notes = try self.module.gpa.alloc(Module.ErrorMsg, as.errors.items.len); diff --git a/src/link.zig b/src/link.zig index 3dd182b586..450a008cea 100644 --- a/src/link.zig +++ b/src/link.zig @@ -279,7 +279,7 @@ pub const File = struct { plan9: void, c: void, wasm: Wasm.FnData, - spirv: SpirV.FnData, + spirv: void, nvptx: void, }; diff --git a/src/link/SpirV.zig b/src/link/SpirV.zig index 7dbd3a42ce..14a29e4498 100644 --- a/src/link/SpirV.zig +++ b/src/link/SpirV.zig @@ -42,13 +42,6 @@ const SpvModule = @import("../codegen/spirv/Module.zig"); const spec = @import("../codegen/spirv/spec.zig"); const IdResult = spec.IdResult; -// TODO: Should this struct be used at all rather than just a hashmap of aux data for every decl? -pub const FnData = struct { - // We're going to fill these in flushModule, and we're going to fill them unconditionally, - // so just set it to undefined. - id: IdResult = undefined, -}; - base: link.File, /// 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 // so that we can access them before processing them. // TODO: We're allocating an ID unconditionally now, are there // declarations which don't generate a result? - // TODO: fn_link is used here, but thats probably not the right field. It will work anyway though. + var ids = std.AutoHashMap(Module.Decl.Index, IdResult).init(self.base.allocator); + defer ids.deinit(); + try ids.ensureTotalCapacity(@intCast(u32, self.decl_table.count())); + for (self.decl_table.keys()) |decl_index| { const decl = module.declPtr(decl_index); if (decl.has_tv) { - decl.fn_link.spirv.id = spv.allocId(); + ids.putAssumeCapacityNoClobber(decl_index, spv.allocId()); } } // Now, actually generate the code for all declarations. - var decl_gen = codegen.DeclGen.init(self.base.allocator, module, &spv); + var decl_gen = codegen.DeclGen.init(self.base.allocator, module, &spv, &ids); defer decl_gen.deinit(); var it = self.decl_table.iterator(); @@ -231,7 +227,7 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No const liveness = entry.value_ptr.liveness; // Note, if `decl` is not a function, air/liveness may be undefined. - if (try decl_gen.gen(decl, air, liveness)) |msg| { + if (try decl_gen.gen(decl_index, air, liveness)) |msg| { try module.failed_decls.put(module.gpa, decl_index, msg); return; // TODO: Attempt to generate more decls? } -- cgit v1.2.3