diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-07-03 22:09:30 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-07-18 19:02:05 -0700 |
| commit | db33ee45b7261c9ec62a1087cfc9377bc4e7aa8f (patch) | |
| tree | 81e1f629c296a8a9c9573879382586dac3784737 /src/codegen | |
| parent | 70c71935c7c9f20353dc2a50b497b752d70d3452 (diff) | |
| download | zig-db33ee45b7261c9ec62a1087cfc9377bc4e7aa8f.tar.gz zig-db33ee45b7261c9ec62a1087cfc9377bc4e7aa8f.zip | |
rework generic function calls
Abridged summary:
* Move `Module.Fn` into `InternPool`.
* Delete a lot of confusing and problematic `Sema` logic related to
generic function calls.
This commit removes `Module.Fn` and replaces it with two new
`InternPool.Tag` values:
* `func_decl` - corresponding to a function declared in the source
code. This one contains line/column numbers, zir_body_inst, etc.
* `func_instance` - one for each monomorphization of a generic
function. Contains a reference to the `func_decl` from whence the
instantiation came, along with the `comptime` parameter values (or
types in the case of `anytype`)
Since `InternPool` provides deduplication on these values, these fields
are now deleted from `Module`:
* `monomorphed_func_keys`
* `monomorphed_funcs`
* `align_stack_fns`
Instead of these, Sema logic for generic function instantiation now
unconditionally evaluates the function prototype expression for every
generic callsite. This is technically required in order for type
coercions to work. The previous code had some dubious, probably wrong
hacks to make things work, such as `hashUncoerced`. I'm not 100% sure
how we were able to eliminate that function and still pass all the
behavior tests, but I'm pretty sure things were still broken without
doing type coercion for every generic function call argument.
After the function prototype is evaluated, it produces a deduplicated
`func_instance` `InternPool.Index` which can then be used for the
generic function call.
Some other nice things made by this simplification are the removal of
`comptime_args_fn_inst` and `preallocated_new_func` from `Sema`, and the
messy logic associated with them.
I have not yet been able to measure the perf of this against master
branch. On one hand, it reduces memory usage and pointer chasing of the
most heavily used `InternPool` Tag - function bodies - but on the other
hand, it does evaluate function prototype expressions more than before.
We will soon find out.
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/c.zig | 16 | ||||
| -rw-r--r-- | src/codegen/c/type.zig | 14 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 118 | ||||
| -rw-r--r-- | src/codegen/spirv.zig | 20 |
4 files changed, 93 insertions, 75 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index b685263759..6533173805 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -257,7 +257,8 @@ pub fn fmtIdent(ident: []const u8) std.fmt.Formatter(formatIdent) { return .{ .data = ident }; } -/// This data is available when outputting .c code for a `Module.Fn.Index`. +/// This data is available when outputting .c code for a `InternPool.Index` +/// that corresponds to `func`. /// It is not available when generating .h file. pub const Function = struct { air: Air, @@ -268,7 +269,7 @@ pub const Function = struct { next_block_index: usize = 0, object: Object, lazy_fns: LazyFnMap, - func_index: Module.Fn.Index, + func_index: InternPool.Index, /// All the locals, to be emitted at the top of the function. locals: std.ArrayListUnmanaged(Local) = .{}, /// Which locals are available for reuse, based on Type. @@ -1487,6 +1488,7 @@ pub const DeclGen = struct { ) !void { const store = &dg.ctypes.set; const mod = dg.module; + const ip = &mod.intern_pool; const fn_decl = mod.declPtr(fn_decl_index); const fn_cty_idx = try dg.typeToIndex(fn_decl.ty, kind); @@ -1499,7 +1501,7 @@ pub const DeclGen = struct { else => unreachable, } } - if (fn_decl.val.getFunction(mod)) |func| if (func.is_cold) try w.writeAll("zig_cold "); + if (fn_decl.val.getFunction(mod)) |func| if (func.analysis(ip).is_cold) try w.writeAll("zig_cold "); if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn "); const trailing = try renderTypePrefix( @@ -1744,7 +1746,7 @@ pub const DeclGen = struct { return switch (mod.intern_pool.indexToKey(tv.val.ip_index)) { .variable => |variable| mod.decl_exports.contains(variable.decl), .extern_func => true, - .func => |func| mod.decl_exports.contains(mod.funcPtr(func.index).owner_decl), + .func => |func| mod.decl_exports.contains(func.owner_decl), else => unreachable, }; } @@ -4161,7 +4163,7 @@ fn airCall( const callee_val = (try f.air.value(pl_op.operand, mod)) orelse break :known; break :fn_decl switch (mod.intern_pool.indexToKey(callee_val.ip_index)) { .extern_func => |extern_func| extern_func.decl, - .func => |func| mod.funcPtr(func.index).owner_decl, + .func => |func| func.owner_decl, .ptr => |ptr| switch (ptr.addr) { .decl => |decl| decl, else => break :known, @@ -4238,9 +4240,9 @@ fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue { const ty_fn = f.air.instructions.items(.data)[inst].ty_fn; const mod = f.object.dg.module; const writer = f.object.writer(); - const function = mod.funcPtr(ty_fn.func); + const owner_decl = mod.funcOwnerDeclPtr(ty_fn.func); try writer.print("/* dbg func:{s} */\n", .{ - mod.intern_pool.stringToSlice(mod.declPtr(function.owner_decl).name), + mod.intern_pool.stringToSlice(owner_decl.name), }); return .none; } diff --git a/src/codegen/c/type.zig b/src/codegen/c/type.zig index dbdb65ac29..01540a9f2d 100644 --- a/src/codegen/c/type.zig +++ b/src/codegen/c/type.zig @@ -1722,6 +1722,7 @@ pub const CType = extern union { .Fn => { const info = mod.typeToFunc(ty).?; + const ip = &mod.intern_pool; if (!info.is_generic) { if (lookup.isMutable()) { const param_kind: Kind = switch (kind) { @@ -1730,7 +1731,7 @@ pub const CType = extern union { .payload => unreachable, }; _ = try lookup.typeToIndex(info.return_type.toType(), param_kind); - for (info.param_types) |param_type| { + for (info.param_types.get(ip)) |param_type| { if (!param_type.toType().hasRuntimeBitsIgnoreComptime(mod)) continue; _ = try lookup.typeToIndex(param_type.toType(), param_kind); } @@ -2014,6 +2015,7 @@ pub const CType = extern union { .function, .varargs_function, => { + const ip = &mod.intern_pool; const info = mod.typeToFunc(ty).?; assert(!info.is_generic); const param_kind: Kind = switch (kind) { @@ -2023,14 +2025,14 @@ pub const CType = extern union { }; var c_params_len: usize = 0; - for (info.param_types) |param_type| { + for (info.param_types.get(ip)) |param_type| { if (!param_type.toType().hasRuntimeBitsIgnoreComptime(mod)) continue; c_params_len += 1; } const params_pl = try arena.alloc(Index, c_params_len); var c_param_i: usize = 0; - for (info.param_types) |param_type| { + for (info.param_types.get(ip)) |param_type| { if (!param_type.toType().hasRuntimeBitsIgnoreComptime(mod)) continue; params_pl[c_param_i] = store.set.typeToIndex(param_type.toType(), mod, param_kind).?; c_param_i += 1; @@ -2147,6 +2149,7 @@ pub const CType = extern union { => { if (ty.zigTypeTag(mod) != .Fn) return false; + const ip = &mod.intern_pool; const info = mod.typeToFunc(ty).?; assert(!info.is_generic); const data = cty.cast(Payload.Function).?.data; @@ -2160,7 +2163,7 @@ pub const CType = extern union { return false; var c_param_i: usize = 0; - for (info.param_types) |param_type| { + for (info.param_types.get(ip)) |param_type| { if (!param_type.toType().hasRuntimeBitsIgnoreComptime(mod)) continue; if (c_param_i >= data.param_types.len) return false; @@ -2202,6 +2205,7 @@ pub const CType = extern union { autoHash(hasher, t); const mod = self.lookup.getModule(); + const ip = &mod.intern_pool; switch (t) { .fwd_anon_struct, .fwd_anon_union, @@ -2270,7 +2274,7 @@ pub const CType = extern union { }; self.updateHasherRecurse(hasher, info.return_type.toType(), param_kind); - for (info.param_types) |param_type| { + for (info.param_types.get(ip)) |param_type| { if (!param_type.toType().hasRuntimeBitsIgnoreComptime(mod)) continue; self.updateHasherRecurse(hasher, param_type.toType(), param_kind); } diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index ec456e53a7..d26af7be7f 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -867,14 +867,15 @@ pub const Object = struct { pub fn updateFunc( o: *Object, mod: *Module, - func_index: Module.Fn.Index, + func_index: InternPool.Index, air: Air, liveness: Liveness, ) !void { - const func = mod.funcPtr(func_index); + const func = mod.funcInfo(func_index); const decl_index = func.owner_decl; const decl = mod.declPtr(decl_index); const target = mod.getTarget(); + const ip = &mod.intern_pool; var dg: DeclGen = .{ .object = o, @@ -885,24 +886,23 @@ pub const Object = struct { const llvm_func = try o.resolveLlvmFunction(decl_index); - if (mod.align_stack_fns.get(func_index)) |align_info| { - o.addFnAttrInt(llvm_func, "alignstack", align_info.alignment.toByteUnitsOptional().?); + if (func.analysis(ip).is_noinline) { o.addFnAttr(llvm_func, "noinline"); } else { - Object.removeFnAttr(llvm_func, "alignstack"); - if (!func.is_noinline) Object.removeFnAttr(llvm_func, "noinline"); + Object.removeFnAttr(llvm_func, "noinline"); } - if (func.is_cold) { - o.addFnAttr(llvm_func, "cold"); + if (func.analysis(ip).stack_alignment.toByteUnitsOptional()) |alignment| { + o.addFnAttrInt(llvm_func, "alignstack", alignment); + o.addFnAttr(llvm_func, "noinline"); } else { - Object.removeFnAttr(llvm_func, "cold"); + Object.removeFnAttr(llvm_func, "alignstack"); } - if (func.is_noinline) { - o.addFnAttr(llvm_func, "noinline"); + if (func.analysis(ip).is_cold) { + o.addFnAttr(llvm_func, "cold"); } else { - Object.removeFnAttr(llvm_func, "noinline"); + Object.removeFnAttr(llvm_func, "cold"); } // TODO: disable this if safety is off for the function scope @@ -921,7 +921,7 @@ pub const Object = struct { o.addFnAttrString(llvm_func, "no-stack-arg-probe", ""); } - if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |section| + if (ip.stringToSliceUnwrap(decl.@"linksection")) |section| llvm_func.setSection(section); // Remove all the basic blocks of a function in order to start over, generating @@ -968,7 +968,7 @@ pub const Object = struct { .byval => { assert(!it.byval_attr); const param_index = it.zig_index - 1; - const param_ty = fn_info.param_types[param_index].toType(); + const param_ty = fn_info.param_types.get(ip)[param_index].toType(); const param = llvm_func.getParam(llvm_arg_i); try args.ensureUnusedCapacity(1); @@ -987,7 +987,7 @@ pub const Object = struct { llvm_arg_i += 1; }, .byref => { - const param_ty = fn_info.param_types[it.zig_index - 1].toType(); + const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); const param_llvm_ty = try o.lowerType(param_ty); const param = llvm_func.getParam(llvm_arg_i); const alignment = param_ty.abiAlignment(mod); @@ -1006,7 +1006,7 @@ pub const Object = struct { } }, .byref_mut => { - const param_ty = fn_info.param_types[it.zig_index - 1].toType(); + const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); const param_llvm_ty = try o.lowerType(param_ty); const param = llvm_func.getParam(llvm_arg_i); const alignment = param_ty.abiAlignment(mod); @@ -1026,7 +1026,7 @@ pub const Object = struct { }, .abi_sized_int => { assert(!it.byval_attr); - const param_ty = fn_info.param_types[it.zig_index - 1].toType(); + const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); const param = llvm_func.getParam(llvm_arg_i); llvm_arg_i += 1; @@ -1053,7 +1053,7 @@ pub const Object = struct { }, .slice => { assert(!it.byval_attr); - const param_ty = fn_info.param_types[it.zig_index - 1].toType(); + const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); const ptr_info = param_ty.ptrInfo(mod); if (math.cast(u5, it.zig_index - 1)) |i| { @@ -1083,7 +1083,7 @@ pub const Object = struct { .multiple_llvm_types => { assert(!it.byval_attr); const field_types = it.llvm_types_buffer[0..it.llvm_types_len]; - const param_ty = fn_info.param_types[it.zig_index - 1].toType(); + const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); const param_llvm_ty = try o.lowerType(param_ty); const param_alignment = param_ty.abiAlignment(mod); const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, param_alignment, target); @@ -1114,7 +1114,7 @@ pub const Object = struct { args.appendAssumeCapacity(casted); }, .float_array => { - const param_ty = fn_info.param_types[it.zig_index - 1].toType(); + const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); const param_llvm_ty = try o.lowerType(param_ty); const param = llvm_func.getParam(llvm_arg_i); llvm_arg_i += 1; @@ -1132,7 +1132,7 @@ pub const Object = struct { } }, .i32_array, .i64_array => { - const param_ty = fn_info.param_types[it.zig_index - 1].toType(); + const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); const param_llvm_ty = try o.lowerType(param_ty); const param = llvm_func.getParam(llvm_arg_i); llvm_arg_i += 1; @@ -1168,7 +1168,7 @@ pub const Object = struct { const decl_di_ty = try o.lowerDebugType(decl.ty, .full); const subprogram = dib.createFunction( di_file.?.toScope(), - mod.intern_pool.stringToSlice(decl.name), + ip.stringToSlice(decl.name), llvm_func.getValueName(), di_file.?, line_number, @@ -1460,6 +1460,7 @@ pub const Object = struct { const target = o.target; const dib = o.di_builder.?; const mod = o.module; + const ip = &mod.intern_pool; switch (ty.zigTypeTag(mod)) { .Void, .NoReturn => { const di_type = dib.createBasicType("void", 0, DW.ATE.signed); @@ -1492,7 +1493,6 @@ pub const Object = struct { return enum_di_ty; } - const ip = &mod.intern_pool; const enum_type = ip.indexToKey(ty.toIntern()).enum_type; const enumerators = try gpa.alloc(*llvm.DIEnumerator, enum_type.names.len); @@ -1518,7 +1518,7 @@ pub const Object = struct { if (@sizeOf(usize) == @sizeOf(u64)) { enumerators[i] = dib.createEnumerator2( field_name_z, - @as(c_uint, @intCast(bigint.limbs.len)), + @intCast(bigint.limbs.len), bigint.limbs.ptr, int_info.bits, int_info.signedness == .unsigned, @@ -2320,8 +2320,8 @@ pub const Object = struct { try param_di_types.append(try o.lowerDebugType(ptr_ty, .full)); } - for (0..mod.typeToFunc(ty).?.param_types.len) |i| { - const param_ty = mod.typeToFunc(ty).?.param_types[i].toType(); + for (0..fn_info.param_types.len) |i| { + const param_ty = fn_info.param_types.get(ip)[i].toType(); if (!param_ty.hasRuntimeBitsIgnoreComptime(mod)) continue; if (isByRef(param_ty, mod)) { @@ -2475,9 +2475,10 @@ pub const Object = struct { const fn_type = try o.lowerType(zig_fn_type); const fqn = try decl.getFullyQualifiedName(mod); + const ip = &mod.intern_pool; const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); - const llvm_fn = o.llvm_module.addFunctionInAddressSpace(mod.intern_pool.stringToSlice(fqn), fn_type, llvm_addrspace); + const llvm_fn = o.llvm_module.addFunctionInAddressSpace(ip.stringToSlice(fqn), fn_type, llvm_addrspace); gop.value_ptr.* = llvm_fn; const is_extern = decl.isExtern(mod); @@ -2486,8 +2487,8 @@ pub const Object = struct { llvm_fn.setUnnamedAddr(.True); } else { if (target.isWasm()) { - o.addFnAttrString(llvm_fn, "wasm-import-name", mod.intern_pool.stringToSlice(decl.name)); - if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| { + o.addFnAttrString(llvm_fn, "wasm-import-name", ip.stringToSlice(decl.name)); + if (ip.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| { if (!std.mem.eql(u8, lib_name, "c")) { o.addFnAttrString(llvm_fn, "wasm-import-module", lib_name); } @@ -2546,13 +2547,13 @@ pub const Object = struct { while (it.next()) |lowering| switch (lowering) { .byval => { const param_index = it.zig_index - 1; - const param_ty = fn_info.param_types[param_index].toType(); + const param_ty = fn_info.param_types.get(ip)[param_index].toType(); if (!isByRef(param_ty, mod)) { o.addByValParamAttrs(llvm_fn, param_ty, param_index, fn_info, it.llvm_index - 1); } }, .byref => { - const param_ty = fn_info.param_types[it.zig_index - 1]; + const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1]; const param_llvm_ty = try o.lowerType(param_ty.toType()); const alignment = param_ty.toType().abiAlignment(mod); o.addByRefParamAttrs(llvm_fn, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty); @@ -3031,6 +3032,7 @@ pub const Object = struct { fn lowerTypeFn(o: *Object, fn_ty: Type) Allocator.Error!*llvm.Type { const mod = o.module; + const ip = &mod.intern_pool; const fn_info = mod.typeToFunc(fn_ty).?; const llvm_ret_ty = try lowerFnRetTy(o, fn_info); @@ -3052,19 +3054,19 @@ pub const Object = struct { while (it.next()) |lowering| switch (lowering) { .no_bits => continue, .byval => { - const param_ty = fn_info.param_types[it.zig_index - 1].toType(); + const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); try llvm_params.append(try o.lowerType(param_ty)); }, .byref, .byref_mut => { try llvm_params.append(o.context.pointerType(0)); }, .abi_sized_int => { - const param_ty = fn_info.param_types[it.zig_index - 1].toType(); + const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); const abi_size = @as(c_uint, @intCast(param_ty.abiSize(mod))); try llvm_params.append(o.context.intType(abi_size * 8)); }, .slice => { - const param_ty = fn_info.param_types[it.zig_index - 1].toType(); + const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); const ptr_ty = if (param_ty.zigTypeTag(mod) == .Optional) param_ty.optionalChild(mod).slicePtrFieldType(mod) else @@ -3083,7 +3085,7 @@ pub const Object = struct { try llvm_params.append(o.context.intType(16)); }, .float_array => |count| { - const param_ty = fn_info.param_types[it.zig_index - 1].toType(); + const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(param_ty, mod).?); const field_count = @as(c_uint, @intCast(count)); const arr_ty = float_ty.arrayType(field_count); @@ -3137,8 +3139,7 @@ pub const Object = struct { return llvm_type.getUndef(); } - const val_key = mod.intern_pool.indexToKey(tv.val.toIntern()); - switch (val_key) { + switch (mod.intern_pool.indexToKey(tv.val.toIntern())) { .int_type, .ptr_type, .array_type, @@ -3175,12 +3176,14 @@ pub const Object = struct { .enum_literal, .empty_enum_value, => unreachable, // non-runtime values - .extern_func, .func => { - const fn_decl_index = switch (val_key) { - .extern_func => |extern_func| extern_func.decl, - .func => |func| mod.funcPtr(func.index).owner_decl, - else => unreachable, - }; + .extern_func => |extern_func| { + const fn_decl_index = extern_func.decl; + const fn_decl = mod.declPtr(fn_decl_index); + try mod.markDeclAlive(fn_decl); + return o.resolveLlvmFunction(fn_decl_index); + }, + .func => |func| { + const fn_decl_index = func.owner_decl; const fn_decl = mod.declPtr(fn_decl_index); try mod.markDeclAlive(fn_decl); return o.resolveLlvmFunction(fn_decl_index); @@ -4598,6 +4601,7 @@ pub const FuncGen = struct { const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len])); const o = self.dg.object; const mod = o.module; + const ip = &mod.intern_pool; const callee_ty = self.typeOf(pl_op.operand); const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) { .Fn => callee_ty, @@ -4801,14 +4805,14 @@ pub const FuncGen = struct { while (it.next()) |lowering| switch (lowering) { .byval => { const param_index = it.zig_index - 1; - const param_ty = fn_info.param_types[param_index].toType(); + const param_ty = fn_info.param_types.get(ip)[param_index].toType(); if (!isByRef(param_ty, mod)) { o.addByValParamAttrs(call, param_ty, param_index, fn_info, it.llvm_index - 1); } }, .byref => { const param_index = it.zig_index - 1; - const param_ty = fn_info.param_types[param_index].toType(); + const param_ty = fn_info.param_types.get(ip)[param_index].toType(); const param_llvm_ty = try o.lowerType(param_ty); const alignment = param_ty.abiAlignment(mod); o.addByRefParamAttrs(call, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty); @@ -4828,7 +4832,7 @@ pub const FuncGen = struct { .slice => { assert(!it.byval_attr); - const param_ty = fn_info.param_types[it.zig_index - 1].toType(); + const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); const ptr_info = param_ty.ptrInfo(mod); const llvm_arg_i = it.llvm_index - 2; @@ -4930,7 +4934,7 @@ pub const FuncGen = struct { fg.context.pointerType(0).constNull(), null_opt_addr_global, }; - const panic_func = mod.funcPtrUnwrap(mod.panic_func_index).?; + const panic_func = mod.funcInfo(mod.panic_func_index); const panic_decl = mod.declPtr(panic_func.owner_decl); const fn_info = mod.typeToFunc(panic_decl.ty).?; const panic_global = try o.resolveLlvmFunction(panic_func.owner_decl); @@ -6030,7 +6034,7 @@ pub const FuncGen = struct { const ty_fn = self.air.instructions.items(.data)[inst].ty_fn; const mod = o.module; - const func = mod.funcPtr(ty_fn.func); + const func = mod.funcInfo(ty_fn.func); const decl_index = func.owner_decl; const decl = mod.declPtr(decl_index); const di_file = try o.getDIFile(self.gpa, mod.namespacePtr(decl.src_namespace).file_scope); @@ -6039,7 +6043,7 @@ pub const FuncGen = struct { const cur_debug_location = self.builder.getCurrentDebugLocation2(); try self.dbg_inlined.append(self.gpa, .{ - .loc = @as(*llvm.DILocation, @ptrCast(cur_debug_location)), + .loc = @ptrCast(cur_debug_location), .scope = self.di_scope.?, .base_line = self.base_line, }); @@ -6090,8 +6094,7 @@ pub const FuncGen = struct { const ty_fn = self.air.instructions.items(.data)[inst].ty_fn; const mod = o.module; - const func = mod.funcPtr(ty_fn.func); - const decl = mod.declPtr(func.owner_decl); + const decl = mod.funcOwnerDeclPtr(ty_fn.func); const di_file = try o.getDIFile(self.gpa, mod.namespacePtr(decl.src_namespace).file_scope); self.di_file = di_file; const old = self.dbg_inlined.pop(); @@ -8137,12 +8140,13 @@ pub const FuncGen = struct { } const src_index = self.air.instructions.items(.data)[inst].arg.src_index; - const func = self.dg.decl.getOwnedFunction(mod).?; + const func_index = self.dg.decl.getOwnedFunctionIndex(); + const func = mod.funcInfo(func_index); const lbrace_line = mod.declPtr(func.owner_decl).src_line + func.lbrace_line + 1; const lbrace_col = func.lbrace_column + 1; const di_local_var = dib.createParameterVariable( self.di_scope.?, - func.getParamName(mod, src_index).ptr, // TODO test 0 bit args + mod.getParamName(func_index, src_index).ptr, // TODO test 0 bit args self.di_file.?, lbrace_line, try o.lowerDebugType(inst_ty, .full), @@ -10888,13 +10892,17 @@ const ParamTypeIterator = struct { pub fn next(it: *ParamTypeIterator) ?Lowering { if (it.zig_index >= it.fn_info.param_types.len) return null; - const ty = it.fn_info.param_types[it.zig_index]; + const mod = it.object.module; + const ip = &mod.intern_pool; + const ty = it.fn_info.param_types.get(ip)[it.zig_index]; it.byval_attr = false; return nextInner(it, ty.toType()); } /// `airCall` uses this instead of `next` so that it can take into account variadic functions. pub fn nextCall(it: *ParamTypeIterator, fg: *FuncGen, args: []const Air.Inst.Ref) ?Lowering { + const mod = it.object.module; + const ip = &mod.intern_pool; if (it.zig_index >= it.fn_info.param_types.len) { if (it.zig_index >= args.len) { return null; @@ -10902,7 +10910,7 @@ const ParamTypeIterator = struct { return nextInner(it, fg.typeOf(args[it.zig_index])); } } else { - return nextInner(it, it.fn_info.param_types[it.zig_index].toType()); + return nextInner(it, it.fn_info.param_types.get(ip)[it.zig_index].toType()); } } diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index eb697ea94e..9f84781966 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -238,7 +238,7 @@ pub const DeclGen = struct { if (ty.zigTypeTag(mod) == .Fn) { const fn_decl_index = switch (mod.intern_pool.indexToKey(val.ip_index)) { .extern_func => |extern_func| extern_func.decl, - .func => |func| mod.funcPtr(func.index).owner_decl, + .func => |func| func.owner_decl, else => unreachable, }; const spv_decl_index = try self.resolveDecl(fn_decl_index); @@ -255,13 +255,14 @@ pub const DeclGen = struct { /// Fetch or allocate a result id for decl index. This function also marks the decl as alive. /// Note: Function does not actually generate the decl. fn resolveDecl(self: *DeclGen, decl_index: Module.Decl.Index) !SpvModule.Decl.Index { - const decl = self.module.declPtr(decl_index); - try self.module.markDeclAlive(decl); + const mod = self.module; + const decl = mod.declPtr(decl_index); + try mod.markDeclAlive(decl); const entry = try self.decl_link.getOrPut(decl_index); if (!entry.found_existing) { // TODO: Extern fn? - const kind: SpvModule.DeclKind = if (decl.val.getFunctionIndex(self.module) != .none) + const kind: SpvModule.DeclKind = if (decl.val.isFuncBody(mod)) .func else .global; @@ -1268,6 +1269,7 @@ pub const DeclGen = struct { }, .Fn => switch (repr) { .direct => { + const ip = &mod.intern_pool; const fn_info = mod.typeToFunc(ty).?; // TODO: Put this somewhere in Sema.zig if (fn_info.is_var_args) @@ -1275,8 +1277,8 @@ pub const DeclGen = struct { const param_ty_refs = try self.gpa.alloc(CacheRef, fn_info.param_types.len); defer self.gpa.free(param_ty_refs); - for (param_ty_refs, 0..) |*param_type, i| { - param_type.* = try self.resolveType(fn_info.param_types[i].toType(), .direct); + for (param_ty_refs, fn_info.param_types.get(ip)) |*param_type, fn_param_type| { + param_type.* = try self.resolveType(fn_param_type.toType(), .direct); } const return_ty_ref = try self.resolveType(fn_info.return_type.toType(), .direct); @@ -1576,6 +1578,7 @@ pub const DeclGen = struct { fn genDecl(self: *DeclGen) !void { const mod = self.module; + const ip = &mod.intern_pool; const decl = mod.declPtr(self.decl_index); const spv_decl_index = try self.resolveDecl(self.decl_index); @@ -1594,7 +1597,8 @@ pub const DeclGen = struct { const fn_info = mod.typeToFunc(decl.ty).?; try self.args.ensureUnusedCapacity(self.gpa, fn_info.param_types.len); - for (fn_info.param_types) |param_type| { + for (0..fn_info.param_types.len) |i| { + const param_type = fn_info.param_types.get(ip)[i]; const param_type_id = try self.resolveTypeId(param_type.toType()); const arg_result_id = self.spv.allocId(); try self.func.prologue.emit(self.spv.gpa, .OpFunctionParameter, .{ @@ -1621,7 +1625,7 @@ pub const DeclGen = struct { try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {}); try self.spv.addFunction(spv_decl_index, self.func); - const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(self.module)); + const fqn = ip.stringToSlice(try decl.getFullyQualifiedName(self.module)); try self.spv.sections.debug_names.emit(self.gpa, .OpName, .{ .target = decl_id, |
