aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-03-22 00:23:54 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-03-22 15:45:58 -0700
commit593130ce0a4b06185fcb4806f8330857a1da9f92 (patch)
treeae30c61a06e6cecb97cc760dc6acd0cbfb83c162 /src/codegen
parentb74f2924102fe06addb688dc5fd039dc2756f619 (diff)
downloadzig-593130ce0a4b06185fcb4806f8330857a1da9f92.tar.gz
zig-593130ce0a4b06185fcb4806f8330857a1da9f92.zip
stage2: lazy `@alignOf`
Add a `target` parameter to every function that deals with Type and Value.
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/c.zig57
-rw-r--r--src/codegen/llvm.zig106
-rw-r--r--src/codegen/spirv.zig18
3 files changed, 100 insertions, 81 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index f5a1036479..c62abdb3f6 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -56,8 +56,14 @@ pub const TypedefMap = std.ArrayHashMap(
true,
);
+const FormatTypeAsCIdentContext = struct {
+ ty: Type,
+ target: std.Target,
+};
+
+/// TODO make this not cut off at 128 bytes
fn formatTypeAsCIdentifier(
- data: Type,
+ data: FormatTypeAsCIdentContext,
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
writer: anytype,
@@ -65,13 +71,15 @@ fn formatTypeAsCIdentifier(
_ = fmt;
_ = options;
var buffer = [1]u8{0} ** 128;
- // We don't care if it gets cut off, it's still more unique than a number
- var buf = std.fmt.bufPrint(&buffer, "{}", .{data}) catch &buffer;
+ var buf = std.fmt.bufPrint(&buffer, "{}", .{data.ty.fmt(data.target)}) catch &buffer;
return formatIdent(buf, "", .{}, writer);
}
-pub fn typeToCIdentifier(t: Type) std.fmt.Formatter(formatTypeAsCIdentifier) {
- return .{ .data = t };
+pub fn typeToCIdentifier(ty: Type, target: std.Target) std.fmt.Formatter(formatTypeAsCIdentifier) {
+ return .{ .data = .{
+ .ty = ty,
+ .target = target,
+ } };
}
const reserved_idents = std.ComptimeStringMap(void, .{
@@ -369,6 +377,8 @@ pub const DeclGen = struct {
) error{ OutOfMemory, AnalysisFail }!void {
decl.markAlive();
+ const target = dg.module.getTarget();
+
if (ty.isSlice()) {
try writer.writeByte('(');
try dg.renderTypecast(writer, ty);
@@ -376,7 +386,7 @@ pub const DeclGen = struct {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr());
try writer.writeAll(", ");
- try writer.print("{d}", .{val.sliceLen()});
+ try writer.print("{d}", .{val.sliceLen(target)});
try writer.writeAll("}");
return;
}
@@ -388,7 +398,7 @@ pub const DeclGen = struct {
// somewhere and we should let the C compiler tell us about it.
if (ty.castPtrToFn() == null) {
// Determine if we must pointer cast.
- if (ty.eql(decl.ty)) {
+ if (ty.eql(decl.ty, target)) {
try writer.writeByte('&');
try dg.renderDeclName(writer, decl);
return;
@@ -508,6 +518,7 @@ pub const DeclGen = struct {
ty: Type,
val: Value,
) error{ OutOfMemory, AnalysisFail }!void {
+ const target = dg.module.getTarget();
if (val.isUndefDeep()) {
switch (ty.zigTypeTag()) {
// Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang)
@@ -551,7 +562,7 @@ pub const DeclGen = struct {
else => {
if (ty.isSignedInt())
return writer.print("{d}", .{val.toSignedInt()});
- return writer.print("{d}u", .{val.toUnsignedInt()});
+ return writer.print("{d}u", .{val.toUnsignedInt(target)});
},
},
.Float => {
@@ -609,7 +620,7 @@ pub const DeclGen = struct {
.int_u64, .one => {
try writer.writeAll("((");
try dg.renderTypecast(writer, ty);
- try writer.print(")0x{x}u)", .{val.toUnsignedInt()});
+ try writer.print(")0x{x}u)", .{val.toUnsignedInt(target)});
},
else => unreachable,
},
@@ -653,7 +664,6 @@ pub const DeclGen = struct {
if (ty.isPtrLikeOptional()) {
return dg.renderValue(writer, payload_type, val);
}
- const target = dg.module.getTarget();
if (payload_type.abiSize(target) == 0) {
const is_null = val.castTag(.opt_payload) == null;
return writer.print("{}", .{is_null});
@@ -773,7 +783,6 @@ pub const DeclGen = struct {
.Union => {
const union_obj = val.castTag(.@"union").?.data;
const union_ty = ty.cast(Type.Payload.Union).?.data;
- const target = dg.module.getTarget();
const layout = ty.unionGetLayout(target);
try writer.writeAll("(");
@@ -789,7 +798,7 @@ pub const DeclGen = struct {
try writer.writeAll(".payload = {");
}
- const index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag).?;
+ const index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag, target).?;
const field_ty = ty.unionFields().values()[index].ty;
const field_name = ty.unionFields().keys()[index];
if (field_ty.hasRuntimeBits()) {
@@ -879,8 +888,8 @@ pub const DeclGen = struct {
try bw.writeAll(" (*");
const name_start = buffer.items.len;
- // TODO: typeToCIdentifier truncates to 128 bytes, we probably don't want to do this
- try bw.print("zig_F_{s})(", .{typeToCIdentifier(t)});
+ const target = dg.module.getTarget();
+ try bw.print("zig_F_{s})(", .{typeToCIdentifier(t, target)});
const name_end = buffer.items.len - 2;
const param_len = fn_info.param_types.len;
@@ -934,10 +943,11 @@ pub const DeclGen = struct {
try bw.writeAll("; size_t len; } ");
const name_index = buffer.items.len;
+ const target = dg.module.getTarget();
if (t.isConstPtr()) {
- try bw.print("zig_L_{s}", .{typeToCIdentifier(child_type)});
+ try bw.print("zig_L_{s}", .{typeToCIdentifier(child_type, target)});
} else {
- try bw.print("zig_M_{s}", .{typeToCIdentifier(child_type)});
+ try bw.print("zig_M_{s}", .{typeToCIdentifier(child_type, target)});
}
if (ptr_sentinel) |s| {
try bw.writeAll("_s_");
@@ -1023,7 +1033,8 @@ pub const DeclGen = struct {
try buffer.appendSlice("} ");
const name_start = buffer.items.len;
- try writer.print("zig_T_{};\n", .{typeToCIdentifier(t)});
+ const target = dg.module.getTarget();
+ try writer.print("zig_T_{};\n", .{typeToCIdentifier(t, target)});
const rendered = buffer.toOwnedSlice();
errdefer dg.typedefs.allocator.free(rendered);
@@ -1107,6 +1118,7 @@ pub const DeclGen = struct {
try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);
try bw.writeAll("; uint16_t error; } ");
const name_index = buffer.items.len;
+ const target = dg.module.getTarget();
if (err_set_type.castTag(.error_set_inferred)) |inf_err_set_payload| {
const func = inf_err_set_payload.data.func;
try bw.writeAll("zig_E_");
@@ -1114,7 +1126,7 @@ pub const DeclGen = struct {
try bw.writeAll(";\n");
} else {
try bw.print("zig_E_{s}_{s};\n", .{
- typeToCIdentifier(err_set_type), typeToCIdentifier(child_type),
+ typeToCIdentifier(err_set_type, target), typeToCIdentifier(child_type, target),
});
}
@@ -1144,7 +1156,8 @@ pub const DeclGen = struct {
try dg.renderType(bw, elem_type);
const name_start = buffer.items.len + 1;
- try bw.print(" zig_A_{s}_{d}", .{ typeToCIdentifier(elem_type), c_len });
+ const target = dg.module.getTarget();
+ try bw.print(" zig_A_{s}_{d}", .{ typeToCIdentifier(elem_type, target), c_len });
const name_end = buffer.items.len;
try bw.print("[{d}];\n", .{c_len});
@@ -1172,7 +1185,8 @@ pub const DeclGen = struct {
try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);
try bw.writeAll("; bool is_null; } ");
const name_index = buffer.items.len;
- try bw.print("zig_Q_{s};\n", .{typeToCIdentifier(child_type)});
+ const target = dg.module.getTarget();
+ try bw.print("zig_Q_{s};\n", .{typeToCIdentifier(child_type, target)});
const rendered = buffer.toOwnedSlice();
errdefer dg.typedefs.allocator.free(rendered);
@@ -2177,12 +2191,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
if (src_val_is_undefined)
return try airStoreUndefined(f, dest_ptr);
+ const target = f.object.dg.module.getTarget();
const writer = f.object.writer();
if (lhs_child_type.zigTypeTag() == .Array) {
// 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).
const rhs_type = f.air.typeOf(bin_op.rhs);
- assert(rhs_type.eql(lhs_child_type));
+ assert(rhs_type.eql(lhs_child_type, target));
// If the source is a constant, writeCValue will emit a brace initialization
// so work around this by initializing into new local.
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 107b059765..c8ca540f59 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -812,7 +812,7 @@ pub const Object = struct {
const gpa = o.gpa;
// Be careful not to reference this `gop` variable after any recursive calls
// to `lowerDebugType`.
- const gop = try o.di_type_map.getOrPut(gpa, ty);
+ const gop = try o.di_type_map.getOrPutContext(gpa, ty, .{ .target = o.target });
if (gop.found_existing) {
const annotated = gop.value_ptr.*;
const di_type = annotated.toDIType();
@@ -825,7 +825,7 @@ pub const Object = struct {
};
return o.lowerDebugTypeImpl(entry, resolve, di_type);
}
- errdefer assert(o.di_type_map.orderedRemove(ty));
+ errdefer assert(o.di_type_map.orderedRemoveContext(ty, .{ .target = o.target }));
// The Type memory is ephemeral; since we want to store a longer-lived
// reference, we need to copy it here.
gop.key_ptr.* = try ty.copy(o.type_map_arena.allocator());
@@ -856,7 +856,7 @@ pub const Object = struct {
.Int => {
const info = ty.intInfo(target);
assert(info.bits != 0);
- const name = try ty.nameAlloc(gpa);
+ const name = try ty.nameAlloc(gpa, target);
defer gpa.free(name);
const dwarf_encoding: c_uint = switch (info.signedness) {
.signed => DW.ATE.signed,
@@ -873,7 +873,7 @@ pub const Object = struct {
const enum_di_ty = try o.makeEmptyNamespaceDIType(owner_decl);
// The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
// means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty), .{ .target = o.target });
return enum_di_ty;
}
@@ -903,7 +903,7 @@ pub const Object = struct {
const di_file = try o.getDIFile(gpa, owner_decl.src_namespace.file_scope);
const di_scope = try o.namespaceToDebugScope(owner_decl.src_namespace);
- const name = try ty.nameAlloc(gpa);
+ const name = try ty.nameAlloc(gpa, target);
defer gpa.free(name);
var buffer: Type.Payload.Bits = undefined;
const int_ty = ty.intTagType(&buffer);
@@ -921,12 +921,12 @@ pub const Object = struct {
"",
);
// The recursive call to `lowerDebugType` means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty), .{ .target = o.target });
return enum_di_ty;
},
.Float => {
const bits = ty.floatBits(target);
- const name = try ty.nameAlloc(gpa);
+ const name = try ty.nameAlloc(gpa, target);
defer gpa.free(name);
const di_type = dib.createBasicType(name, bits, DW.ATE.float);
gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
@@ -974,7 +974,7 @@ pub const Object = struct {
const bland_ptr_ty = Type.initPayload(&payload.base);
const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve);
// The recursive call to `lowerDebugType` means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve), .{ .target = o.target });
return ptr_di_ty;
}
@@ -983,7 +983,7 @@ pub const Object = struct {
const ptr_ty = ty.slicePtrFieldType(&buf);
const len_ty = Type.usize;
- const name = try ty.nameAlloc(gpa);
+ const name = try ty.nameAlloc(gpa, target);
defer gpa.free(name);
const di_file: ?*llvm.DIFile = null;
const line = 0;
@@ -1054,12 +1054,12 @@ pub const Object = struct {
);
dib.replaceTemporary(fwd_decl, full_di_ty);
// The recursive call to `lowerDebugType` means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });
return full_di_ty;
}
const elem_di_ty = try o.lowerDebugType(ptr_info.pointee_type, .fwd);
- const name = try ty.nameAlloc(gpa);
+ const name = try ty.nameAlloc(gpa, target);
defer gpa.free(name);
const ptr_di_ty = dib.createPointerType(
elem_di_ty,
@@ -1068,7 +1068,7 @@ pub const Object = struct {
name,
);
// The recursive call to `lowerDebugType` means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty), .{ .target = o.target });
return ptr_di_ty;
},
.Opaque => {
@@ -1077,7 +1077,7 @@ pub const Object = struct {
gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
return di_ty;
}
- const name = try ty.nameAlloc(gpa);
+ const name = try ty.nameAlloc(gpa, target);
defer gpa.free(name);
const owner_decl = ty.getOwnerDecl();
const opaque_di_ty = dib.createForwardDeclType(
@@ -1089,7 +1089,7 @@ pub const Object = struct {
);
// The recursive call to `lowerDebugType` va `namespaceToDebugScope`
// means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(opaque_di_ty));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(opaque_di_ty), .{ .target = o.target });
return opaque_di_ty;
},
.Array => {
@@ -1100,7 +1100,7 @@ pub const Object = struct {
@intCast(c_int, ty.arrayLen()),
);
// The recursive call to `lowerDebugType` means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(array_di_ty));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(array_di_ty), .{ .target = o.target });
return array_di_ty;
},
.Vector => {
@@ -1111,11 +1111,11 @@ pub const Object = struct {
ty.vectorLen(),
);
// The recursive call to `lowerDebugType` means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(vector_di_ty));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(vector_di_ty), .{ .target = o.target });
return vector_di_ty;
},
.Optional => {
- const name = try ty.nameAlloc(gpa);
+ const name = try ty.nameAlloc(gpa, target);
defer gpa.free(name);
var buf: Type.Payload.ElemType = undefined;
const child_ty = ty.optionalChild(&buf);
@@ -1127,7 +1127,7 @@ pub const Object = struct {
if (ty.isPtrLikeOptional()) {
const ptr_di_ty = try o.lowerDebugType(child_ty, resolve);
// The recursive call to `lowerDebugType` means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty), .{ .target = o.target });
return ptr_di_ty;
}
@@ -1200,7 +1200,7 @@ pub const Object = struct {
);
dib.replaceTemporary(fwd_decl, full_di_ty);
// The recursive call to `lowerDebugType` means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });
return full_di_ty;
},
.ErrorUnion => {
@@ -1209,10 +1209,10 @@ pub const Object = struct {
if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
const err_set_di_ty = try o.lowerDebugType(err_set_ty, .full);
// The recursive call to `lowerDebugType` means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(err_set_di_ty));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(err_set_di_ty), .{ .target = o.target });
return err_set_di_ty;
}
- const name = try ty.nameAlloc(gpa);
+ const name = try ty.nameAlloc(gpa, target);
defer gpa.free(name);
const di_file: ?*llvm.DIFile = null;
const line = 0;
@@ -1282,7 +1282,7 @@ pub const Object = struct {
);
dib.replaceTemporary(fwd_decl, full_di_ty);
// The recursive call to `lowerDebugType` means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });
return full_di_ty;
},
.ErrorSet => {
@@ -1294,7 +1294,7 @@ pub const Object = struct {
},
.Struct => {
const compile_unit_scope = o.di_compile_unit.?.toScope();
- const name = try ty.nameAlloc(gpa);
+ const name = try ty.nameAlloc(gpa, target);
defer gpa.free(name);
if (ty.castTag(.@"struct")) |payload| {
@@ -1381,7 +1381,7 @@ pub const Object = struct {
);
dib.replaceTemporary(fwd_decl, full_di_ty);
// The recursive call to `lowerDebugType` means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });
return full_di_ty;
}
@@ -1395,7 +1395,7 @@ pub const Object = struct {
dib.replaceTemporary(fwd_decl, struct_di_ty);
// The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
// means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty), .{ .target = o.target });
return struct_di_ty;
}
}
@@ -1406,7 +1406,7 @@ pub const Object = struct {
dib.replaceTemporary(fwd_decl, struct_di_ty);
// The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
// means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty), .{ .target = o.target });
return struct_di_ty;
}
@@ -1461,13 +1461,13 @@ pub const Object = struct {
);
dib.replaceTemporary(fwd_decl, full_di_ty);
// The recursive call to `lowerDebugType` means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });
return full_di_ty;
},
.Union => {
const owner_decl = ty.getOwnerDecl();
- const name = try ty.nameAlloc(gpa);
+ const name = try ty.nameAlloc(gpa, target);
defer gpa.free(name);
const fwd_decl = opt_fwd_decl orelse blk: {
@@ -1489,7 +1489,7 @@ pub const Object = struct {
dib.replaceTemporary(fwd_decl, union_di_ty);
// The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
// means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(union_di_ty));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(union_di_ty), .{ .target = o.target });
return union_di_ty;
}
@@ -1603,7 +1603,7 @@ pub const Object = struct {
0,
);
// The recursive call to `lowerDebugType` means we can't use `gop` anymore.
- try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(fn_di_ty));
+ try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(fn_di_ty), .{ .target = o.target });
return fn_di_ty;
},
.ComptimeInt => unreachable,
@@ -1676,7 +1676,9 @@ pub const DeclGen = struct {
const decl = dg.decl;
assert(decl.has_tv);
- log.debug("gen: {s} type: {}, value: {}", .{ decl.name, decl.ty, decl.val.fmtDebug() });
+ log.debug("gen: {s} type: {}, value: {}", .{
+ decl.name, decl.ty.fmtDebug(), decl.val.fmtDebug(),
+ });
if (decl.val.castTag(.function)) |func_payload| {
_ = func_payload;
@@ -1990,7 +1992,7 @@ pub const DeclGen = struct {
},
.Opaque => switch (t.tag()) {
.@"opaque" => {
- const gop = try dg.object.type_map.getOrPut(gpa, t);
+ const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .target = target });
if (gop.found_existing) return gop.value_ptr.*;
// The Type memory is ephemeral; since we want to store a longer-lived
@@ -2051,7 +2053,7 @@ pub const DeclGen = struct {
return dg.context.intType(16);
},
.Struct => {
- const gop = try dg.object.type_map.getOrPut(gpa, t);
+ const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .target = target });
if (gop.found_existing) return gop.value_ptr.*;
// The Type memory is ephemeral; since we want to store a longer-lived
@@ -2174,7 +2176,7 @@ pub const DeclGen = struct {
return llvm_struct_ty;
},
.Union => {
- const gop = try dg.object.type_map.getOrPut(gpa, t);
+ const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .target = target });
if (gop.found_existing) return gop.value_ptr.*;
// The Type memory is ephemeral; since we want to store a longer-lived
@@ -2289,6 +2291,7 @@ pub const DeclGen = struct {
const llvm_type = try dg.llvmType(tv.ty);
return llvm_type.getUndef();
}
+ const target = dg.module.getTarget();
switch (tv.ty.zigTypeTag()) {
.Bool => {
@@ -2302,8 +2305,7 @@ pub const DeclGen = struct {
.decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),
else => {
var bigint_space: Value.BigIntSpace = undefined;
- const bigint = tv.val.toBigInt(&bigint_space);
- const target = dg.module.getTarget();
+ const bigint = tv.val.toBigInt(&bigint_space, target);
const int_info = tv.ty.intInfo(target);
assert(int_info.bits != 0);
const llvm_type = dg.context.intType(int_info.bits);
@@ -2331,9 +2333,8 @@ pub const DeclGen = struct {
const int_val = tv.enumToInt(&int_buffer);
var bigint_space: Value.BigIntSpace = undefined;
- const bigint = int_val.toBigInt(&bigint_space);
+ const bigint = int_val.toBigInt(&bigint_space, target);
- const target = dg.module.getTarget();
const int_info = tv.ty.intInfo(target);
const llvm_type = dg.context.intType(int_info.bits);
@@ -2356,7 +2357,6 @@ pub const DeclGen = struct {
},
.Float => {
const llvm_ty = try dg.llvmType(tv.ty);
- const target = dg.module.getTarget();
switch (tv.ty.floatBits(target)) {
16, 32, 64 => return llvm_ty.constReal(tv.val.toFloat(f64)),
80 => {
@@ -2414,7 +2414,7 @@ pub const DeclGen = struct {
},
.int_u64, .one, .int_big_positive => {
const llvm_usize = try dg.llvmType(Type.usize);
- const llvm_int = llvm_usize.constInt(tv.val.toUnsignedInt(), .False);
+ const llvm_int = llvm_usize.constInt(tv.val.toUnsignedInt(target), .False);
return llvm_int.constIntToPtr(try dg.llvmType(tv.ty));
},
.field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => {
@@ -2424,7 +2424,9 @@ pub const DeclGen = struct {
const llvm_type = try dg.llvmType(tv.ty);
return llvm_type.constNull();
},
- else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{ tv.ty, tag }),
+ else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{
+ tv.ty.fmtDebug(), tag,
+ }),
},
.Array => switch (tv.val.tag()) {
.bytes => {
@@ -2592,7 +2594,6 @@ pub const DeclGen = struct {
const llvm_struct_ty = try dg.llvmType(tv.ty);
const field_vals = tv.val.castTag(.aggregate).?.data;
const gpa = dg.gpa;
- const target = dg.module.getTarget();
if (tv.ty.isTupleOrAnonStruct()) {
const tuple = tv.ty.tupleFields();
@@ -2753,7 +2754,6 @@ pub const DeclGen = struct {
const llvm_union_ty = try dg.llvmType(tv.ty);
const tag_and_val = tv.val.castTag(.@"union").?.data;
- const target = dg.module.getTarget();
const layout = tv.ty.unionGetLayout(target);
if (layout.payload_size == 0) {
@@ -2763,7 +2763,7 @@ pub const DeclGen = struct {
});
}
const union_obj = tv.ty.cast(Type.Payload.Union).?.data;
- const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag).?;
+ const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, target).?;
assert(union_obj.haveFieldTypes());
const field_ty = union_obj.fields.values()[field_index].ty;
const payload = p: {
@@ -2892,7 +2892,7 @@ pub const DeclGen = struct {
.Frame,
.AnyFrame,
- => return dg.todo("implement const of type '{}'", .{tv.ty}),
+ => return dg.todo("implement const of type '{}'", .{tv.ty.fmtDebug()}),
}
}
@@ -2910,7 +2910,8 @@ pub const DeclGen = struct {
const ptr_ty = Type.initPayload(&ptr_ty_payload.base);
const llvm_ptr = try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl);
- if (ptr_child_ty.eql(decl.ty)) {
+ const target = dg.module.getTarget();
+ if (ptr_child_ty.eql(decl.ty, target)) {
return llvm_ptr;
} else {
return llvm_ptr.constBitCast((try dg.llvmType(ptr_child_ty)).pointerType(0));
@@ -2918,6 +2919,7 @@ pub const DeclGen = struct {
}
fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, ptr_child_ty: Type) Error!*const llvm.Value {
+ const target = dg.module.getTarget();
var bitcast_needed: bool = undefined;
const llvm_ptr = switch (ptr_val.tag()) {
.decl_ref_mut => {
@@ -2951,7 +2953,6 @@ pub const DeclGen = struct {
const field_index = @intCast(u32, field_ptr.field_index);
const llvm_u32 = dg.context.intType(32);
- const target = dg.module.getTarget();
switch (parent_ty.zigTypeTag()) {
.Union => {
bitcast_needed = true;
@@ -2974,7 +2975,7 @@ pub const DeclGen = struct {
},
.Struct => {
const field_ty = parent_ty.structFieldType(field_index);
- bitcast_needed = !field_ty.eql(ptr_child_ty);
+ bitcast_needed = !field_ty.eql(ptr_child_ty, target);
var ty_buf: Type.Payload.Pointer = undefined;
const llvm_field_index = llvmFieldIndex(parent_ty, field_index, target, &ty_buf).?;
@@ -2990,7 +2991,7 @@ pub const DeclGen = struct {
.elem_ptr => blk: {
const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr, elem_ptr.elem_ty);
- bitcast_needed = !elem_ptr.elem_ty.eql(ptr_child_ty);
+ bitcast_needed = !elem_ptr.elem_ty.eql(ptr_child_ty, target);
const llvm_usize = try dg.llvmType(Type.usize);
const indices: [1]*const llvm.Value = .{
@@ -3004,7 +3005,7 @@ pub const DeclGen = struct {
var buf: Type.Payload.ElemType = undefined;
const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf);
- bitcast_needed = !payload_ty.eql(ptr_child_ty);
+ bitcast_needed = !payload_ty.eql(ptr_child_ty, target);
if (!payload_ty.hasRuntimeBitsIgnoreComptime() or payload_ty.isPtrLikeOptional()) {
// In this case, we represent pointer to optional the same as pointer
@@ -3024,7 +3025,7 @@ pub const DeclGen = struct {
const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, eu_payload_ptr.container_ty);
const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();
- bitcast_needed = !payload_ty.eql(ptr_child_ty);
+ bitcast_needed = !payload_ty.eql(ptr_child_ty, target);
if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
// In this case, we represent pointer to error union the same as pointer
@@ -3053,12 +3054,13 @@ pub const DeclGen = struct {
tv: TypedValue,
decl: *Module.Decl,
) Error!*const llvm.Value {
+ const target = self.module.getTarget();
if (tv.ty.isSlice()) {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = tv.ty.slicePtrFieldType(&buf);
var slice_len: Value.Payload.U64 = .{
.base = .{ .tag = .int_u64 },
- .data = tv.val.sliceLen(),
+ .data = tv.val.sliceLen(target),
};
const fields: [2]*const llvm.Value = .{
try self.genTypedValue(.{
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig
index 0d9d1ae223..6072c59845 100644
--- a/src/codegen/spirv.zig
+++ b/src/codegen/spirv.zig
@@ -313,7 +313,7 @@ pub const DeclGen = struct {
// As of yet, there is no vector support in the self-hosted compiler.
.Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}),
// TODO: For which types is this the case?
- else => self.todo("implement arithmeticTypeInfo for {}", .{ty}),
+ else => self.todo("implement arithmeticTypeInfo for {}", .{ty.fmtDebug()}),
};
}
@@ -335,7 +335,7 @@ pub const DeclGen = struct {
const int_info = ty.intInfo(target);
const backing_bits = self.backingIntBits(int_info.bits) orelse {
// Integers too big for any native type are represented as "composite integers": An array of largestSupportedIntBits.
- return self.todo("implement composite int constants for {}", .{ty});
+ return self.todo("implement composite int constants for {}", .{ty.fmtDebug()});
};
// We can just use toSignedInt/toUnsignedInt here as it returns u64 - a type large enough to hold any
@@ -345,7 +345,7 @@ pub const DeclGen = struct {
// Note, value is required to be sign-extended, so we don't need to mask off the upper bits.
// See https://www.khronos.org/registry/SPIR-V/specs/unified1/SPIRV.html#Literal
- var int_bits = if (ty.isSignedInt()) @bitCast(u64, val.toSignedInt()) else val.toUnsignedInt();
+ var int_bits = if (ty.isSignedInt()) @bitCast(u64, val.toSignedInt()) else val.toUnsignedInt(target);
const value: spec.LiteralContextDependentNumber = switch (backing_bits) {
1...32 => .{ .uint32 = @truncate(u32, int_bits) },
@@ -388,7 +388,7 @@ pub const DeclGen = struct {
});
},
.Void => unreachable,
- else => return self.todo("constant generation of type {}", .{ty}),
+ else => return self.todo("constant generation of type {}", .{ty.fmtDebug()}),
}
return result_id.toRef();
@@ -414,7 +414,7 @@ pub const DeclGen = struct {
const backing_bits = self.backingIntBits(int_info.bits) orelse {
// TODO: Integers too big for any native type are represented as "composite integers":
// An array of largestSupportedIntBits.
- return self.todo("Implement composite int type {}", .{ty});
+ return self.todo("Implement composite int type {}", .{ty.fmtDebug()});
};
const payload = try self.spv.arena.create(SpvType.Payload.Int);
@@ -644,8 +644,10 @@ pub const DeclGen = struct {
const result_id = self.spv.allocId();
const result_type_id = try self.resolveTypeId(ty);
- assert(self.air.typeOf(bin_op.lhs).eql(ty));
- assert(self.air.typeOf(bin_op.rhs).eql(ty));
+ const target = self.getTarget();
+
+ assert(self.air.typeOf(bin_op.lhs).eql(ty, target));
+ assert(self.air.typeOf(bin_op.rhs).eql(ty, target));
// Binary operations are generally applicable to both scalar and vector operations
// in SPIR-V, but int and float versions of operations require different opcodes.
@@ -692,7 +694,7 @@ pub const DeclGen = struct {
const result_id = self.spv.allocId();
const result_type_id = try self.resolveTypeId(Type.initTag(.bool));
const op_ty = self.air.typeOf(bin_op.lhs);
- assert(op_ty.eql(self.air.typeOf(bin_op.rhs)));
+ assert(op_ty.eql(self.air.typeOf(bin_op.rhs), self.getTarget()));
// Comparisons are generally applicable to both scalar and vector operations in SPIR-V,
// but int and float versions of operations require different opcodes.