Address Spaces: Implement in LLVM codegen
This commit is contained in:
@@ -554,7 +554,8 @@ pub const DeclGen = struct {
|
||||
@intCast(c_uint, fn_param_len),
|
||||
.False,
|
||||
);
|
||||
const llvm_fn = self.llvmModule().addFunction(decl.name, fn_type);
|
||||
const llvm_addrspace = self.llvmAddressSpace(decl.@"addrspace");
|
||||
const llvm_fn = self.llvmModule().addFunctionInAddressSpace(decl.name, fn_type, llvm_addrspace);
|
||||
|
||||
const is_extern = decl.val.tag() == .extern_fn;
|
||||
if (!is_extern) {
|
||||
@@ -576,7 +577,27 @@ pub const DeclGen = struct {
|
||||
if (llvm_module.getNamedGlobal(decl.name)) |val| return val;
|
||||
// TODO: remove this redundant `llvmType`, it is also called in `genTypedValue`.
|
||||
const llvm_type = try self.llvmType(decl.ty);
|
||||
return llvm_module.addGlobal(llvm_type, decl.name);
|
||||
const llvm_addrspace = self.llvmAddressSpace(decl.@"addrspace");
|
||||
return llvm_module.addGlobalInAddressSpace(llvm_type, decl.name, llvm_addrspace);
|
||||
}
|
||||
|
||||
fn llvmAddressSpace(self: DeclGen, address_space: std.builtin.AddressSpace) c_uint {
|
||||
const target = self.module.getTarget();
|
||||
return switch (address_space) {
|
||||
.generic => llvm.address_space.default,
|
||||
.gs => switch (target.cpu.arch) {
|
||||
.i386, .x86_64 => llvm.address_space.x86.gs,
|
||||
else => unreachable,
|
||||
},
|
||||
.fs => switch (target.cpu.arch) {
|
||||
.i386, .x86_64 => llvm.address_space.x86.fs,
|
||||
else => unreachable,
|
||||
},
|
||||
.ss => switch (target.cpu.arch) {
|
||||
.i386, .x86_64 => llvm.address_space.x86.ss,
|
||||
else => unreachable,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn llvmType(self: *DeclGen, t: Type) error{ OutOfMemory, CodegenFail }!*const llvm.Type {
|
||||
@@ -605,7 +626,7 @@ pub const DeclGen = struct {
|
||||
.Bool => return self.context.intType(1),
|
||||
.Pointer => {
|
||||
if (t.isSlice()) {
|
||||
var buf: Type.Payload.ElemType = undefined;
|
||||
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
|
||||
const ptr_type = t.slicePtrFieldType(&buf);
|
||||
|
||||
const fields: [2]*const llvm.Type = .{
|
||||
@@ -615,7 +636,8 @@ pub const DeclGen = struct {
|
||||
return self.context.structType(&fields, fields.len, .False);
|
||||
} else {
|
||||
const elem_type = try self.llvmType(t.elemType());
|
||||
return elem_type.pointerType(0);
|
||||
const llvm_addrspace = self.llvmAddressSpace(t.ptrAddressSpace());
|
||||
return elem_type.pointerType(llvm_addrspace);
|
||||
}
|
||||
},
|
||||
.Array => {
|
||||
@@ -681,7 +703,8 @@ pub const DeclGen = struct {
|
||||
@intCast(c_uint, llvm_params.len),
|
||||
llvm.Bool.fromBool(is_var_args),
|
||||
);
|
||||
return llvm_fn_ty.pointerType(0);
|
||||
const llvm_addrspace = self.llvmAddressSpace(t.fnAddressSpace());
|
||||
return llvm_fn_ty.pointerType(llvm_addrspace);
|
||||
},
|
||||
.ComptimeInt => unreachable,
|
||||
.ComptimeFloat => unreachable,
|
||||
@@ -749,7 +772,7 @@ pub const DeclGen = struct {
|
||||
.Pointer => switch (tv.val.tag()) {
|
||||
.decl_ref => {
|
||||
if (tv.ty.isSlice()) {
|
||||
var buf: Type.Payload.ElemType = undefined;
|
||||
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
|
||||
const ptr_ty = tv.ty.slicePtrFieldType(&buf);
|
||||
var slice_len: Value.Payload.U64 = .{
|
||||
.base = .{ .tag = .int_u64 },
|
||||
@@ -779,12 +802,13 @@ pub const DeclGen = struct {
|
||||
decl.alive = true;
|
||||
const val = try self.resolveGlobalDecl(decl);
|
||||
const llvm_var_type = try self.llvmType(tv.ty);
|
||||
const llvm_type = llvm_var_type.pointerType(0);
|
||||
const llvm_addrspace = self.llvmAddressSpace(decl.@"addrspace");
|
||||
const llvm_type = llvm_var_type.pointerType(llvm_addrspace);
|
||||
return val.constBitCast(llvm_type);
|
||||
},
|
||||
.slice => {
|
||||
const slice = tv.val.castTag(.slice).?.data;
|
||||
var buf: Type.Payload.ElemType = undefined;
|
||||
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
|
||||
const fields: [2]*const llvm.Value = .{
|
||||
try self.genTypedValue(.{
|
||||
.ty = tv.ty.slicePtrFieldType(&buf),
|
||||
|
||||
Reference in New Issue
Block a user