diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-02-03 12:49:40 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-02-03 12:49:40 -0700 |
| commit | fab9b7110ed1fa7bb082aad5e095047441db2b24 (patch) | |
| tree | 81fef60aa45e7980dab8f3e23e5b5e92b40ee0a9 /src/codegen | |
| parent | d20d69b59e6b65a99f45cb6a45c14e887034dd18 (diff) | |
| parent | 60935decd318498529a016eeb1379d943a7e830d (diff) | |
| download | zig-fab9b7110ed1fa7bb082aad5e095047441db2b24.tar.gz zig-fab9b7110ed1fa7bb082aad5e095047441db2b24.zip | |
Merge remote-tracking branch 'origin/master' into llvm16
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/c.zig | 70 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 5 | ||||
| -rw-r--r-- | src/codegen/spirv.zig | 30 |
3 files changed, 69 insertions, 36 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 68c20ea49c..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; @@ -1663,6 +1662,22 @@ pub const DeclGen = struct { defer buffer.deinit(); try buffer.appendSlice("struct "); + + var needs_pack_attr = false; + { + var it = t.structFields().iterator(); + while (it.next()) |field| { + const field_ty = field.value_ptr.ty; + if (!field_ty.hasRuntimeBits()) continue; + const alignment = field.value_ptr.abi_align; + if (alignment != 0 and alignment < field_ty.abiAlignment(dg.module.getTarget())) { + needs_pack_attr = true; + try buffer.appendSlice("zig_packed("); + break; + } + } + } + try buffer.appendSlice(name); try buffer.appendSlice(" {\n"); { @@ -1672,7 +1687,7 @@ pub const DeclGen = struct { const field_ty = field.value_ptr.ty; if (!field_ty.hasRuntimeBits()) continue; - const alignment = field.value_ptr.abi_align; + const alignment = field.value_ptr.alignment(dg.module.getTarget(), t.containerLayout()); const field_name = CValue{ .identifier = field.key_ptr.* }; try buffer.append(' '); try dg.renderTypeAndName(buffer.writer(), field_ty, field_name, .Mut, alignment, .Complete); @@ -1682,7 +1697,7 @@ pub const DeclGen = struct { } if (empty) try buffer.appendSlice(" char empty_struct;\n"); } - try buffer.appendSlice("};\n"); + if (needs_pack_attr) try buffer.appendSlice("});\n") else try buffer.appendSlice("};\n"); const rendered = try buffer.toOwnedSlice(); errdefer dg.typedefs.allocator.free(rendered); @@ -2367,8 +2382,13 @@ pub const DeclGen = struct { depth += 1; } - if (alignment != 0 and alignment > ty.abiAlignment(target)) { - try w.print("zig_align({}) ", .{alignment}); + if (alignment != 0) { + const abi_alignment = ty.abiAlignment(target); + if (alignment < abi_alignment) { + try w.print("zig_under_align({}) ", .{alignment}); + } else if (alignment > abi_alignment) { + try w.print("zig_align({}) ", .{alignment}); + } } try dg.renderType(w, render_ty, kind); @@ -2860,27 +2880,30 @@ pub fn genDecl(o: *Object) !void { const w = o.writer(); if (!is_global) try w.writeAll("static "); if (variable.is_threadlocal) try w.writeAll("zig_threadlocal "); + if (o.dg.decl.@"linksection") |section| try w.print("zig_linksection(\"{s}\", ", .{section}); try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete); + if (o.dg.decl.@"linksection" != null) try w.writeAll(", read, write)"); try w.writeAll(" = "); try o.dg.renderValue(w, tv.ty, variable.init, .StaticInitializer); try w.writeByte(';'); try o.indent_writer.insertNewline(); } else { + const is_global = o.dg.module.decl_exports.contains(o.dg.decl_index); + const fwd_decl_writer = o.dg.fwd_decl.writer(); const decl_c_value: CValue = .{ .decl = o.dg.decl_index }; - const fwd_decl_writer = o.dg.fwd_decl.writer(); - try fwd_decl_writer.writeAll("static "); - try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete); + try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); + try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, .Const, o.dg.decl.@"align", .Complete); try fwd_decl_writer.writeAll(";\n"); - const writer = o.writer(); - try writer.writeAll("static "); - // TODO ask the Decl if it is const - // https://github.com/ziglang/zig/issues/7582 - try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete); - try writer.writeAll(" = "); - try o.dg.renderValue(writer, tv.ty, tv.val, .StaticInitializer); - try writer.writeAll(";\n"); + const w = o.writer(); + if (!is_global) try w.writeAll("static "); + if (o.dg.decl.@"linksection") |section| try w.print("zig_linksection(\"{s}\", ", .{section}); + try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, .Const, o.dg.decl.@"align", .Complete); + if (o.dg.decl.@"linksection" != null) try w.writeAll(", read)"); + try w.writeAll(" = "); + try o.dg.renderValue(w, tv.ty, tv.val, .StaticInitializer); + try w.writeAll(";\n"); } } @@ -3726,16 +3749,15 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { const ptr_val = try f.resolveInst(bin_op.lhs); const src_ty = f.air.typeOf(bin_op.rhs); - const src_val = try f.resolveInst(bin_op.rhs); - - try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); // TODO Sema should emit a different instruction when the store should // possibly do the safety 0xaa bytes for undefined. const src_val_is_undefined = if (f.air.value(bin_op.rhs)) |v| v.isUndefDeep() else false; - if (src_val_is_undefined) + if (src_val_is_undefined) { + try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); return try storeUndefined(f, ptr_info.pointee_type, ptr_val); + } const target = f.object.dg.module.getTarget(); const is_aligned = ptr_info.@"align" == 0 or @@ -3744,6 +3766,9 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { const need_memcpy = !is_aligned or is_array; const writer = f.object.writer(); + const src_val = try f.resolveInst(bin_op.rhs); + try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); + if (need_memcpy) { // For this memcpy to safely work we need the rhs to have the same // underlying type as the lhs (i.e. they must both be arrays of the same underlying type). @@ -4344,8 +4369,9 @@ fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue { fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue { const pl_op = f.air.instructions.items(.data)[inst].pl_op; const name = f.air.nullTerminatedString(pl_op.payload); - const operand = try f.resolveInst(pl_op.operand); - _ = operand; + const operand_is_undef = if (f.air.value(pl_op.operand)) |v| v.isUndefDeep() else false; + if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand); + try reap(f, inst, &.{pl_op.operand}); const writer = f.object.writer(); try writer.print("/* var:{s} */\n", .{name}); diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index e53ebe5450..6433191221 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"); @@ -11057,8 +11056,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, }; } 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); |
