aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/llvm.zig
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/llvm.zig
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/llvm.zig')
-rw-r--r--src/codegen/llvm.zig106
1 files changed, 54 insertions, 52 deletions
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(.{