From e09465fc49d86cc4aa9338106862d3e059ae3303 Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Sun, 29 Aug 2021 03:18:23 +0200 Subject: Address Spaces: Chaining tests --- src/codegen/llvm/bindings.zig | 59 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'src/codegen') diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index db1dcd22f2..67b39784b1 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -973,3 +973,62 @@ pub const TypeKind = enum(c_int) { BFloat, X86_AMX, }; + +pub const address_space = struct { + // See llvm/lib/Target/X86/X86.h + pub const x86_64 = x86; + pub const x86 = struct { + pub const gs = 256; + pub const fs = 257; + pub const ss = 258; + + pub const ptr32_sptr = 270; + pub const ptr32_uptr = 271; + pub const ptr64 = 272; + }; + + // See llvm/lib/Target/AVR/AVR.h + pub const avr = struct { + pub const data_memory = 0; + pub const program_memory = 1; + }; + + // See llvm/lib/Target/NVPTX/NVPTX.h + pub const nvptx = struct { + pub const generic = 0; + pub const global = 1; + pub const constant = 2; + pub const shared = 3; + pub const param = 4; + pub const local = 5; + }; + + // See llvm/lib/Target/AMDGPU/AMDGPU.h + pub const amdgpu = struct { + pub const flat = 0; + pub const global = 1; + pub const region = 2; + pub const local = 3; + pub const constant = 4; + pub const constant_32bit = 6; + pub const buffer_fat_pointer = 7; + pub const param_d = 6; + pub const param_i = 7; + pub const constant_buffer_0 = 8; + pub const constant_buffer_1 = 9; + pub const constant_buffer_2 = 10; + pub const constant_buffer_3 = 11; + pub const constant_buffer_4 = 12; + pub const constant_buffer_5 = 13; + pub const constant_buffer_6 = 14; + pub const constant_buffer_7 = 15; + pub const constant_buffer_8 = 16; + pub const constant_buffer_9 = 17; + pub const constant_buffer_10 = 18; + pub const constant_buffer_11 = 19; + pub const constant_buffer_12 = 20; + pub const constant_buffer_13 = 21; + pub const constant_buffer_14 = 22; + pub const constant_buffer_15 = 23; + }; +}; -- cgit v1.2.3 From ea393b2bca7587955df81d149caecc5522944d15 Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Sun, 29 Aug 2021 06:08:19 +0200 Subject: Address Spaces: Implement in LLVM codegen --- src/Module.zig | 2 +- src/Sema.zig | 2 +- src/codegen.zig | 2 +- src/codegen/c.zig | 2 +- src/codegen/llvm.zig | 40 ++++++++++++++++++++++++++++-------- src/codegen/llvm/bindings.zig | 8 ++++++++ src/type.zig | 48 +++++++++++++++++++++++++++++++++++-------- src/zig_llvm.cpp | 5 +++++ src/zig_llvm.h | 3 +++ 9 files changed, 91 insertions(+), 21 deletions(-) (limited to 'src/codegen') diff --git a/src/Module.zig b/src/Module.zig index b2cef0792a..1f9b5abcb9 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -4761,7 +4761,7 @@ pub fn populateTestFunctions(mod: *Module) !void { const builtin_file = (mod.importPkg(builtin_pkg) catch unreachable).file; const builtin_namespace = builtin_file.root_decl.?.namespace; const decl = builtin_namespace.decls.get("test_functions").?; - var buf: Type.Payload.ElemType = undefined; + var buf: Type.SlicePtrFieldTypeBuffer = undefined; const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf).elemType(); const array_decl = d: { diff --git a/src/Sema.zig b/src/Sema.zig index 4b75cc4c43..d6e926e604 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -8390,7 +8390,7 @@ fn fieldVal( .Pointer => switch (object_ty.ptrSize()) { .Slice => { if (mem.eql(u8, field_name, "ptr")) { - const buf = try arena.create(Type.Payload.ElemType); + const buf = try arena.create(Type.SlicePtrFieldTypeBuffer); const result_ty = object_ty.slicePtrFieldType(buf); if (try sema.resolveMaybeUndefVal(block, object_src, object)) |val| { if (val.isUndef()) return sema.addConstUndef(result_ty); diff --git a/src/codegen.zig b/src/codegen.zig index e0047de1f7..cbee79f139 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -4873,7 +4873,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { switch (typed_value.ty.zigTypeTag()) { .Pointer => switch (typed_value.ty.ptrSize()) { .Slice => { - var buf: Type.Payload.ElemType = undefined; + var buf: Type.SlicePtrFieldTypeBuffer = undefined; const ptr_type = typed_value.ty.slicePtrFieldType(&buf); const ptr_mcv = try self.genTypedValue(.{ .ty = ptr_type, .val = typed_value.val }); const slice_len = typed_value.val.sliceLen(); diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 5eb4388a9e..7a2dc343f7 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -251,7 +251,7 @@ pub const DeclGen = struct { try writer.writeByte('('); try dg.renderType(writer, t); try writer.writeAll("){"); - var buf: Type.Payload.ElemType = undefined; + var buf: Type.SlicePtrFieldTypeBuffer = undefined; try dg.renderValue(writer, t.slicePtrFieldType(&buf), val); try writer.writeAll(", "); try writer.print("{d}", .{val.sliceLen()}); diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 53e57ee219..8b7282160e 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -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), diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index 67b39784b1..e50589dee1 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -197,6 +197,9 @@ pub const Module = opaque { pub const addFunction = LLVMAddFunction; extern fn LLVMAddFunction(*const Module, Name: [*:0]const u8, FunctionTy: *const Type) *const Value; + pub const addFunctionInAddressSpace = ZigLLVMAddFunctionInAddressSpace; + extern fn ZigLLVMAddFunctionInAddressSpace(*const Module, Name: [*:0]const u8, FunctionTy: *const Type, AddressSpace: c_uint) *const Value; + pub const getNamedFunction = LLVMGetNamedFunction; extern fn LLVMGetNamedFunction(*const Module, Name: [*:0]const u8) ?*const Value; @@ -209,6 +212,9 @@ pub const Module = opaque { pub const addGlobal = LLVMAddGlobal; extern fn LLVMAddGlobal(M: *const Module, Ty: *const Type, Name: [*:0]const u8) *const Value; + pub const addGlobalInAddressSpace = LLVMAddGlobalInAddressSpace; + extern fn LLVMAddGlobalInAddressSpace(M: *const Module, Ty: *const Type, Name: [*:0]const u8, AddressSpace: c_uint) *const Value; + pub const getNamedGlobal = LLVMGetNamedGlobal; extern fn LLVMGetNamedGlobal(M: *const Module, Name: [*:0]const u8) ?*const Value; @@ -975,6 +981,8 @@ pub const TypeKind = enum(c_int) { }; pub const address_space = struct { + pub const default = 0; + // See llvm/lib/Target/X86/X86.h pub const x86_64 = x86; pub const x86 = struct { diff --git a/src/type.zig b/src/type.zig index b15026b595..9cda4aacf7 100644 --- a/src/type.zig +++ b/src/type.zig @@ -2161,42 +2161,72 @@ pub const Type = extern union { }; } - pub fn slicePtrFieldType(self: Type, buffer: *Payload.ElemType) Type { + pub const SlicePtrFieldTypeBuffer = union { + elem_type: Payload.ElemType, + pointer: Payload.Pointer, + }; + + pub fn slicePtrFieldType(self: Type, buffer: *SlicePtrFieldTypeBuffer) Type { switch (self.tag()) { .const_slice_u8 => return Type.initTag(.manyptr_const_u8), .const_slice => { const elem_type = self.castTag(.const_slice).?.data; - buffer.* = .{ + buffer.elem_type = .{ .base = .{ .tag = .many_const_pointer }, .data = elem_type, }; - return Type.initPayload(&buffer.base); + return Type.initPayload(&buffer.elem_type.base); }, .mut_slice => { const elem_type = self.castTag(.mut_slice).?.data; - buffer.* = .{ + buffer.elem_type = .{ .base = .{ .tag = .many_mut_pointer }, .data = elem_type, }; - return Type.initPayload(&buffer.base); + return Type.initPayload(&buffer.elem_type.base); }, .pointer => { const payload = self.castTag(.pointer).?.data; assert(payload.size == .Slice); - if (payload.mutable) { - buffer.* = .{ + + if (payload.sentinel != null or + payload.@"align" != 0 or + payload.@"addrspace" != .generic or + payload.bit_offset != 0 or + payload.host_size != 0 or + payload.@"allowzero" or + payload.@"volatile" + ) { + buffer.pointer = .{ + .data = .{ + .pointee_type = payload.pointee_type, + .sentinel = payload.sentinel, + .@"align" = payload.@"align", + .@"addrspace" = payload.@"addrspace", + .bit_offset = payload.bit_offset, + .host_size = payload.host_size, + .@"allowzero" = payload.@"allowzero", + .mutable = payload.mutable, + .@"volatile" = payload.@"volatile", + .size = .Many + }, + }; + return Type.initPayload(&buffer.pointer.base); + } else if (payload.mutable) { + buffer.elem_type = .{ .base = .{ .tag = .many_mut_pointer }, .data = payload.pointee_type, }; + return Type.initPayload(&buffer.elem_type.base); } else { - buffer.* = .{ + buffer.elem_type = .{ .base = .{ .tag = .many_const_pointer }, .data = payload.pointee_type, }; + return Type.initPayload(&buffer.elem_type.base); } - return Type.initPayload(&buffer.base); }, else => unreachable, diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index e1ab74f423..6e136161a6 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -416,6 +416,11 @@ ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref) { return wrap(Type::getTokenTy(*unwrap(context_ref))); } +LLVMValueRef ZigLLVMAddFunctionInAddressSpace(LLVMModuleRef M, const char *Name, LLVMTypeRef FunctionTy, unsigned AddressSpace) { + Function* func = Function::Create(unwrap(FunctionTy), GlobalValue::ExternalLinkage, AddressSpace, Name, unwrap(M)); + return wrap(func); +} + LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, ZigLLVM_CallingConv CC, ZigLLVM_CallAttr attr, const char *Name) { diff --git a/src/zig_llvm.h b/src/zig_llvm.h index be279d86e1..49a4c0e8fd 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -65,6 +65,9 @@ ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, co ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref); +ZIG_EXTERN_C LLVMValueRef ZigLLVMAddFunctionInAddressSpace(LLVMModuleRef M, const char *Name, + LLVMTypeRef FunctionTy, unsigned AddressSpace); + enum ZigLLVM_CallingConv { ZigLLVM_C = 0, ZigLLVM_Fast = 8, -- cgit v1.2.3 From e4ac063297fc9210ae3a97fa370ea8c6c216ec43 Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Fri, 3 Sep 2021 04:36:56 +0200 Subject: Address Spaces: Restructure llvmAddressSpace a bit --- src/codegen/llvm.zig | 19 +++++----- src/codegen/llvm/bindings.zig | 81 ++++++++++++++++++++++--------------------- 2 files changed, 49 insertions(+), 51 deletions(-) (limited to 'src/codegen') diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 8b7282160e..ce79d43fac 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -583,18 +583,15 @@ pub const DeclGen = struct { 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, + return switch (target.cpu.arch) { + .i386, .x86_64 => switch (address_space) { + .generic => llvm.address_space.default, + .gs => llvm.address_space.x86.gs, + .fs => llvm.address_space.x86.fs, + .ss => llvm.address_space.x86.ss, }, - .ss => switch (target.cpu.arch) { - .i386, .x86_64 => llvm.address_space.x86.ss, + else => switch (address_space) { + .generic => llvm.address_space.default, else => unreachable, }, }; diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index e50589dee1..ebb84cb05b 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -981,62 +981,63 @@ pub const TypeKind = enum(c_int) { }; pub const address_space = struct { - pub const default = 0; + pub const default: c_uint = 0; // See llvm/lib/Target/X86/X86.h pub const x86_64 = x86; pub const x86 = struct { - pub const gs = 256; - pub const fs = 257; - pub const ss = 258; + pub const gs: c_uint = 256; + pub const fs: c_uint = 257; + pub const ss: c_uint = 258; - pub const ptr32_sptr = 270; - pub const ptr32_uptr = 271; - pub const ptr64 = 272; + pub const ptr32_sptr: c_uint = 270; + pub const ptr32_uptr: c_uint = 271; + pub const ptr64: c_uint = 272; }; // See llvm/lib/Target/AVR/AVR.h pub const avr = struct { - pub const data_memory = 0; - pub const program_memory = 1; + pub const data_memory: c_uint = 0; + pub const program_memory: c_uint = 1; }; // See llvm/lib/Target/NVPTX/NVPTX.h pub const nvptx = struct { - pub const generic = 0; - pub const global = 1; - pub const constant = 2; - pub const shared = 3; - pub const param = 4; - pub const local = 5; + pub const generic: c_uint = 0; + pub const global: c_uint = 1; + pub const constant: c_uint = 2; + pub const shared: c_uint = 3; + pub const param: c_uint = 4; + pub const local: c_uint = 5; }; // See llvm/lib/Target/AMDGPU/AMDGPU.h pub const amdgpu = struct { - pub const flat = 0; - pub const global = 1; - pub const region = 2; - pub const local = 3; - pub const constant = 4; - pub const constant_32bit = 6; - pub const buffer_fat_pointer = 7; - pub const param_d = 6; - pub const param_i = 7; - pub const constant_buffer_0 = 8; - pub const constant_buffer_1 = 9; - pub const constant_buffer_2 = 10; - pub const constant_buffer_3 = 11; - pub const constant_buffer_4 = 12; - pub const constant_buffer_5 = 13; - pub const constant_buffer_6 = 14; - pub const constant_buffer_7 = 15; - pub const constant_buffer_8 = 16; - pub const constant_buffer_9 = 17; - pub const constant_buffer_10 = 18; - pub const constant_buffer_11 = 19; - pub const constant_buffer_12 = 20; - pub const constant_buffer_13 = 21; - pub const constant_buffer_14 = 22; - pub const constant_buffer_15 = 23; + pub const flat: c_uint = 0; + pub const global: c_uint = 1; + pub const region: c_uint = 2; + pub const local: c_uint = 3; + pub const constant: c_uint = 4; + pub const private: c_uint = 5; + pub const constant_32bit: c_uint = 6; + pub const buffer_fat_pointer: c_uint = 7; + pub const param_d: c_uint = 6; + pub const param_i: c_uint = 7; + pub const constant_buffer_0: c_uint = 8; + pub const constant_buffer_1: c_uint = 9; + pub const constant_buffer_2: c_uint = 10; + pub const constant_buffer_3: c_uint = 11; + pub const constant_buffer_4: c_uint = 12; + pub const constant_buffer_5: c_uint = 13; + pub const constant_buffer_6: c_uint = 14; + pub const constant_buffer_7: c_uint = 15; + pub const constant_buffer_8: c_uint = 16; + pub const constant_buffer_9: c_uint = 17; + pub const constant_buffer_10: c_uint = 18; + pub const constant_buffer_11: c_uint = 19; + pub const constant_buffer_12: c_uint = 20; + pub const constant_buffer_13: c_uint = 21; + pub const constant_buffer_14: c_uint = 22; + pub const constant_buffer_15: c_uint = 23; }; }; -- cgit v1.2.3 From 95e83afa98c5af89c6e5f40d559eb54c6c31a54e Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Mon, 6 Sep 2021 00:29:04 +0200 Subject: Address Spaces: Yeet address space on function prototypes This is a property which solely belongs to pointers to functions, not to the functions themselves. This cannot be properly represented by stage 2 at the moment, as type with zigTypeTag() == .Fn is overloaded for for function pointers and function prototypes. --- lib/std/builtin.zig | 1 - src/AstGen.zig | 18 ++----- src/Module.zig | 114 ++++++++++++++++++++++----------------------- src/Sema.zig | 121 ++++++++++++++++++++++++++++++++---------------- src/Zir.zig | 15 +----- src/codegen/llvm.zig | 3 +- src/stage1/ir.cpp | 54 +++++++-------------- src/target.zig | 18 +++++++ src/type.zig | 23 --------- test/compile_errors.zig | 20 -------- 10 files changed, 179 insertions(+), 208 deletions(-) (limited to 'src/codegen') diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index 11273eedeb..f01e7605ab 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -365,7 +365,6 @@ pub const TypeInfo = union(enum) { pub const Fn = struct { calling_convention: CallingConvention, alignment: comptime_int, - address_space: AddressSpace, is_generic: bool, is_var_args: bool, return_type: ?type, diff --git a/src/AstGen.zig b/src/AstGen.zig index 2e4671d92e..f1eabe4c0c 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -1117,9 +1117,9 @@ fn fnProtoExpr( break :inst try expr(gz, scope, align_rl, fn_proto.ast.align_expr); }; - const addrspace_inst: Zir.Inst.Ref = if (fn_proto.ast.addrspace_expr == 0) .none else inst: { - break :inst try expr(gz, scope, .{ .ty = .address_space_type }, fn_proto.ast.addrspace_expr); - }; + if (fn_proto.ast.addrspace_expr != 0) { + return astgen.failNode(fn_proto.ast.addrspace_expr, "addrspace not allowed on function prototypes", .{}); + } if (fn_proto.ast.section_expr != 0) { return astgen.failNode(fn_proto.ast.section_expr, "linksection not allowed on function prototypes", .{}); @@ -1153,7 +1153,6 @@ fn fnProtoExpr( .body = &[0]Zir.Inst.Index{}, .cc = cc, .align_inst = align_inst, - .addrspace_inst = addrspace_inst, .lib_name = 0, .is_var_args = is_var_args, .is_inferred_error = false, @@ -3089,7 +3088,6 @@ fn fnDecl( .body = &[0]Zir.Inst.Index{}, .cc = cc, .align_inst = .none, // passed in the per-decl data - .addrspace_inst = .none, // passed in the per-decl data .lib_name = lib_name, .is_var_args = is_var_args, .is_inferred_error = false, @@ -3129,7 +3127,6 @@ fn fnDecl( .body = fn_gz.instructions.items, .cc = cc, .align_inst = .none, // passed in the per-decl data - .addrspace_inst = .none, // passed in the per-decl data .lib_name = lib_name, .is_var_args = is_var_args, .is_inferred_error = is_inferred_error, @@ -3481,7 +3478,6 @@ fn testDecl( .body = fn_block.instructions.items, .cc = .none, .align_inst = .none, - .addrspace_inst = .none, .lib_name = 0, .is_var_args = false, .is_inferred_error = true, @@ -9217,7 +9213,6 @@ const GenZir = struct { ret_br: Zir.Inst.Index, cc: Zir.Inst.Ref, align_inst: Zir.Inst.Ref, - addrspace_inst: Zir.Inst.Ref, lib_name: u32, is_var_args: bool, is_inferred_error: bool, @@ -9261,7 +9256,7 @@ const GenZir = struct { if (args.cc != .none or args.lib_name != 0 or args.is_var_args or args.is_test or args.align_inst != .none or - args.addrspace_inst != .none or args.is_extern) + args.is_extern) { try astgen.extra.ensureUnusedCapacity( gpa, @@ -9269,7 +9264,6 @@ const GenZir = struct { args.ret_ty.len + args.body.len + src_locs.len + @boolToInt(args.lib_name != 0) + @boolToInt(args.align_inst != .none) + - @boolToInt(args.addrspace_inst != .none) + @boolToInt(args.cc != .none), ); const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.ExtendedFunc{ @@ -9287,9 +9281,6 @@ const GenZir = struct { if (args.align_inst != .none) { astgen.extra.appendAssumeCapacity(@enumToInt(args.align_inst)); } - if (args.addrspace_inst != .none) { - astgen.extra.appendAssumeCapacity(@enumToInt(args.addrspace_inst)); - } astgen.extra.appendSliceAssumeCapacity(args.ret_ty); astgen.extra.appendSliceAssumeCapacity(args.body); astgen.extra.appendSliceAssumeCapacity(src_locs); @@ -9308,7 +9299,6 @@ const GenZir = struct { .has_lib_name = args.lib_name != 0, .has_cc = args.cc != .none, .has_align = args.align_inst != .none, - .has_addrspace = args.addrspace_inst != .none, .is_test = args.is_test, .is_extern = args.is_extern, }), diff --git a/src/Module.zig b/src/Module.zig index 2313480aeb..500c34bcb0 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -3220,7 +3220,12 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { }; break :blk switch (decl.zirAddrspaceRef()) { - .none => .generic, + .none => switch (addrspace_ctx) { + .function => target_util.defaultAddressSpace(sema.mod.getTarget(), .function), + .variable => target_util.defaultAddressSpace(sema.mod.getTarget(), .global_mutable), + .constant => target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant), + else => unreachable, + }, else => |addrspace_ref| try sema.analyzeAddrspace(&block_scope, src, addrspace_ref, addrspace_ctx), }; }; @@ -4359,26 +4364,21 @@ pub fn simplePtrType( elem_ty: Type, mutable: bool, size: std.builtin.TypeInfo.Pointer.Size, + @"addrspace": std.builtin.AddressSpace, ) Allocator.Error!Type { - if (!mutable and size == .Slice and elem_ty.eql(Type.initTag(.u8))) { - return Type.initTag(.const_slice_u8); - } - // TODO stage1 type inference bug - const T = Type.Tag; - - const type_payload = try arena.create(Type.Payload.ElemType); - type_payload.* = .{ - .base = .{ - .tag = switch (size) { - .One => if (mutable) T.single_mut_pointer else T.single_const_pointer, - .Many => if (mutable) T.many_mut_pointer else T.many_const_pointer, - .C => if (mutable) T.c_mut_pointer else T.c_const_pointer, - .Slice => if (mutable) T.mut_slice else T.const_slice, - }, - }, - .data = elem_ty, - }; - return Type.initPayload(&type_payload.base); + return ptrType( + arena, + elem_ty, + null, + 0, + @"addrspace", + 0, + 0, + mutable, + false, + false, + size, + ); } pub fn ptrType( @@ -4396,47 +4396,43 @@ pub fn ptrType( ) Allocator.Error!Type { assert(host_size == 0 or bit_offset < host_size * 8); - // TODO check if type can be represented by simplePtrType - return Type.Tag.pointer.create(arena, .{ - .pointee_type = elem_ty, - .sentinel = sentinel, - .@"align" = @"align", - .@"addrspace" = @"addrspace", - .bit_offset = bit_offset, - .host_size = host_size, - .@"allowzero" = @"allowzero", - .mutable = mutable, - .@"volatile" = @"volatile", - .size = size, - }); -} + if (sentinel != null or @"align" != 0 or @"addrspace" != .generic or + bit_offset != 0 or host_size != 0 or @"allowzero" or @"volatile") + { + return Type.Tag.pointer.create(arena, .{ + .pointee_type = elem_ty, + .sentinel = sentinel, + .@"align" = @"align", + .@"addrspace" = @"addrspace", + .bit_offset = bit_offset, + .host_size = host_size, + .@"allowzero" = @"allowzero", + .mutable = mutable, + .@"volatile" = @"volatile", + .size = size, + }); + } -/// Create a pointer type with an explicit address space. This function might return results -/// of either simplePtrType or ptrType, depending on the address space. -/// TODO(Snektron) unify ptrType functions. -pub fn simplePtrTypeWithAddressSpace( - arena: *Allocator, - elem_ty: Type, - mutable: bool, - size: std.builtin.TypeInfo.Pointer.Size, - address_space: std.builtin.AddressSpace, -) Allocator.Error!Type { - switch (address_space) { - .generic => return simplePtrType(arena, elem_ty, mutable, size), - else => return ptrType( - arena, - elem_ty, - null, - 0, - address_space, - 0, - 0, - mutable, - false, - false, - size, - ), + if (!mutable and size == .Slice and elem_ty.eql(Type.initTag(.u8))) { + return Type.initTag(.const_slice_u8); } + + // TODO stage1 type inference bug + const T = Type.Tag; + + const type_payload = try arena.create(Type.Payload.ElemType); + type_payload.* = .{ + .base = .{ + .tag = switch (size) { + .One => if (mutable) T.single_mut_pointer else T.single_const_pointer, + .Many => if (mutable) T.many_mut_pointer else T.many_const_pointer, + .C => if (mutable) T.c_mut_pointer else T.c_const_pointer, + .Slice => if (mutable) T.mut_slice else T.const_slice, + }, + }, + .data = elem_ty, + }; + return Type.initPayload(&type_payload.base); } pub fn optionalType(arena: *Allocator, child_type: Type) Allocator.Error!Type { diff --git a/src/Sema.zig b/src/Sema.zig index 7f2b0e855e..f781138df5 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -1373,7 +1373,13 @@ fn zirRetPtr( return sema.analyzeComptimeAlloc(block, sema.fn_ret_ty); } - const ptr_type = try Module.simplePtrType(sema.arena, sema.fn_ret_ty, true, .One); + const ptr_type = try Module.simplePtrType( + sema.arena, + sema.fn_ret_ty, + true, + .One, + target_util.defaultAddressSpace(sema.mod.getTarget(), .local), + ); return block.addTy(.alloc, ptr_type); } @@ -1521,7 +1527,13 @@ fn zirAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node }; const var_decl_src = inst_data.src(); const var_type = try sema.resolveType(block, ty_src, inst_data.operand); - const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One); + const ptr_type = try Module.simplePtrType( + sema.arena, + var_type, + true, + .One, + target_util.defaultAddressSpace(sema.mod.getTarget(), .local), + ); try sema.requireRuntimeBlock(block, var_decl_src); return block.addTy(.alloc, ptr_type); } @@ -1538,7 +1550,13 @@ fn zirAllocMut(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr return sema.analyzeComptimeAlloc(block, var_type); } try sema.validateVarType(block, ty_src, var_type); - const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One); + const ptr_type = try Module.simplePtrType( + sema.arena, + var_type, + true, + .One, + target_util.defaultAddressSpace(sema.mod.getTarget(), .local), + ); try sema.requireRuntimeBlock(block, var_decl_src); return block.addTy(.alloc, ptr_type); } @@ -1598,7 +1616,13 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde try sema.mod.declareDeclDependency(sema.owner_decl, decl); const final_elem_ty = try decl.ty.copy(sema.arena); - const final_ptr_ty = try Module.simplePtrType(sema.arena, final_elem_ty, true, .One); + const final_ptr_ty = try Module.simplePtrType( + sema.arena, + final_elem_ty, + true, + .One, + target_util.defaultAddressSpace(sema.mod.getTarget(), .local), + ); const final_ptr_ty_inst = try sema.addType(final_ptr_ty); sema.air_instructions.items(.data)[ptr_inst].ty_pl.ty = final_ptr_ty_inst; @@ -1620,7 +1644,13 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde try sema.validateVarType(block, ty_src, final_elem_ty); } // Change it to a normal alloc. - const final_ptr_ty = try Module.simplePtrType(sema.arena, final_elem_ty, true, .One); + const final_ptr_ty = try Module.simplePtrType( + sema.arena, + final_elem_ty, + true, + .One, + target_util.defaultAddressSpace(sema.mod.getTarget(), .local), + ); sema.air_instructions.set(ptr_inst, .{ .tag = .alloc, .data = .{ .ty = final_ptr_ty }, @@ -1774,7 +1804,14 @@ fn zirStoreToBlockPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co } const ptr = sema.resolveInst(bin_inst.lhs); const value = sema.resolveInst(bin_inst.rhs); - const ptr_ty = try Module.simplePtrType(sema.arena, sema.typeOf(value), true, .One); + const ptr_ty = try Module.simplePtrType( + sema.arena, + sema.typeOf(value), + true, + .One, + // TODO figure out which address space is appropriate here + target_util.defaultAddressSpace(sema.mod.getTarget(), .local), + ); // TODO detect when this store should be done at compile-time. For example, // if expressions should force it when the condition is compile-time known. const src: LazySrcLoc = .unneeded; @@ -1821,7 +1858,14 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) // for the inferred allocation. try inferred_alloc.data.stored_inst_list.append(sema.arena, operand); // Create a runtime bitcast instruction with exactly the type the pointer wants. - const ptr_ty = try Module.simplePtrType(sema.arena, operand_ty, true, .One); + const ptr_ty = try Module.simplePtrType( + sema.arena, + operand_ty, + true, + .One, + // TODO figure out which address space is appropriate here + target_util.defaultAddressSpace(sema.mod.getTarget(), .local), + ); const bitcasted_ptr = try block.addTyOp(.bitcast, ptr_ty, ptr); return sema.storePtr(block, src, bitcasted_ptr, operand); } @@ -3658,7 +3702,7 @@ fn zirOptionalPayloadPtr( } const child_type = try opt_type.optionalChildAlloc(sema.arena); - const child_pointer = try Module.simplePtrTypeWithAddressSpace( + const child_pointer = try Module.simplePtrType( sema.arena, child_type, !optional_ptr_ty.isConstPtr(), @@ -3779,7 +3823,7 @@ fn zirErrUnionPayloadPtr( return sema.mod.fail(&block.base, src, "expected error union type, found {}", .{operand_ty.elemType()}); const payload_ty = operand_ty.elemType().errorUnionPayload(); - const operand_pointer_ty = try Module.simplePtrTypeWithAddressSpace( + const operand_pointer_ty = try Module.simplePtrType( sema.arena, payload_ty, !operand_ty.isConstPtr(), @@ -3907,7 +3951,6 @@ fn zirFunc( ret_ty_body, cc, Value.initTag(.null_value), - .generic, false, inferred_error_set, false, @@ -3924,7 +3967,6 @@ fn funcCommon( ret_ty_body: []const Zir.Inst.Index, cc: std.builtin.CallingConvention, align_val: Value, - address_space: std.builtin.AddressSpace, var_args: bool, inferred_error_set: bool, is_extern: bool, @@ -3982,7 +4024,7 @@ fn funcCommon( // Hot path for some common function types. // TODO can we eliminate some of these Type tag values? seems unnecessarily complicated. if (!is_generic and block.params.items.len == 0 and !var_args and - align_val.tag() == .null_value and !inferred_error_set and address_space == .generic) + align_val.tag() == .null_value and !inferred_error_set) { if (bare_return_type.zigTypeTag() == .NoReturn and cc == .Unspecified) { break :fn_ty Type.initTag(.fn_noreturn_no_args); @@ -4034,7 +4076,6 @@ fn funcCommon( .comptime_params = comptime_params.ptr, .return_type = return_type, .cc = cc, - .@"addrspace" = address_space, .is_var_args = var_args, .is_generic = is_generic, }); @@ -6413,7 +6454,7 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr switch (ty.zigTypeTag()) { .Fn => { - const field_values = try sema.arena.alloc(Value, 7); + const field_values = try sema.arena.alloc(Value, 6); // calling_convention: CallingConvention, field_values[0] = try Value.Tag.enum_field_index.create( sema.arena, @@ -6421,19 +6462,14 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr ); // alignment: comptime_int, field_values[1] = try Value.Tag.int_u64.create(sema.arena, ty.abiAlignment(target)); - // address_space: AddressSpace, - field_values[2] = try Value.Tag.enum_field_index.create( - sema.arena, - @enumToInt(ty.fnAddressSpace()), - ); // is_generic: bool, - field_values[3] = Value.initTag(.bool_false); // TODO + field_values[2] = Value.initTag(.bool_false); // TODO // is_var_args: bool, - field_values[4] = Value.initTag(.bool_false); // TODO + field_values[3] = Value.initTag(.bool_false); // TODO // return_type: ?type, - field_values[5] = try Value.Tag.ty.create(sema.arena, ty.fnReturnType()); + field_values[4] = try Value.Tag.ty.create(sema.arena, ty.fnReturnType()); // args: []const FnArg, - field_values[6] = Value.initTag(.null_value); // TODO + field_values[5] = Value.initTag(.null_value); // TODO return sema.addConstant( type_info_ty, @@ -8063,7 +8099,6 @@ fn zirFuncExtended( const src: LazySrcLoc = .{ .node_offset = extra.data.src_node }; const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = extra.data.src_node }; const align_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at align - const addrspace_src: LazySrcLoc = src; // TODO(Snektron) add a LazySrcLoc that points at addrspace const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small); var extra_index: usize = extra.end; @@ -8088,12 +8123,6 @@ fn zirFuncExtended( break :blk align_tv.val; } else Value.initTag(.null_value); - const address_space: std.builtin.AddressSpace = if (small.has_addrspace) blk: { - const addrspace_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); - extra_index += 1; - break :blk try sema.analyzeAddrspace(block, addrspace_src, addrspace_ref, .function); - } else .generic; - const ret_ty_body = sema.code.extra[extra_index..][0..extra.data.ret_body_len]; extra_index += ret_ty_body.len; @@ -8116,7 +8145,6 @@ fn zirFuncExtended( ret_ty_body, cc, align_val, - address_space, is_var_args, is_inferred_error, is_extern, @@ -8309,7 +8337,13 @@ fn panicWithMsg( const panic_fn = try sema.getBuiltin(block, src, "panic"); const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace"); const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty); - const ptr_stack_trace_ty = try Module.simplePtrType(arena, stack_trace_ty, true, .One); + const ptr_stack_trace_ty = try Module.simplePtrType( + arena, + stack_trace_ty, + true, + .One, + target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant), // TODO might need a place that is more dynamic + ); const null_stack_trace = try sema.addConstant( try Module.optionalType(arena, ptr_stack_trace_ty), Value.initTag(.null_value), @@ -8788,7 +8822,7 @@ fn structFieldPtr( const field_index = struct_obj.fields.getIndex(field_name) orelse return sema.failWithBadFieldAccess(block, struct_obj, field_name_src, field_name); const field = struct_obj.fields.values()[field_index]; - const ptr_field_ty = try Module.simplePtrTypeWithAddressSpace( + const ptr_field_ty = try Module.simplePtrType( arena, field.ty, struct_ptr_ty.ptrIsMutable(), @@ -8893,7 +8927,7 @@ fn unionFieldPtr( return sema.failWithBadUnionFieldAccess(block, union_obj, field_name_src, field_name); const field = union_obj.fields.values()[field_index]; - const ptr_field_ty = try Module.simplePtrTypeWithAddressSpace( + const ptr_field_ty = try Module.simplePtrType( arena, field.ty, union_ptr_ty.ptrIsMutable(), @@ -9075,7 +9109,7 @@ fn elemPtrArray( ) CompileError!Air.Inst.Ref { const array_ptr_ty = sema.typeOf(array_ptr); const pointee_type = array_ptr_ty.elemType().elemType(); - const result_ty = try Module.simplePtrTypeWithAddressSpace( + const result_ty = try Module.simplePtrType( sema.arena, pointee_type, array_ptr_ty.ptrIsMutable(), @@ -9581,11 +9615,11 @@ fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref { const decl_tv = try decl.typedValue(); if (decl_tv.val.castTag(.variable)) |payload| { const variable = payload.data; - const ty = try Module.simplePtrTypeWithAddressSpace(sema.arena, decl_tv.ty, variable.is_mutable, .One, decl.@"addrspace"); + const ty = try Module.simplePtrType(sema.arena, decl_tv.ty, variable.is_mutable, .One, decl.@"addrspace"); return sema.addConstant(ty, try Value.Tag.decl_ref.create(sema.arena, decl)); } return sema.addConstant( - try Module.simplePtrTypeWithAddressSpace(sema.arena, decl_tv.ty, false, .One, decl.@"addrspace"), + try Module.simplePtrType(sema.arena, decl_tv.ty, false, .One, decl.@"addrspace"), try Value.Tag.decl_ref.create(sema.arena, decl), ); } @@ -9608,8 +9642,9 @@ fn analyzeRef( } try sema.requireRuntimeBlock(block, src); - const ptr_type = try Module.simplePtrType(sema.arena, operand_ty, false, .One); - const mut_ptr_type = try Module.simplePtrType(sema.arena, operand_ty, true, .One); + const address_space = target_util.defaultAddressSpace(sema.mod.getTarget(), .local); + const ptr_type = try Module.simplePtrType(sema.arena, operand_ty, false, .One, address_space); + const mut_ptr_type = try Module.simplePtrType(sema.arena, operand_ty, true, .One, address_space); const alloc = try block.addTy(.alloc, mut_ptr_type); try sema.storePtr(block, src, alloc, operand); @@ -10955,7 +10990,13 @@ fn analyzeComptimeAlloc( block: *Scope.Block, var_type: Type, ) CompileError!Air.Inst.Ref { - const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One); + const ptr_type = try Module.simplePtrType( + sema.arena, + var_type, + true, + .One, + target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant), + ); var anon_decl = try block.startAnonDecl(); defer anon_decl.deinit(); diff --git a/src/Zir.zig b/src/Zir.zig index 50c53e5485..28fa92d4a0 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -2309,7 +2309,6 @@ pub const Inst = struct { /// 0. lib_name: u32, // null terminated string index, if has_lib_name is set /// 1. cc: Ref, // if has_cc is set /// 2. align: Ref, // if has_align is set - /// 3. addrspace: Ref, // if has_addrspace is set /// 3. return_type: Index // for each ret_body_len /// 4. body: Index // for each body_len /// 5. src_locs: Func.SrcLocs // if body_len != 0 @@ -2327,10 +2326,9 @@ pub const Inst = struct { has_lib_name: bool, has_cc: bool, has_align: bool, - has_addrspace: bool, is_test: bool, is_extern: bool, - _: u8 = undefined, + _: u9 = undefined, }; }; @@ -4483,7 +4481,6 @@ const Writer = struct { false, .none, .none, - .none, body, src, src_locs, @@ -4512,11 +4509,6 @@ const Writer = struct { extra_index += 1; break :blk align_inst; }; - const addrspace_inst: Inst.Ref = if (!small.has_addrspace) .none else blk: { - const addrspace_inst = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]); - extra_index += 1; - break :blk addrspace_inst; - }; const ret_ty_body = self.code.extra[extra_index..][0..extra.data.ret_body_len]; extra_index += ret_ty_body.len; @@ -4536,7 +4528,6 @@ const Writer = struct { small.is_extern, cc, align_inst, - addrspace_inst, body, src, src_locs, @@ -4619,7 +4610,6 @@ const Writer = struct { is_extern: bool, cc: Inst.Ref, align_inst: Inst.Ref, - addrspace_inst: Inst.Ref, body: []const Inst.Index, src: LazySrcLoc, src_locs: Zir.Inst.Func.SrcLocs, @@ -4637,7 +4627,6 @@ const Writer = struct { try self.writeOptionalInstRef(stream, ", cc=", cc); try self.writeOptionalInstRef(stream, ", align=", align_inst); - try self.writeOptionalInstRef(stream, ", addrspace=", addrspace_inst); try self.writeFlag(stream, ", vargs", var_args); try self.writeFlag(stream, ", extern", is_extern); try self.writeFlag(stream, ", inferror", inferred_error_set); @@ -4915,7 +4904,6 @@ fn findDeclsInner( extra_index += @boolToInt(small.has_lib_name); extra_index += @boolToInt(small.has_cc); extra_index += @boolToInt(small.has_align); - extra_index += @boolToInt(small.has_addrspace); const body = zir.extra[extra_index..][0..extra.data.body_len]; return zir.findDeclsBody(list, body); }, @@ -5119,7 +5107,6 @@ pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo { extra_index += @boolToInt(small.has_lib_name); extra_index += @boolToInt(small.has_cc); extra_index += @boolToInt(small.has_align); - extra_index += @boolToInt(small.has_addrspace); const ret_ty_body = zir.extra[extra_index..][0..extra.data.ret_body_len]; extra_index += ret_ty_body.len; const body = zir.extra[extra_index..][0..extra.data.body_len]; diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index ce79d43fac..e2d6e964cf 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -700,7 +700,8 @@ pub const DeclGen = struct { @intCast(c_uint, llvm_params.len), llvm.Bool.fromBool(is_var_args), ); - const llvm_addrspace = self.llvmAddressSpace(t.fnAddressSpace()); + // TODO make .Fn not both a pointer type and a prototype + const llvm_addrspace = self.llvmAddressSpace(.generic); return llvm_fn_ty.pointerType(llvm_addrspace); }, .ComptimeInt => unreachable, diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index a41384cee6..87dfee1bf2 100644 --- a/src/stage1/ir.cpp +++ b/src/stage1/ir.cpp @@ -18483,35 +18483,30 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour fields[1]->special = ConstValSpecialStatic; fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; bigint_init_unsigned(&fields[1]->data.x_bigint, get_ptr_align(ira->codegen, type_entry)); - // address_space: AddressSpace - ensure_field_index(result->type, "address_space", 2); - fields[2]->special = ConstValSpecialStatic; - fields[2]->type = get_builtin_type(ira->codegen, "AddressSpace"); - bigint_init_unsigned(&fields[2]->data.x_enum_tag, AddressSpaceGeneric); // is_generic: bool - ensure_field_index(result->type, "is_generic", 3); + ensure_field_index(result->type, "is_generic", 2); bool is_generic = type_entry->data.fn.is_generic; - fields[3]->special = ConstValSpecialStatic; - fields[3]->type = ira->codegen->builtin_types.entry_bool; - fields[3]->data.x_bool = is_generic; + fields[2]->special = ConstValSpecialStatic; + fields[2]->type = ira->codegen->builtin_types.entry_bool; + fields[2]->data.x_bool = is_generic; // is_varargs: bool - ensure_field_index(result->type, "is_var_args", 4); + ensure_field_index(result->type, "is_var_args", 3); bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args; - fields[4]->special = ConstValSpecialStatic; - fields[4]->type = ira->codegen->builtin_types.entry_bool; - fields[4]->data.x_bool = is_varargs; + fields[3]->special = ConstValSpecialStatic; + fields[3]->type = ira->codegen->builtin_types.entry_bool; + fields[3]->data.x_bool = is_varargs; // return_type: ?type - ensure_field_index(result->type, "return_type", 5); - fields[5]->special = ConstValSpecialStatic; - fields[5]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); + ensure_field_index(result->type, "return_type", 4); + fields[4]->special = ConstValSpecialStatic; + fields[4]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); if (type_entry->data.fn.fn_type_id.return_type == nullptr) - fields[5]->data.x_optional = nullptr; + fields[4]->data.x_optional = nullptr; else { ZigValue *return_type = ira->codegen->pass1_arena->create(); return_type->special = ConstValSpecialStatic; return_type->type = ira->codegen->builtin_types.entry_type; return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type; - fields[5]->data.x_optional = return_type; + fields[4]->data.x_optional = return_type; } // args: []TypeInfo.FnArg ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); @@ -18526,7 +18521,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour fn_arg_array->data.x_array.special = ConstArraySpecialNone; fn_arg_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate(fn_arg_count); - init_const_slice(ira->codegen, fields[6], fn_arg_array, 0, fn_arg_count, false, nullptr); + init_const_slice(ira->codegen, fields[5], fn_arg_array, 0, fn_arg_count, false, nullptr); for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; @@ -19330,22 +19325,9 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_ if (alignment == nullptr) return ira->codegen->invalid_inst_gen->value->type; - ZigValue *as_value = get_const_field(ira, source_node, payload, "address_space", 2); - if (as_value == nullptr) - return ira->codegen->invalid_inst_gen->value->type; - assert(as_value->special == ConstValSpecialStatic); - assert(as_value->type == get_builtin_type(ira->codegen, "AddressSpace")); - AddressSpace as = (AddressSpace)bigint_as_u32(&as_value->data.x_enum_tag); - if (as != AddressSpaceGeneric) { - ir_add_error_node(ira, source_node, buf_sprintf( - "address space '%s' not available in stage 1 compiler, must be .generic", - address_space_name(as))); - return ira->codegen->invalid_inst_gen->value->type; - } - Error err; bool is_generic; - if ((err = get_const_field_bool(ira, source_node, payload, "is_generic", 3, &is_generic))) + if ((err = get_const_field_bool(ira, source_node, payload, "is_generic", 2, &is_generic))) return ira->codegen->invalid_inst_gen->value->type; if (is_generic) { ir_add_error_node(ira, source_node, buf_sprintf("TypeInfo.Fn.is_generic must be false for @Type")); @@ -19353,20 +19335,20 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_ } bool is_var_args; - if ((err = get_const_field_bool(ira, source_node, payload, "is_var_args", 4, &is_var_args))) + if ((err = get_const_field_bool(ira, source_node, payload, "is_var_args", 3, &is_var_args))) return ira->codegen->invalid_inst_gen->value->type; if (is_var_args && cc != CallingConventionC) { ir_add_error_node(ira, source_node, buf_sprintf("varargs functions must have C calling convention")); return ira->codegen->invalid_inst_gen->value->type; } - ZigType *return_type = get_const_field_meta_type_optional(ira, source_node, payload, "return_type", 5); + ZigType *return_type = get_const_field_meta_type_optional(ira, source_node, payload, "return_type", 4); if (return_type == nullptr) { ir_add_error_node(ira, source_node, buf_sprintf("TypeInfo.Fn.return_type must be non-null for @Type")); return ira->codegen->invalid_inst_gen->value->type; } - ZigValue *args_value = get_const_field(ira, source_node, payload, "args", 6); + ZigValue *args_value = get_const_field(ira, source_node, payload, "args", 5); if (args_value == nullptr) return ira->codegen->invalid_inst_gen->value->type; assert(args_value->special == ConstValSpecialStatic); diff --git a/src/target.zig b/src/target.zig index c9d7e1742b..09e65ff909 100644 --- a/src/target.zig +++ b/src/target.zig @@ -544,3 +544,21 @@ pub fn largestAtomicBits(target: std.Target) u32 { .x86_64 => 128, }; } + +pub fn defaultAddressSpace( + target: std.Target, + context: enum { + /// Query the default address space for global constant values. + global_constant, + /// Query the default address space for global mutable values. + global_mutable, + /// Query the default address space for function-local values. + local, + /// Query the default address space for functions themselves. + function, + }, +) std.builtin.AddressSpace { + _ = target; + _ = context; + return .generic; +} diff --git a/src/type.zig b/src/type.zig index e8a9d059d0..f85ee12d4b 100644 --- a/src/type.zig +++ b/src/type.zig @@ -530,8 +530,6 @@ pub const Type = extern union { return false; if (a.fnCallingConvention() != b.fnCallingConvention()) return false; - if (a.fnAddressSpace() != b.fnAddressSpace()) - return false; const a_param_len = a.fnParamLen(); const b_param_len = b.fnParamLen(); if (a_param_len != b_param_len) @@ -838,7 +836,6 @@ pub const Type = extern union { .return_type = try payload.return_type.copy(allocator), .param_types = param_types, .cc = payload.cc, - .@"addrspace" = payload.@"addrspace", .is_var_args = payload.is_var_args, .is_generic = payload.is_generic, .comptime_params = comptime_params.ptr, @@ -1001,9 +998,6 @@ pub const Type = extern union { try writer.writeAll(") callconv(."); try writer.writeAll(@tagName(payload.cc)); try writer.writeAll(") "); - if (payload.@"addrspace" != .generic) { - try writer.print("addrspace(.{s}) ", .{@tagName(payload.@"addrspace")}); - } ty = payload.return_type; continue; }, @@ -2730,18 +2724,6 @@ pub const Type = extern union { }; } - pub fn fnAddressSpace(self: Type) std.builtin.AddressSpace { - return switch (self.tag()) { - .fn_noreturn_no_args => .generic, - .fn_void_no_args => .generic, - .fn_naked_noreturn_no_args => .generic, - .fn_ccc_void_no_args => .generic, - .function => self.castTag(.function).?.data.@"addrspace", - - else => unreachable, - }; - } - pub fn fnInfo(ty: Type) Payload.Function.Data { return switch (ty.tag()) { .fn_noreturn_no_args => .{ @@ -2749,7 +2731,6 @@ pub const Type = extern union { .comptime_params = undefined, .return_type = initTag(.noreturn), .cc = .Unspecified, - .@"addrspace" = .generic, .is_var_args = false, .is_generic = false, }, @@ -2758,7 +2739,6 @@ pub const Type = extern union { .comptime_params = undefined, .return_type = initTag(.void), .cc = .Unspecified, - .@"addrspace" = .generic, .is_var_args = false, .is_generic = false, }, @@ -2767,7 +2747,6 @@ pub const Type = extern union { .comptime_params = undefined, .return_type = initTag(.noreturn), .cc = .Naked, - .@"addrspace" = .generic, .is_var_args = false, .is_generic = false, }, @@ -2776,7 +2755,6 @@ pub const Type = extern union { .comptime_params = undefined, .return_type = initTag(.void), .cc = .C, - .@"addrspace" = .generic, .is_var_args = false, .is_generic = false, }, @@ -3648,7 +3626,6 @@ pub const Type = extern union { comptime_params: [*]bool, return_type: Type, cc: std.builtin.CallingConvention, - @"addrspace": std.builtin.AddressSpace, is_var_args: bool, is_generic: bool, diff --git a/test/compile_errors.zig b/test/compile_errors.zig index f2fa20d722..058fd1f2db 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -410,7 +410,6 @@ pub fn addCases(ctx: *TestContext) !void { \\ .Fn = .{ \\ .calling_convention = .Unspecified, \\ .alignment = 0, - \\ .address_space = .generic, \\ .is_generic = true, \\ .is_var_args = false, \\ .return_type = u0, @@ -427,7 +426,6 @@ pub fn addCases(ctx: *TestContext) !void { \\ .Fn = .{ \\ .calling_convention = .Unspecified, \\ .alignment = 0, - \\ .address_space = .generic, \\ .is_generic = false, \\ .is_var_args = true, \\ .return_type = u0, @@ -444,7 +442,6 @@ pub fn addCases(ctx: *TestContext) !void { \\ .Fn = .{ \\ .calling_convention = .Unspecified, \\ .alignment = 0, - \\ .address_space = .generic, \\ .is_generic = false, \\ .is_var_args = false, \\ .return_type = null, @@ -456,23 +453,6 @@ pub fn addCases(ctx: *TestContext) !void { "tmp.zig:1:20: error: TypeInfo.Fn.return_type must be non-null for @Type", }); - ctx.objErrStage1("@Type(.Fn) with invalid address space ", - \\const Foo = @Type(.{ - \\ .Fn = .{ - \\ .calling_convention = .Unspecified, - \\ .alignment = 0, - \\ .address_space = .fs, - \\ .is_generic = false, - \\ .is_var_args = false, - \\ .return_type = u0, - \\ .args = &[_]@import("std").builtin.TypeInfo.FnArg{}, - \\ }, - \\}); - \\comptime { _ = Foo; } - , &[_][]const u8{ - "tmp.zig:1:20: error: address space 'fs' not available in stage 1 compiler, must be .generic", - }); - ctx.objErrStage1("@Type for union with opaque field", \\const TypeInfo = @import("std").builtin.TypeInfo; \\const Untagged = @Type(.{ -- cgit v1.2.3