authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-23 21:59:58-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-24 02:29:49-07:00
loga5e15eced0e9cb00871966ede74eed9b3a07183c
tree3664db39697a0d16ba491b13d9b0655e4ae705f8
parentd82ab4fd8af33b546676e0c6b77d8644f139d630

LLVM: move many DeclGen methods to Object

DeclGen/FuncGen methods are for things that pertain to a particular declaration or function, while Object methods are for things that pertain to the entire LLVM Module. Many methods were in the wrong category, such as type and value lowering. This is a prerequisite commit for a local branch I am working on, which needs to be able to call lowerValue() without the context of any particular function or declaration.

1 files changed, 971 insertions(+), 852 deletions(-)

src/codegen/llvm.zig+971-852
......@@ -568,20 +568,20 @@ pub const Object = struct {
568568 return slice.ptr;
569569 }
570570
571 fn genErrorNameTable(self: *Object) !void {
572 // If self.error_name_table is null, there was no instruction that actually referenced the error table.
573 const error_name_table_ptr_global = self.error_name_table orelse return;
571 fn genErrorNameTable(o: *Object) !void {
572 // If o.error_name_table is null, there was no instruction that actually referenced the error table.
573 const error_name_table_ptr_global = o.error_name_table orelse return;
574574
575 const mod = self.module;
575 const mod = o.module;
576576 const target = mod.getTarget();
577577
578 const llvm_ptr_ty = self.context.pointerType(0); // TODO: Address space
579 const llvm_usize_ty = self.context.intType(target.ptrBitWidth());
578 const llvm_ptr_ty = o.context.pointerType(0); // TODO: Address space
579 const llvm_usize_ty = o.context.intType(target.ptrBitWidth());
580580 const type_fields = [_]*llvm.Type{
581581 llvm_ptr_ty,
582582 llvm_usize_ty,
583583 };
584 const llvm_slice_ty = self.context.structType(&type_fields, type_fields.len, .False);
584 const llvm_slice_ty = o.context.structType(&type_fields, type_fields.len, .False);
585585 const slice_ty = Type.slice_const_u8_sentinel_0;
586586 const slice_alignment = slice_ty.abiAlignment(mod);
587587
......@@ -592,8 +592,8 @@ pub const Object = struct {
592592 llvm_errors[0] = llvm_slice_ty.getUndef();
593593 for (llvm_errors[1..], error_name_list[1..]) |*llvm_error, name_nts| {
594594 const name = mod.intern_pool.stringToSlice(name_nts);
595 const str_init = self.context.constString(name.ptr, @intCast(c_uint, name.len), .False);
596 const str_global = self.llvm_module.addGlobal(str_init.typeOf(), "");
595 const str_init = o.context.constString(name.ptr, @intCast(c_uint, name.len), .False);
596 const str_global = o.llvm_module.addGlobal(str_init.typeOf(), "");
597597 str_global.setInitializer(str_init);
598598 str_global.setLinkage(.Private);
599599 str_global.setGlobalConstant(.True);
......@@ -609,7 +609,7 @@ pub const Object = struct {
609609
610610 const error_name_table_init = llvm_slice_ty.constArray(llvm_errors.ptr, @intCast(c_uint, error_name_list.len));
611611
612 const error_name_table_global = self.llvm_module.addGlobal(error_name_table_init.typeOf(), "");
612 const error_name_table_global = o.llvm_module.addGlobal(error_name_table_init.typeOf(), "");
613613 error_name_table_global.setInitializer(error_name_table_init);
614614 error_name_table_global.setLinkage(.Private);
615615 error_name_table_global.setGlobalConstant(.True);
......@@ -873,35 +873,32 @@ pub const Object = struct {
873873 const target = mod.getTarget();
874874
875875 var dg: DeclGen = .{
876 .context = o.context,
877876 .object = o,
878 .module = mod,
879877 .decl_index = decl_index,
880878 .decl = decl,
881879 .err_msg = null,
882 .gpa = mod.gpa,
883880 };
884881
885 const llvm_func = try dg.resolveLlvmFunction(decl_index);
882 const llvm_func = try o.resolveLlvmFunction(decl_index);
886883
887884 if (mod.align_stack_fns.get(func_index)) |align_info| {
888 dg.addFnAttrInt(llvm_func, "alignstack", align_info.alignment.toByteUnitsOptional().?);
889 dg.addFnAttr(llvm_func, "noinline");
885 o.addFnAttrInt(llvm_func, "alignstack", align_info.alignment.toByteUnitsOptional().?);
886 o.addFnAttr(llvm_func, "noinline");
890887 } else {
891 DeclGen.removeFnAttr(llvm_func, "alignstack");
892 if (!func.is_noinline) DeclGen.removeFnAttr(llvm_func, "noinline");
888 Object.removeFnAttr(llvm_func, "alignstack");
889 if (!func.is_noinline) Object.removeFnAttr(llvm_func, "noinline");
893890 }
894891
895892 if (func.is_cold) {
896 dg.addFnAttr(llvm_func, "cold");
893 o.addFnAttr(llvm_func, "cold");
897894 } else {
898 DeclGen.removeFnAttr(llvm_func, "cold");
895 Object.removeFnAttr(llvm_func, "cold");
899896 }
900897
901898 if (func.is_noinline) {
902 dg.addFnAttr(llvm_func, "noinline");
899 o.addFnAttr(llvm_func, "noinline");
903900 } else {
904 DeclGen.removeFnAttr(llvm_func, "noinline");
901 Object.removeFnAttr(llvm_func, "noinline");
905902 }
906903
907904 // TODO: disable this if safety is off for the function scope
......@@ -909,15 +906,15 @@ pub const Object = struct {
909906 if (ssp_buf_size != 0) {
910907 var buf: [12]u8 = undefined;
911908 const arg = std.fmt.bufPrintZ(&buf, "{d}", .{ssp_buf_size}) catch unreachable;
912 dg.addFnAttr(llvm_func, "sspstrong");
913 dg.addFnAttrString(llvm_func, "stack-protector-buffer-size", arg);
909 o.addFnAttr(llvm_func, "sspstrong");
910 o.addFnAttrString(llvm_func, "stack-protector-buffer-size", arg);
914911 }
915912
916913 // TODO: disable this if safety is off for the function scope
917914 if (mod.comp.bin_file.options.stack_check) {
918 dg.addFnAttrString(llvm_func, "probe-stack", "__zig_probe_stack");
915 o.addFnAttrString(llvm_func, "probe-stack", "__zig_probe_stack");
919916 } else if (target.os.tag == .uefi) {
920 dg.addFnAttrString(llvm_func, "no-stack-arg-probe", "");
917 o.addFnAttrString(llvm_func, "no-stack-arg-probe", "");
921918 }
922919
923920 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |section|
......@@ -929,20 +926,20 @@ pub const Object = struct {
929926 bb.deleteBasicBlock();
930927 }
931928
932 const builder = dg.context.createBuilder();
929 const builder = o.context.createBuilder();
933930
934 const entry_block = dg.context.appendBasicBlock(llvm_func, "Entry");
931 const entry_block = o.context.appendBasicBlock(llvm_func, "Entry");
935932 builder.positionBuilderAtEnd(entry_block);
936933
937934 // This gets the LLVM values from the function and stores them in `dg.args`.
938935 const fn_info = mod.typeToFunc(decl.ty).?;
939936 const sret = firstParamSRet(fn_info, mod);
940937 const ret_ptr = if (sret) llvm_func.getParam(0) else null;
941 const gpa = dg.gpa;
938 const gpa = o.gpa;
942939
943940 if (ccAbiPromoteInt(fn_info.cc, mod, fn_info.return_type.toType())) |s| switch (s) {
944 .signed => dg.addAttr(llvm_func, 0, "signext"),
945 .unsigned => dg.addAttr(llvm_func, 0, "zeroext"),
941 .signed => o.addAttr(llvm_func, 0, "signext"),
942 .unsigned => o.addAttr(llvm_func, 0, "zeroext"),
946943 };
947944
948945 const err_return_tracing = fn_info.return_type.toType().isError(mod) and
......@@ -961,7 +958,7 @@ pub const Object = struct {
961958
962959 {
963960 var llvm_arg_i = @as(c_uint, @intFromBool(ret_ptr != null)) + @intFromBool(err_return_tracing);
964 var it = iterateParamTypes(&dg, fn_info);
961 var it = iterateParamTypes(o, fn_info);
965962 while (it.next()) |lowering| switch (lowering) {
966963 .no_bits => continue,
967964 .byval => {
......@@ -974,24 +971,24 @@ pub const Object = struct {
974971 if (isByRef(param_ty, mod)) {
975972 const alignment = param_ty.abiAlignment(mod);
976973 const param_llvm_ty = param.typeOf();
977 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
974 const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
978975 const store_inst = builder.buildStore(param, arg_ptr);
979976 store_inst.setAlignment(alignment);
980977 args.appendAssumeCapacity(arg_ptr);
981978 } else {
982979 args.appendAssumeCapacity(param);
983980
984 dg.addByValParamAttrs(llvm_func, param_ty, param_index, fn_info, llvm_arg_i);
981 o.addByValParamAttrs(llvm_func, param_ty, param_index, fn_info, llvm_arg_i);
985982 }
986983 llvm_arg_i += 1;
987984 },
988985 .byref => {
989986 const param_ty = fn_info.param_types[it.zig_index - 1].toType();
990 const param_llvm_ty = try dg.lowerType(param_ty);
987 const param_llvm_ty = try o.lowerType(param_ty);
991988 const param = llvm_func.getParam(llvm_arg_i);
992989 const alignment = param_ty.abiAlignment(mod);
993990
994 dg.addByRefParamAttrs(llvm_func, llvm_arg_i, alignment, it.byval_attr, param_llvm_ty);
991 o.addByRefParamAttrs(llvm_func, llvm_arg_i, alignment, it.byval_attr, param_llvm_ty);
995992 llvm_arg_i += 1;
996993
997994 try args.ensureUnusedCapacity(1);
......@@ -1006,11 +1003,11 @@ pub const Object = struct {
10061003 },
10071004 .byref_mut => {
10081005 const param_ty = fn_info.param_types[it.zig_index - 1].toType();
1009 const param_llvm_ty = try dg.lowerType(param_ty);
1006 const param_llvm_ty = try o.lowerType(param_ty);
10101007 const param = llvm_func.getParam(llvm_arg_i);
10111008 const alignment = param_ty.abiAlignment(mod);
10121009
1013 dg.addArgAttr(llvm_func, llvm_arg_i, "noundef");
1010 o.addArgAttr(llvm_func, llvm_arg_i, "noundef");
10141011 llvm_arg_i += 1;
10151012
10161013 try args.ensureUnusedCapacity(1);
......@@ -1029,14 +1026,14 @@ pub const Object = struct {
10291026 const param = llvm_func.getParam(llvm_arg_i);
10301027 llvm_arg_i += 1;
10311028
1032 const param_llvm_ty = try dg.lowerType(param_ty);
1029 const param_llvm_ty = try o.lowerType(param_ty);
10331030 const abi_size = @intCast(c_uint, param_ty.abiSize(mod));
1034 const int_llvm_ty = dg.context.intType(abi_size * 8);
1031 const int_llvm_ty = o.context.intType(abi_size * 8);
10351032 const alignment = @max(
10361033 param_ty.abiAlignment(mod),
1037 dg.object.target_data.abiAlignmentOfType(int_llvm_ty),
1034 o.target_data.abiAlignmentOfType(int_llvm_ty),
10381035 );
1039 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
1036 const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
10401037 const store_inst = builder.buildStore(param, arg_ptr);
10411038 store_inst.setAlignment(alignment);
10421039
......@@ -1057,24 +1054,24 @@ pub const Object = struct {
10571054
10581055 if (math.cast(u5, it.zig_index - 1)) |i| {
10591056 if (@truncate(u1, fn_info.noalias_bits >> i) != 0) {
1060 dg.addArgAttr(llvm_func, llvm_arg_i, "noalias");
1057 o.addArgAttr(llvm_func, llvm_arg_i, "noalias");
10611058 }
10621059 }
10631060 if (param_ty.zigTypeTag(mod) != .Optional) {
1064 dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull");
1061 o.addArgAttr(llvm_func, llvm_arg_i, "nonnull");
10651062 }
10661063 if (ptr_info.flags.is_const) {
1067 dg.addArgAttr(llvm_func, llvm_arg_i, "readonly");
1064 o.addArgAttr(llvm_func, llvm_arg_i, "readonly");
10681065 }
10691066 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse
10701067 @max(ptr_info.child.toType().abiAlignment(mod), 1);
1071 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);
1068 o.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);
10721069 const ptr_param = llvm_func.getParam(llvm_arg_i);
10731070 llvm_arg_i += 1;
10741071 const len_param = llvm_func.getParam(llvm_arg_i);
10751072 llvm_arg_i += 1;
10761073
1077 const slice_llvm_ty = try dg.lowerType(param_ty);
1074 const slice_llvm_ty = try o.lowerType(param_ty);
10781075 const partial = builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr_param, 0, "");
10791076 const aggregate = builder.buildInsertValue(partial, len_param, 1, "");
10801077 try args.append(aggregate);
......@@ -1083,10 +1080,10 @@ pub const Object = struct {
10831080 assert(!it.byval_attr);
10841081 const field_types = it.llvm_types_buffer[0..it.llvm_types_len];
10851082 const param_ty = fn_info.param_types[it.zig_index - 1].toType();
1086 const param_llvm_ty = try dg.lowerType(param_ty);
1083 const param_llvm_ty = try o.lowerType(param_ty);
10871084 const param_alignment = param_ty.abiAlignment(mod);
1088 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, param_alignment, target);
1089 const llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
1085 const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, param_alignment, target);
1086 const llvm_ty = o.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
10901087 for (field_types, 0..) |_, field_i_usize| {
10911088 const field_i = @intCast(c_uint, field_i_usize);
10921089 const param = llvm_func.getParam(llvm_arg_i);
......@@ -1108,18 +1105,18 @@ pub const Object = struct {
11081105 assert(!it.byval_attr);
11091106 const param = llvm_func.getParam(llvm_arg_i);
11101107 llvm_arg_i += 1;
1111 const casted = builder.buildBitCast(param, dg.context.halfType(), "");
1108 const casted = builder.buildBitCast(param, o.context.halfType(), "");
11121109 try args.ensureUnusedCapacity(1);
11131110 args.appendAssumeCapacity(casted);
11141111 },
11151112 .float_array => {
11161113 const param_ty = fn_info.param_types[it.zig_index - 1].toType();
1117 const param_llvm_ty = try dg.lowerType(param_ty);
1114 const param_llvm_ty = try o.lowerType(param_ty);
11181115 const param = llvm_func.getParam(llvm_arg_i);
11191116 llvm_arg_i += 1;
11201117
11211118 const alignment = param_ty.abiAlignment(mod);
1122 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
1119 const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
11231120 _ = builder.buildStore(param, arg_ptr);
11241121
11251122 if (isByRef(param_ty, mod)) {
......@@ -1132,12 +1129,12 @@ pub const Object = struct {
11321129 },
11331130 .i32_array, .i64_array => {
11341131 const param_ty = fn_info.param_types[it.zig_index - 1].toType();
1135 const param_llvm_ty = try dg.lowerType(param_ty);
1132 const param_llvm_ty = try o.lowerType(param_ty);
11361133 const param = llvm_func.getParam(llvm_arg_i);
11371134 llvm_arg_i += 1;
11381135
11391136 const alignment = param_ty.abiAlignment(mod);
1140 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
1137 const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
11411138 _ = builder.buildStore(param, arg_ptr);
11421139
11431140 if (isByRef(param_ty, mod)) {
......@@ -1154,8 +1151,8 @@ pub const Object = struct {
11541151 var di_file: ?*llvm.DIFile = null;
11551152 var di_scope: ?*llvm.DIScope = null;
11561153
1157 if (dg.object.di_builder) |dib| {
1158 di_file = try dg.object.getDIFile(gpa, mod.namespacePtr(decl.src_namespace).file_scope);
1154 if (o.di_builder) |dib| {
1155 di_file = try o.getDIFile(gpa, mod.namespacePtr(decl.src_namespace).file_scope);
11591156
11601157 const line_number = decl.src_line + 1;
11611158 const is_internal_linkage = decl.val.getExternFunc(mod) == null and
......@@ -1179,7 +1176,7 @@ pub const Object = struct {
11791176 mod.comp.bin_file.options.optimize_mode != .Debug,
11801177 null, // decl_subprogram
11811178 );
1182 try dg.object.di_map.put(gpa, decl, subprogram.toNode());
1179 try o.di_map.put(gpa, decl, subprogram.toNode());
11831180
11841181 llvm_func.fnSetSubprogram(subprogram);
11851182
......@@ -1190,7 +1187,7 @@ pub const Object = struct {
11901187 .gpa = gpa,
11911188 .air = air,
11921189 .liveness = liveness,
1193 .context = dg.context,
1190 .context = o.context,
11941191 .dg = &dg,
11951192 .builder = builder,
11961193 .ret_ptr = ret_ptr,
......@@ -1225,13 +1222,10 @@ pub const Object = struct {
12251222 pub fn updateDecl(self: *Object, module: *Module, decl_index: Module.Decl.Index) !void {
12261223 const decl = module.declPtr(decl_index);
12271224 var dg: DeclGen = .{
1228 .context = self.context,
12291225 .object = self,
1230 .module = module,
12311226 .decl = decl,
12321227 .decl_index = decl_index,
12331228 .err_msg = null,
1234 .gpa = module.gpa,
12351229 };
12361230 dg.genDecl() catch |err| switch (err) {
12371231 error.CodegenFail => {
......@@ -2421,117 +2415,16 @@ pub const Object = struct {
24212415 try ty.print(buffer.writer(), o.module);
24222416 return buffer.toOwnedSliceSentinel(0);
24232417 }
2424};
2425
2426pub const DeclGen = struct {
2427 context: *llvm.Context,
2428 object: *Object,
2429 module: *Module,
2430 decl: *Module.Decl,
2431 decl_index: Module.Decl.Index,
2432 gpa: Allocator,
2433 err_msg: ?*Module.ErrorMsg,
2434
2435 fn todo(self: *DeclGen, comptime format: []const u8, args: anytype) Error {
2436 @setCold(true);
2437 assert(self.err_msg == null);
2438 const mod = self.module;
2439 const src_loc = LazySrcLoc.nodeOffset(0).toSrcLoc(self.decl, mod);
2440 self.err_msg = try Module.ErrorMsg.create(self.gpa, src_loc, "TODO (LLVM): " ++ format, args);
2441 return error.CodegenFail;
2442 }
2443
2444 fn llvmModule(self: *DeclGen) *llvm.Module {
2445 return self.object.llvm_module;
2446 }
2447
2448 fn genDecl(dg: *DeclGen) !void {
2449 const mod = dg.module;
2450 const decl = dg.decl;
2451 const decl_index = dg.decl_index;
2452 assert(decl.has_tv);
2453
2454 if (decl.val.getExternFunc(mod)) |extern_func| {
2455 _ = try dg.resolveLlvmFunction(extern_func.decl);
2456 } else {
2457 const target = mod.getTarget();
2458 var global = try dg.resolveGlobalDecl(decl_index);
2459 global.setAlignment(decl.getAlignment(mod));
2460 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| global.setSection(s);
2461 assert(decl.has_tv);
2462 const init_val = if (decl.val.getVariable(mod)) |variable| init_val: {
2463 break :init_val variable.init;
2464 } else init_val: {
2465 global.setGlobalConstant(.True);
2466 break :init_val decl.val.toIntern();
2467 };
2468 if (init_val != .none) {
2469 const llvm_init = try dg.lowerValue(.{ .ty = decl.ty, .val = init_val.toValue() });
2470 if (global.globalGetValueType() == llvm_init.typeOf()) {
2471 global.setInitializer(llvm_init);
2472 } else {
2473 // LLVM does not allow us to change the type of globals. So we must
2474 // create a new global with the correct type, copy all its attributes,
2475 // and then update all references to point to the new global,
2476 // delete the original, and rename the new one to the old one's name.
2477 // This is necessary because LLVM does not support const bitcasting
2478 // a struct with padding bytes, which is needed to lower a const union value
2479 // to LLVM, when a field other than the most-aligned is active. Instead,
2480 // we must lower to an unnamed struct, and pointer cast at usage sites
2481 // of the global. Such an unnamed struct is the cause of the global type
2482 // mismatch, because we don't have the LLVM type until the *value* is created,
2483 // whereas the global needs to be created based on the type alone, because
2484 // lowering the value may reference the global as a pointer.
2485 const llvm_global_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);
2486 const new_global = dg.object.llvm_module.addGlobalInAddressSpace(
2487 llvm_init.typeOf(),
2488 "",
2489 llvm_global_addrspace,
2490 );
2491 new_global.setLinkage(global.getLinkage());
2492 new_global.setUnnamedAddr(global.getUnnamedAddress());
2493 new_global.setAlignment(global.getAlignment());
2494 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
2495 new_global.setSection(s);
2496 new_global.setInitializer(llvm_init);
2497 // TODO: How should this work then the address space of a global changed?
2498 global.replaceAllUsesWith(new_global);
2499 dg.object.decl_map.putAssumeCapacity(decl_index, new_global);
2500 new_global.takeName(global);
2501 global.deleteGlobal();
2502 global = new_global;
2503 }
2504 }
2505
2506 if (dg.object.di_builder) |dib| {
2507 const di_file = try dg.object.getDIFile(dg.gpa, mod.namespacePtr(decl.src_namespace).file_scope);
2508
2509 const line_number = decl.src_line + 1;
2510 const is_internal_linkage = !dg.module.decl_exports.contains(decl_index);
2511 const di_global = dib.createGlobalVariableExpression(
2512 di_file.toScope(),
2513 mod.intern_pool.stringToSlice(decl.name),
2514 global.getValueName(),
2515 di_file,
2516 line_number,
2517 try dg.object.lowerDebugType(decl.ty, .full),
2518 is_internal_linkage,
2519 );
2520
2521 try dg.object.di_map.put(dg.gpa, dg.decl, di_global.getVariable().toNode());
2522 if (!is_internal_linkage or decl.isExtern(mod)) global.attachMetaData(di_global);
2523 }
2524 }
2525 }
25262418
25272419 /// If the llvm function does not exist, create it.
25282420 /// Note that this can be called before the function's semantic analysis has
25292421 /// completed, so if any attributes rely on that, they must be done in updateFunc, not here.
2530 fn resolveLlvmFunction(dg: *DeclGen, decl_index: Module.Decl.Index) !*llvm.Value {
2531 const mod = dg.module;
2422 fn resolveLlvmFunction(o: *Object, decl_index: Module.Decl.Index) !*llvm.Value {
2423 const mod = o.module;
2424 const gpa = o.gpa;
25322425 const decl = mod.declPtr(decl_index);
25332426 const zig_fn_type = decl.ty;
2534 const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl_index);
2427 const gop = try o.decl_map.getOrPut(gpa, decl_index);
25352428 if (gop.found_existing) return gop.value_ptr.*;
25362429
25372430 assert(decl.has_tv);
......@@ -2539,12 +2432,12 @@ pub const DeclGen = struct {
25392432 const target = mod.getTarget();
25402433 const sret = firstParamSRet(fn_info, mod);
25412434
2542 const fn_type = try dg.lowerType(zig_fn_type);
2435 const fn_type = try o.lowerType(zig_fn_type);
25432436
25442437 const fqn = try decl.getFullyQualifiedName(mod);
25452438
25462439 const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
2547 const llvm_fn = dg.llvmModule().addFunctionInAddressSpace(mod.intern_pool.stringToSlice(fqn), fn_type, llvm_addrspace);
2440 const llvm_fn = o.llvm_module.addFunctionInAddressSpace(mod.intern_pool.stringToSlice(fqn), fn_type, llvm_addrspace);
25482441 gop.value_ptr.* = llvm_fn;
25492442
25502443 const is_extern = decl.isExtern(mod);
......@@ -2553,20 +2446,20 @@ pub const DeclGen = struct {
25532446 llvm_fn.setUnnamedAddr(.True);
25542447 } else {
25552448 if (target.isWasm()) {
2556 dg.addFnAttrString(llvm_fn, "wasm-import-name", mod.intern_pool.stringToSlice(decl.name));
2449 o.addFnAttrString(llvm_fn, "wasm-import-name", mod.intern_pool.stringToSlice(decl.name));
25572450 if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {
25582451 if (!std.mem.eql(u8, lib_name, "c")) {
2559 dg.addFnAttrString(llvm_fn, "wasm-import-module", lib_name);
2452 o.addFnAttrString(llvm_fn, "wasm-import-module", lib_name);
25602453 }
25612454 }
25622455 }
25632456 }
25642457
25652458 if (sret) {
2566 dg.addArgAttr(llvm_fn, 0, "nonnull"); // Sret pointers must not be address 0
2567 dg.addArgAttr(llvm_fn, 0, "noalias");
2459 o.addArgAttr(llvm_fn, 0, "nonnull"); // Sret pointers must not be address 0
2460 o.addArgAttr(llvm_fn, 0, "noalias");
25682461
2569 const raw_llvm_ret_ty = try dg.lowerType(fn_info.return_type.toType());
2462 const raw_llvm_ret_ty = try o.lowerType(fn_info.return_type.toType());
25702463 llvm_fn.addSretAttr(raw_llvm_ret_ty);
25712464 }
25722465
......@@ -2574,7 +2467,7 @@ pub const DeclGen = struct {
25742467 mod.comp.bin_file.options.error_return_tracing;
25752468
25762469 if (err_return_tracing) {
2577 dg.addArgAttr(llvm_fn, @intFromBool(sret), "nonnull");
2470 o.addArgAttr(llvm_fn, @intFromBool(sret), "nonnull");
25782471 }
25792472
25802473 switch (fn_info.cc) {
......@@ -2582,7 +2475,7 @@ pub const DeclGen = struct {
25822475 llvm_fn.setFunctionCallConv(.Fast);
25832476 },
25842477 .Naked => {
2585 dg.addFnAttr(llvm_fn, "naked");
2478 o.addFnAttr(llvm_fn, "naked");
25862479 },
25872480 .Async => {
25882481 llvm_fn.setFunctionCallConv(.Fast);
......@@ -2598,16 +2491,16 @@ pub const DeclGen = struct {
25982491 }
25992492
26002493 // Function attributes that are independent of analysis results of the function body.
2601 dg.addCommonFnAttributes(llvm_fn);
2494 o.addCommonFnAttributes(llvm_fn);
26022495
26032496 if (fn_info.return_type == .noreturn_type) {
2604 dg.addFnAttr(llvm_fn, "noreturn");
2497 o.addFnAttr(llvm_fn, "noreturn");
26052498 }
26062499
26072500 // Add parameter attributes. We handle only the case of extern functions (no body)
26082501 // because functions with bodies are handled in `updateFunc`.
26092502 if (is_extern) {
2610 var it = iterateParamTypes(dg, fn_info);
2503 var it = iterateParamTypes(o, fn_info);
26112504 it.llvm_index += @intFromBool(sret);
26122505 it.llvm_index += @intFromBool(err_return_tracing);
26132506 while (it.next()) |lowering| switch (lowering) {
......@@ -2615,17 +2508,17 @@ pub const DeclGen = struct {
26152508 const param_index = it.zig_index - 1;
26162509 const param_ty = fn_info.param_types[param_index].toType();
26172510 if (!isByRef(param_ty, mod)) {
2618 dg.addByValParamAttrs(llvm_fn, param_ty, param_index, fn_info, it.llvm_index - 1);
2511 o.addByValParamAttrs(llvm_fn, param_ty, param_index, fn_info, it.llvm_index - 1);
26192512 }
26202513 },
26212514 .byref => {
26222515 const param_ty = fn_info.param_types[it.zig_index - 1];
2623 const param_llvm_ty = try dg.lowerType(param_ty.toType());
2516 const param_llvm_ty = try o.lowerType(param_ty.toType());
26242517 const alignment = param_ty.toType().abiAlignment(mod);
2625 dg.addByRefParamAttrs(llvm_fn, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
2518 o.addByRefParamAttrs(llvm_fn, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
26262519 },
26272520 .byref_mut => {
2628 dg.addArgAttr(llvm_fn, it.llvm_index - 1, "noundef");
2521 o.addArgAttr(llvm_fn, it.llvm_index - 1, "noundef");
26292522 },
26302523 // No attributes needed for these.
26312524 .no_bits,
......@@ -2645,20 +2538,20 @@ pub const DeclGen = struct {
26452538 return llvm_fn;
26462539 }
26472540
2648 fn addCommonFnAttributes(dg: *DeclGen, llvm_fn: *llvm.Value) void {
2649 const comp = dg.module.comp;
2541 fn addCommonFnAttributes(o: *Object, llvm_fn: *llvm.Value) void {
2542 const comp = o.module.comp;
26502543
26512544 if (!comp.bin_file.options.red_zone) {
2652 dg.addFnAttr(llvm_fn, "noredzone");
2545 o.addFnAttr(llvm_fn, "noredzone");
26532546 }
26542547 if (comp.bin_file.options.omit_frame_pointer) {
2655 dg.addFnAttrString(llvm_fn, "frame-pointer", "none");
2548 o.addFnAttrString(llvm_fn, "frame-pointer", "none");
26562549 } else {
2657 dg.addFnAttrString(llvm_fn, "frame-pointer", "all");
2550 o.addFnAttrString(llvm_fn, "frame-pointer", "all");
26582551 }
2659 dg.addFnAttr(llvm_fn, "nounwind");
2552 o.addFnAttr(llvm_fn, "nounwind");
26602553 if (comp.unwind_tables) {
2661 dg.addFnAttrInt(llvm_fn, "uwtable", 2);
2554 o.addFnAttrInt(llvm_fn, "uwtable", 2);
26622555 }
26632556 if (comp.bin_file.options.skip_linker_dependencies or
26642557 comp.bin_file.options.no_builtin)
......@@ -2668,14 +2561,14 @@ pub const DeclGen = struct {
26682561 // and llvm detects that the body is equivalent to memcpy, it may replace the
26692562 // body of memcpy with a call to memcpy, which would then cause a stack
26702563 // overflow instead of performing memcpy.
2671 dg.addFnAttr(llvm_fn, "nobuiltin");
2564 o.addFnAttr(llvm_fn, "nobuiltin");
26722565 }
26732566 if (comp.bin_file.options.optimize_mode == .ReleaseSmall) {
2674 dg.addFnAttr(llvm_fn, "minsize");
2675 dg.addFnAttr(llvm_fn, "optsize");
2567 o.addFnAttr(llvm_fn, "minsize");
2568 o.addFnAttr(llvm_fn, "optsize");
26762569 }
26772570 if (comp.bin_file.options.tsan) {
2678 dg.addFnAttr(llvm_fn, "sanitize_thread");
2571 o.addFnAttr(llvm_fn, "sanitize_thread");
26792572 }
26802573 if (comp.getTarget().cpu.model.llvm_name) |s| {
26812574 llvm_fn.addFunctionAttr("target-cpu", s);
......@@ -2688,21 +2581,21 @@ pub const DeclGen = struct {
26882581 }
26892582 }
26902583
2691 fn resolveGlobalDecl(dg: *DeclGen, decl_index: Module.Decl.Index) Error!*llvm.Value {
2692 const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl_index);
2584 fn resolveGlobalDecl(o: *Object, decl_index: Module.Decl.Index) Error!*llvm.Value {
2585 const gop = try o.decl_map.getOrPut(o.gpa, decl_index);
26932586 if (gop.found_existing) return gop.value_ptr.*;
2694 errdefer assert(dg.object.decl_map.remove(decl_index));
2587 errdefer assert(o.decl_map.remove(decl_index));
26952588
2696 const mod = dg.module;
2589 const mod = o.module;
26972590 const decl = mod.declPtr(decl_index);
26982591 const fqn = try decl.getFullyQualifiedName(mod);
26992592
27002593 const target = mod.getTarget();
27012594
2702 const llvm_type = try dg.lowerType(decl.ty);
2595 const llvm_type = try o.lowerType(decl.ty);
27032596 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);
27042597
2705 const llvm_global = dg.object.llvm_module.addGlobalInAddressSpace(
2598 const llvm_global = o.llvm_module.addGlobalInAddressSpace(
27062599 llvm_type,
27072600 mod.intern_pool.stringToSlice(fqn),
27082601 llvm_actual_addrspace,
......@@ -2731,128 +2624,128 @@ pub const DeclGen = struct {
27312624 return llvm_global;
27322625 }
27332626
2734 fn isUnnamedType(dg: *DeclGen, ty: Type, val: *llvm.Value) bool {
2627 fn isUnnamedType(o: *Object, ty: Type, val: *llvm.Value) bool {
27352628 // Once `lowerType` succeeds, successive calls to it with the same Zig type
27362629 // are guaranteed to succeed. So if a call to `lowerType` fails here it means
27372630 // it is the first time lowering the type, which means the value can't possible
27382631 // have that type.
2739 const llvm_ty = dg.lowerType(ty) catch return true;
2632 const llvm_ty = o.lowerType(ty) catch return true;
27402633 return val.typeOf() != llvm_ty;
27412634 }
27422635
2743 fn lowerType(dg: *DeclGen, t: Type) Allocator.Error!*llvm.Type {
2744 const llvm_ty = try lowerTypeInner(dg, t);
2745 const mod = dg.module;
2636 fn lowerType(o: *Object, t: Type) Allocator.Error!*llvm.Type {
2637 const llvm_ty = try lowerTypeInner(o, t);
2638 const mod = o.module;
27462639 if (std.debug.runtime_safety and false) check: {
27472640 if (t.zigTypeTag(mod) == .Opaque) break :check;
27482641 if (!t.hasRuntimeBits(mod)) break :check;
27492642 if (!llvm_ty.isSized().toBool()) break :check;
27502643
27512644 const zig_size = t.abiSize(mod);
2752 const llvm_size = dg.object.target_data.abiSizeOfType(llvm_ty);
2645 const llvm_size = o.target_data.abiSizeOfType(llvm_ty);
27532646 if (llvm_size != zig_size) {
27542647 log.err("when lowering {}, Zig ABI size = {d} but LLVM ABI size = {d}", .{
2755 t.fmt(dg.module), zig_size, llvm_size,
2648 t.fmt(o.module), zig_size, llvm_size,
27562649 });
27572650 }
27582651 }
27592652 return llvm_ty;
27602653 }
27612654
2762 fn lowerTypeInner(dg: *DeclGen, t: Type) Allocator.Error!*llvm.Type {
2763 const gpa = dg.gpa;
2764 const mod = dg.module;
2655 fn lowerTypeInner(o: *Object, t: Type) Allocator.Error!*llvm.Type {
2656 const gpa = o.gpa;
2657 const mod = o.module;
27652658 const target = mod.getTarget();
27662659 switch (t.zigTypeTag(mod)) {
2767 .Void, .NoReturn => return dg.context.voidType(),
2660 .Void, .NoReturn => return o.context.voidType(),
27682661 .Int => {
27692662 const info = t.intInfo(mod);
27702663 assert(info.bits != 0);
2771 return dg.context.intType(info.bits);
2664 return o.context.intType(info.bits);
27722665 },
27732666 .Enum => {
27742667 const int_ty = t.intTagType(mod);
27752668 const bit_count = int_ty.intInfo(mod).bits;
27762669 assert(bit_count != 0);
2777 return dg.context.intType(bit_count);
2670 return o.context.intType(bit_count);
27782671 },
27792672 .Float => switch (t.floatBits(target)) {
2780 16 => return if (backendSupportsF16(target)) dg.context.halfType() else dg.context.intType(16),
2781 32 => return dg.context.floatType(),
2782 64 => return dg.context.doubleType(),
2783 80 => return if (backendSupportsF80(target)) dg.context.x86FP80Type() else dg.context.intType(80),
2784 128 => return dg.context.fp128Type(),
2673 16 => return if (backendSupportsF16(target)) o.context.halfType() else o.context.intType(16),
2674 32 => return o.context.floatType(),
2675 64 => return o.context.doubleType(),
2676 80 => return if (backendSupportsF80(target)) o.context.x86FP80Type() else o.context.intType(80),
2677 128 => return o.context.fp128Type(),
27852678 else => unreachable,
27862679 },
2787 .Bool => return dg.context.intType(1),
2680 .Bool => return o.context.intType(1),
27882681 .Pointer => {
27892682 if (t.isSlice(mod)) {
27902683 const ptr_type = t.slicePtrFieldType(mod);
27912684
27922685 const fields: [2]*llvm.Type = .{
2793 try dg.lowerType(ptr_type),
2794 try dg.lowerType(Type.usize),
2686 try o.lowerType(ptr_type),
2687 try o.lowerType(Type.usize),
27952688 };
2796 return dg.context.structType(&fields, fields.len, .False);
2689 return o.context.structType(&fields, fields.len, .False);
27972690 }
27982691 const ptr_info = t.ptrInfo(mod);
27992692 const llvm_addrspace = toLlvmAddressSpace(ptr_info.flags.address_space, target);
2800 return dg.context.pointerType(llvm_addrspace);
2693 return o.context.pointerType(llvm_addrspace);
28012694 },
28022695 .Opaque => {
2803 if (t.toIntern() == .anyopaque_type) return dg.context.intType(8);
2696 if (t.toIntern() == .anyopaque_type) return o.context.intType(8);
28042697
2805 const gop = try dg.object.type_map.getOrPut(gpa, t.toIntern());
2698 const gop = try o.type_map.getOrPut(gpa, t.toIntern());
28062699 if (gop.found_existing) return gop.value_ptr.*;
28072700
28082701 const opaque_type = mod.intern_pool.indexToKey(t.toIntern()).opaque_type;
28092702 const name = mod.intern_pool.stringToSlice(try mod.opaqueFullyQualifiedName(opaque_type));
28102703
2811 const llvm_struct_ty = dg.context.structCreateNamed(name);
2704 const llvm_struct_ty = o.context.structCreateNamed(name);
28122705 gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
28132706 return llvm_struct_ty;
28142707 },
28152708 .Array => {
28162709 const elem_ty = t.childType(mod);
28172710 if (std.debug.runtime_safety) assert((try elem_ty.onePossibleValue(mod)) == null);
2818 const elem_llvm_ty = try dg.lowerType(elem_ty);
2711 const elem_llvm_ty = try o.lowerType(elem_ty);
28192712 const total_len = t.arrayLen(mod) + @intFromBool(t.sentinel(mod) != null);
28202713 return elem_llvm_ty.arrayType(@intCast(c_uint, total_len));
28212714 },
28222715 .Vector => {
2823 const elem_type = try dg.lowerType(t.childType(mod));
2716 const elem_type = try o.lowerType(t.childType(mod));
28242717 return elem_type.vectorType(t.vectorLen(mod));
28252718 },
28262719 .Optional => {
28272720 const child_ty = t.optionalChild(mod);
28282721 if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2829 return dg.context.intType(8);
2722 return o.context.intType(8);
28302723 }
2831 const payload_llvm_ty = try dg.lowerType(child_ty);
2724 const payload_llvm_ty = try o.lowerType(child_ty);
28322725 if (t.optionalReprIsPayload(mod)) {
28332726 return payload_llvm_ty;
28342727 }
28352728
28362729 comptime assert(optional_layout_version == 3);
28372730 var fields_buf: [3]*llvm.Type = .{
2838 payload_llvm_ty, dg.context.intType(8), undefined,
2731 payload_llvm_ty, o.context.intType(8), undefined,
28392732 };
28402733 const offset = child_ty.abiSize(mod) + 1;
28412734 const abi_size = t.abiSize(mod);
28422735 const padding = @intCast(c_uint, abi_size - offset);
28432736 if (padding == 0) {
2844 return dg.context.structType(&fields_buf, 2, .False);
2737 return o.context.structType(&fields_buf, 2, .False);
28452738 }
2846 fields_buf[2] = dg.context.intType(8).arrayType(padding);
2847 return dg.context.structType(&fields_buf, 3, .False);
2739 fields_buf[2] = o.context.intType(8).arrayType(padding);
2740 return o.context.structType(&fields_buf, 3, .False);
28482741 },
28492742 .ErrorUnion => {
28502743 const payload_ty = t.errorUnionPayload(mod);
28512744 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2852 return try dg.lowerType(Type.anyerror);
2745 return try o.lowerType(Type.anyerror);
28532746 }
2854 const llvm_error_type = try dg.lowerType(Type.anyerror);
2855 const llvm_payload_type = try dg.lowerType(payload_ty);
2747 const llvm_error_type = try o.lowerType(Type.anyerror);
2748 const llvm_payload_type = try o.lowerType(payload_ty);
28562749
28572750 const payload_align = payload_ty.abiAlignment(mod);
28582751 const error_align = Type.anyerror.abiAlignment(mod);
......@@ -2870,10 +2763,10 @@ pub const DeclGen = struct {
28702763 const abi_size = std.mem.alignForward(u64, payload_end, error_align);
28712764 const padding = @intCast(c_uint, abi_size - payload_end);
28722765 if (padding == 0) {
2873 return dg.context.structType(&fields_buf, 2, .False);
2766 return o.context.structType(&fields_buf, 2, .False);
28742767 }
2875 fields_buf[2] = dg.context.intType(8).arrayType(padding);
2876 return dg.context.structType(&fields_buf, 3, .False);
2768 fields_buf[2] = o.context.intType(8).arrayType(padding);
2769 return o.context.structType(&fields_buf, 3, .False);
28772770 } else {
28782771 fields_buf[0] = llvm_payload_type;
28792772 fields_buf[1] = llvm_error_type;
......@@ -2883,20 +2776,20 @@ pub const DeclGen = struct {
28832776 const abi_size = std.mem.alignForward(u64, error_end, payload_align);
28842777 const padding = @intCast(c_uint, abi_size - error_end);
28852778 if (padding == 0) {
2886 return dg.context.structType(&fields_buf, 2, .False);
2779 return o.context.structType(&fields_buf, 2, .False);
28872780 }
2888 fields_buf[2] = dg.context.intType(8).arrayType(padding);
2889 return dg.context.structType(&fields_buf, 3, .False);
2781 fields_buf[2] = o.context.intType(8).arrayType(padding);
2782 return o.context.structType(&fields_buf, 3, .False);
28902783 }
28912784 },
2892 .ErrorSet => return dg.context.intType(16),
2785 .ErrorSet => return o.context.intType(16),
28932786 .Struct => {
2894 const gop = try dg.object.type_map.getOrPut(gpa, t.toIntern());
2787 const gop = try o.type_map.getOrPut(gpa, t.toIntern());
28952788 if (gop.found_existing) return gop.value_ptr.*;
28962789
28972790 const struct_type = switch (mod.intern_pool.indexToKey(t.toIntern())) {
28982791 .anon_struct_type => |tuple| {
2899 const llvm_struct_ty = dg.context.structCreateNamed("");
2792 const llvm_struct_ty = o.context.structCreateNamed("");
29002793 gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
29012794
29022795 var llvm_field_types: std.ArrayListUnmanaged(*llvm.Type) = .{};
......@@ -2918,10 +2811,10 @@ pub const DeclGen = struct {
29182811
29192812 const padding_len = offset - prev_offset;
29202813 if (padding_len > 0) {
2921 const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
2814 const llvm_array_ty = o.context.intType(8).arrayType(@intCast(c_uint, padding_len));
29222815 try llvm_field_types.append(gpa, llvm_array_ty);
29232816 }
2924 const field_llvm_ty = try dg.lowerType(field_ty.toType());
2817 const field_llvm_ty = try o.lowerType(field_ty.toType());
29252818 try llvm_field_types.append(gpa, field_llvm_ty);
29262819
29272820 offset += field_ty.toType().abiSize(mod);
......@@ -2931,7 +2824,7 @@ pub const DeclGen = struct {
29312824 offset = std.mem.alignForward(u64, offset, big_align);
29322825 const padding_len = offset - prev_offset;
29332826 if (padding_len > 0) {
2934 const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
2827 const llvm_array_ty = o.context.intType(8).arrayType(@intCast(c_uint, padding_len));
29352828 try llvm_field_types.append(gpa, llvm_array_ty);
29362829 }
29372830 }
......@@ -2952,14 +2845,14 @@ pub const DeclGen = struct {
29522845
29532846 if (struct_obj.layout == .Packed) {
29542847 assert(struct_obj.haveLayout());
2955 const int_llvm_ty = try dg.lowerType(struct_obj.backing_int_ty);
2848 const int_llvm_ty = try o.lowerType(struct_obj.backing_int_ty);
29562849 gop.value_ptr.* = int_llvm_ty;
29572850 return int_llvm_ty;
29582851 }
29592852
29602853 const name = mod.intern_pool.stringToSlice(try struct_obj.getFullyQualifiedName(mod));
29612854
2962 const llvm_struct_ty = dg.context.structCreateNamed(name);
2855 const llvm_struct_ty = o.context.structCreateNamed(name);
29632856 gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
29642857
29652858 assert(struct_obj.haveFieldTypes());
......@@ -2987,10 +2880,10 @@ pub const DeclGen = struct {
29872880
29882881 const padding_len = offset - prev_offset;
29892882 if (padding_len > 0) {
2990 const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
2883 const llvm_array_ty = o.context.intType(8).arrayType(@intCast(c_uint, padding_len));
29912884 try llvm_field_types.append(gpa, llvm_array_ty);
29922885 }
2993 const field_llvm_ty = try dg.lowerType(field.ty);
2886 const field_llvm_ty = try o.lowerType(field.ty);
29942887 try llvm_field_types.append(gpa, field_llvm_ty);
29952888
29962889 offset += field.ty.abiSize(mod);
......@@ -3000,7 +2893,7 @@ pub const DeclGen = struct {
30002893 offset = std.mem.alignForward(u64, offset, big_align);
30012894 const padding_len = offset - prev_offset;
30022895 if (padding_len > 0) {
3003 const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
2896 const llvm_array_ty = o.context.intType(8).arrayType(@intCast(c_uint, padding_len));
30042897 try llvm_field_types.append(gpa, llvm_array_ty);
30052898 }
30062899 }
......@@ -3014,7 +2907,7 @@ pub const DeclGen = struct {
30142907 return llvm_struct_ty;
30152908 },
30162909 .Union => {
3017 const gop = try dg.object.type_map.getOrPut(gpa, t.toIntern());
2910 const gop = try o.type_map.getOrPut(gpa, t.toIntern());
30182911 if (gop.found_existing) return gop.value_ptr.*;
30192912
30202913 const layout = t.unionGetLayout(mod);
......@@ -3022,24 +2915,24 @@ pub const DeclGen = struct {
30222915
30232916 if (union_obj.layout == .Packed) {
30242917 const bitsize = @intCast(c_uint, t.bitSize(mod));
3025 const int_llvm_ty = dg.context.intType(bitsize);
2918 const int_llvm_ty = o.context.intType(bitsize);
30262919 gop.value_ptr.* = int_llvm_ty;
30272920 return int_llvm_ty;
30282921 }
30292922
30302923 if (layout.payload_size == 0) {
3031 const enum_tag_llvm_ty = try dg.lowerType(union_obj.tag_ty);
2924 const enum_tag_llvm_ty = try o.lowerType(union_obj.tag_ty);
30322925 gop.value_ptr.* = enum_tag_llvm_ty;
30332926 return enum_tag_llvm_ty;
30342927 }
30352928
30362929 const name = mod.intern_pool.stringToSlice(try union_obj.getFullyQualifiedName(mod));
30372930
3038 const llvm_union_ty = dg.context.structCreateNamed(name);
2931 const llvm_union_ty = o.context.structCreateNamed(name);
30392932 gop.value_ptr.* = llvm_union_ty; // must be done before any recursive calls
30402933
30412934 const aligned_field = union_obj.fields.values()[layout.most_aligned_field];
3042 const llvm_aligned_field_ty = try dg.lowerType(aligned_field.ty);
2935 const llvm_aligned_field_ty = try o.lowerType(aligned_field.ty);
30432936
30442937 const llvm_payload_ty = t: {
30452938 if (layout.most_aligned_field_size == layout.payload_size) {
......@@ -3051,9 +2944,9 @@ pub const DeclGen = struct {
30512944 @intCast(c_uint, layout.payload_size - layout.most_aligned_field_size);
30522945 const fields: [2]*llvm.Type = .{
30532946 llvm_aligned_field_ty,
3054 dg.context.intType(8).arrayType(padding_len),
2947 o.context.intType(8).arrayType(padding_len),
30552948 };
3056 break :t dg.context.structType(&fields, fields.len, .True);
2949 break :t o.context.structType(&fields, fields.len, .True);
30572950 };
30582951
30592952 if (layout.tag_size == 0) {
......@@ -3061,7 +2954,7 @@ pub const DeclGen = struct {
30612954 llvm_union_ty.structSetBody(&llvm_fields, llvm_fields.len, .False);
30622955 return llvm_union_ty;
30632956 }
3064 const enum_tag_llvm_ty = try dg.lowerType(union_obj.tag_ty);
2957 const enum_tag_llvm_ty = try o.lowerType(union_obj.tag_ty);
30652958
30662959 // Put the tag before or after the payload depending on which one's
30672960 // alignment is greater.
......@@ -3076,14 +2969,14 @@ pub const DeclGen = struct {
30762969
30772970 // Insert padding to make the LLVM struct ABI size match the Zig union ABI size.
30782971 if (layout.padding != 0) {
3079 llvm_fields[2] = dg.context.intType(8).arrayType(layout.padding);
2972 llvm_fields[2] = o.context.intType(8).arrayType(layout.padding);
30802973 llvm_fields_len = 3;
30812974 }
30822975
30832976 llvm_union_ty.structSetBody(&llvm_fields, llvm_fields_len, .False);
30842977 return llvm_union_ty;
30852978 },
3086 .Fn => return lowerTypeFn(dg, t),
2979 .Fn => return lowerTypeFn(o, t),
30872980 .ComptimeInt => unreachable,
30882981 .ComptimeFloat => unreachable,
30892982 .Type => unreachable,
......@@ -3096,39 +2989,39 @@ pub const DeclGen = struct {
30962989 }
30972990 }
30982991
3099 fn lowerTypeFn(dg: *DeclGen, fn_ty: Type) Allocator.Error!*llvm.Type {
3100 const mod = dg.module;
2992 fn lowerTypeFn(o: *Object, fn_ty: Type) Allocator.Error!*llvm.Type {
2993 const mod = o.module;
31012994 const fn_info = mod.typeToFunc(fn_ty).?;
3102 const llvm_ret_ty = try lowerFnRetTy(dg, fn_info);
2995 const llvm_ret_ty = try lowerFnRetTy(o, fn_info);
31032996
3104 var llvm_params = std.ArrayList(*llvm.Type).init(dg.gpa);
2997 var llvm_params = std.ArrayList(*llvm.Type).init(o.gpa);
31052998 defer llvm_params.deinit();
31062999
31073000 if (firstParamSRet(fn_info, mod)) {
3108 try llvm_params.append(dg.context.pointerType(0));
3001 try llvm_params.append(o.context.pointerType(0));
31093002 }
31103003
31113004 if (fn_info.return_type.toType().isError(mod) and
31123005 mod.comp.bin_file.options.error_return_tracing)
31133006 {
3114 const ptr_ty = try mod.singleMutPtrType(try dg.object.getStackTraceType());
3115 try llvm_params.append(try dg.lowerType(ptr_ty));
3007 const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType());
3008 try llvm_params.append(try o.lowerType(ptr_ty));
31163009 }
31173010
3118 var it = iterateParamTypes(dg, fn_info);
3011 var it = iterateParamTypes(o, fn_info);
31193012 while (it.next()) |lowering| switch (lowering) {
31203013 .no_bits => continue,
31213014 .byval => {
31223015 const param_ty = fn_info.param_types[it.zig_index - 1].toType();
3123 try llvm_params.append(try dg.lowerType(param_ty));
3016 try llvm_params.append(try o.lowerType(param_ty));
31243017 },
31253018 .byref, .byref_mut => {
3126 try llvm_params.append(dg.context.pointerType(0));
3019 try llvm_params.append(o.context.pointerType(0));
31273020 },
31283021 .abi_sized_int => {
31293022 const param_ty = fn_info.param_types[it.zig_index - 1].toType();
31303023 const abi_size = @intCast(c_uint, param_ty.abiSize(mod));
3131 try llvm_params.append(dg.context.intType(abi_size * 8));
3024 try llvm_params.append(o.context.intType(abi_size * 8));
31323025 },
31333026 .slice => {
31343027 const param_ty = fn_info.param_types[it.zig_index - 1].toType();
......@@ -3136,8 +3029,8 @@ pub const DeclGen = struct {
31363029 param_ty.optionalChild(mod).slicePtrFieldType(mod)
31373030 else
31383031 param_ty.slicePtrFieldType(mod);
3139 const ptr_llvm_ty = try dg.lowerType(ptr_ty);
3140 const len_llvm_ty = try dg.lowerType(Type.usize);
3032 const ptr_llvm_ty = try o.lowerType(ptr_ty);
3033 const len_llvm_ty = try o.lowerType(Type.usize);
31413034
31423035 try llvm_params.ensureUnusedCapacity(2);
31433036 llvm_params.appendAssumeCapacity(ptr_llvm_ty);
......@@ -3147,18 +3040,18 @@ pub const DeclGen = struct {
31473040 try llvm_params.appendSlice(it.llvm_types_buffer[0..it.llvm_types_len]);
31483041 },
31493042 .as_u16 => {
3150 try llvm_params.append(dg.context.intType(16));
3043 try llvm_params.append(o.context.intType(16));
31513044 },
31523045 .float_array => |count| {
31533046 const param_ty = fn_info.param_types[it.zig_index - 1].toType();
3154 const float_ty = try dg.lowerType(aarch64_c_abi.getFloatArrayType(param_ty, mod).?);
3047 const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(param_ty, mod).?);
31553048 const field_count = @intCast(c_uint, count);
31563049 const arr_ty = float_ty.arrayType(field_count);
31573050 try llvm_params.append(arr_ty);
31583051 },
31593052 .i32_array, .i64_array => |arr_len| {
31603053 const elem_size: u8 = if (lowering == .i32_array) 32 else 64;
3161 const arr_ty = dg.context.intType(elem_size).arrayType(arr_len);
3054 const arr_ty = o.context.intType(elem_size).arrayType(arr_len);
31623055 try llvm_params.append(arr_ty);
31633056 },
31643057 };
......@@ -3174,8 +3067,8 @@ pub const DeclGen = struct {
31743067 /// Use this instead of lowerType when you want to handle correctly the case of elem_ty
31753068 /// being a zero bit type, but it should still be lowered as an i8 in such case.
31763069 /// There are other similar cases handled here as well.
3177 fn lowerPtrElemTy(dg: *DeclGen, elem_ty: Type) Allocator.Error!*llvm.Type {
3178 const mod = dg.module;
3070 fn lowerPtrElemTy(o: *Object, elem_ty: Type) Allocator.Error!*llvm.Type {
3071 const mod = o.module;
31793072 const lower_elem_ty = switch (elem_ty.zigTypeTag(mod)) {
31803073 .Opaque => true,
31813074 .Fn => !mod.typeToFunc(elem_ty).?.is_generic,
......@@ -3183,15 +3076,16 @@ pub const DeclGen = struct {
31833076 else => elem_ty.hasRuntimeBitsIgnoreComptime(mod),
31843077 };
31853078 const llvm_elem_ty = if (lower_elem_ty)
3186 try dg.lowerType(elem_ty)
3079 try o.lowerType(elem_ty)
31873080 else
3188 dg.context.intType(8);
3081 o.context.intType(8);
31893082
31903083 return llvm_elem_ty;
31913084 }
31923085
3193 fn lowerValue(dg: *DeclGen, arg_tv: TypedValue) Error!*llvm.Value {
3194 const mod = dg.module;
3086 fn lowerValue(o: *Object, arg_tv: TypedValue) Error!*llvm.Value {
3087 const mod = o.module;
3088 const gpa = o.gpa;
31953089 const target = mod.getTarget();
31963090 var tv = arg_tv;
31973091 switch (mod.intern_pool.indexToKey(tv.val.toIntern())) {
......@@ -3199,7 +3093,7 @@ pub const DeclGen = struct {
31993093 else => {},
32003094 }
32013095 if (tv.val.isUndefDeep(mod)) {
3202 const llvm_type = try dg.lowerType(tv.ty);
3096 const llvm_type = try o.lowerType(tv.ty);
32033097 return llvm_type.getUndef();
32043098 }
32053099
......@@ -3233,7 +3127,7 @@ pub const DeclGen = struct {
32333127 .generic_poison,
32343128 => unreachable, // non-runtime values
32353129 .false, .true => {
3236 const llvm_type = try dg.lowerType(tv.ty);
3130 const llvm_type = try o.lowerType(tv.ty);
32373131 return if (tv.val.toBool()) llvm_type.constAllOnes() else llvm_type.constNull();
32383132 },
32393133 },
......@@ -3247,17 +3141,17 @@ pub const DeclGen = struct {
32473141 .func => |func| mod.funcPtr(func.index).owner_decl,
32483142 else => unreachable,
32493143 };
3250 const fn_decl = dg.module.declPtr(fn_decl_index);
3251 try dg.module.markDeclAlive(fn_decl);
3252 return dg.resolveLlvmFunction(fn_decl_index);
3144 const fn_decl = o.module.declPtr(fn_decl_index);
3145 try o.module.markDeclAlive(fn_decl);
3146 return o.resolveLlvmFunction(fn_decl_index);
32533147 },
32543148 .int => {
32553149 var bigint_space: Value.BigIntSpace = undefined;
32563150 const bigint = tv.val.toBigInt(&bigint_space, mod);
3257 return lowerBigInt(dg, tv.ty, bigint);
3151 return lowerBigInt(o, tv.ty, bigint);
32583152 },
32593153 .err => |err| {
3260 const llvm_ty = try dg.lowerType(Type.anyerror);
3154 const llvm_ty = try o.lowerType(Type.anyerror);
32613155 const int = try mod.getErrorValue(err.name);
32623156 return llvm_ty.constInt(int, .False);
32633157 },
......@@ -3278,13 +3172,13 @@ pub const DeclGen = struct {
32783172 const payload_type = tv.ty.errorUnionPayload(mod);
32793173 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
32803174 // We use the error type directly as the type.
3281 return dg.lowerValue(err_tv);
3175 return o.lowerValue(err_tv);
32823176 }
32833177
32843178 const payload_align = payload_type.abiAlignment(mod);
32853179 const error_align = err_tv.ty.abiAlignment(mod);
3286 const llvm_error_value = try dg.lowerValue(err_tv);
3287 const llvm_payload_value = try dg.lowerValue(.{
3180 const llvm_error_value = try o.lowerValue(err_tv);
3181 const llvm_payload_value = try o.lowerValue(.{
32883182 .ty = payload_type,
32893183 .val = switch (error_union.val) {
32903184 .err_name => try mod.intern(.{ .undef = payload_type.toIntern() }),
......@@ -3293,7 +3187,7 @@ pub const DeclGen = struct {
32933187 });
32943188 var fields_buf: [3]*llvm.Value = undefined;
32953189
3296 const llvm_ty = try dg.lowerType(tv.ty);
3190 const llvm_ty = try o.lowerType(tv.ty);
32973191 const llvm_field_count = llvm_ty.countStructElementTypes();
32983192 if (llvm_field_count > 2) {
32993193 assert(llvm_field_count == 3);
......@@ -3303,11 +3197,11 @@ pub const DeclGen = struct {
33033197 if (error_align > payload_align) {
33043198 fields_buf[0] = llvm_error_value;
33053199 fields_buf[1] = llvm_payload_value;
3306 return dg.context.constStruct(&fields_buf, llvm_field_count, .False);
3200 return o.context.constStruct(&fields_buf, llvm_field_count, .False);
33073201 } else {
33083202 fields_buf[0] = llvm_payload_value;
33093203 fields_buf[1] = llvm_error_value;
3310 return dg.context.constStruct(&fields_buf, llvm_field_count, .False);
3204 return o.context.constStruct(&fields_buf, llvm_field_count, .False);
33113205 }
33123206 },
33133207 .enum_tag => {
......@@ -3317,7 +3211,7 @@ pub const DeclGen = struct {
33173211 const bigint = int_val.toBigInt(&bigint_space, mod);
33183212
33193213 const int_info = tv.ty.intInfo(mod);
3320 const llvm_type = dg.context.intType(int_info.bits);
3214 const llvm_type = o.context.intType(int_info.bits);
33213215
33223216 const unsigned_val = v: {
33233217 if (bigint.limbs.len == 1) {
......@@ -3337,30 +3231,30 @@ pub const DeclGen = struct {
33373231 return unsigned_val;
33383232 },
33393233 .float => {
3340 const llvm_ty = try dg.lowerType(tv.ty);
3234 const llvm_ty = try o.lowerType(tv.ty);
33413235 switch (tv.ty.floatBits(target)) {
33423236 16 => {
33433237 const repr = @bitCast(u16, tv.val.toFloat(f16, mod));
3344 const llvm_i16 = dg.context.intType(16);
3238 const llvm_i16 = o.context.intType(16);
33453239 const int = llvm_i16.constInt(repr, .False);
33463240 return int.constBitCast(llvm_ty);
33473241 },
33483242 32 => {
33493243 const repr = @bitCast(u32, tv.val.toFloat(f32, mod));
3350 const llvm_i32 = dg.context.intType(32);
3244 const llvm_i32 = o.context.intType(32);
33513245 const int = llvm_i32.constInt(repr, .False);
33523246 return int.constBitCast(llvm_ty);
33533247 },
33543248 64 => {
33553249 const repr = @bitCast(u64, tv.val.toFloat(f64, mod));
3356 const llvm_i64 = dg.context.intType(64);
3250 const llvm_i64 = o.context.intType(64);
33573251 const int = llvm_i64.constInt(repr, .False);
33583252 return int.constBitCast(llvm_ty);
33593253 },
33603254 80 => {
33613255 const float = tv.val.toFloat(f80, mod);
33623256 const repr = std.math.break_f80(float);
3363 const llvm_i80 = dg.context.intType(80);
3257 const llvm_i80 = o.context.intType(80);
33643258 var x = llvm_i80.constInt(repr.exp, .False);
33653259 x = x.constShl(llvm_i80.constInt(64, .False));
33663260 x = x.constOr(llvm_i80.constInt(repr.fraction, .False));
......@@ -3377,7 +3271,7 @@ pub const DeclGen = struct {
33773271 if (native_endian == .Big) {
33783272 std.mem.swap(u64, &buf[0], &buf[1]);
33793273 }
3380 const int = dg.context.intType(128).constIntOfArbitraryPrecision(buf.len, &buf);
3274 const int = o.context.intType(128).constIntOfArbitraryPrecision(buf.len, &buf);
33813275 return int.constBitCast(llvm_ty);
33823276 },
33833277 else => unreachable,
......@@ -3389,14 +3283,14 @@ pub const DeclGen = struct {
33893283 else => .{ .ty = tv.ty.slicePtrFieldType(mod), .val = tv.val.slicePtr(mod) },
33903284 };
33913285 const llvm_ptr_val = switch (ptr.addr) {
3392 .decl => |decl| try dg.lowerDeclRefValue(ptr_tv, decl),
3393 .mut_decl => |mut_decl| try dg.lowerDeclRefValue(ptr_tv, mut_decl.decl),
3394 .int => |int| try dg.lowerIntAsPtr(int.toValue()),
3286 .decl => |decl| try o.lowerDeclRefValue(ptr_tv, decl),
3287 .mut_decl => |mut_decl| try o.lowerDeclRefValue(ptr_tv, mut_decl.decl),
3288 .int => |int| try o.lowerIntAsPtr(int.toValue()),
33953289 .eu_payload,
33963290 .opt_payload,
33973291 .elem,
33983292 .field,
3399 => try dg.lowerParentPtr(ptr_tv.val, ptr_tv.ty.ptrInfo(mod).packed_offset.bit_offset % 8 == 0),
3293 => try o.lowerParentPtr(ptr_tv.val, ptr_tv.ty.ptrInfo(mod).packed_offset.bit_offset % 8 == 0),
34003294 .comptime_field => unreachable,
34013295 };
34023296 switch (ptr.len) {
......@@ -3404,9 +3298,9 @@ pub const DeclGen = struct {
34043298 else => {
34053299 const fields: [2]*llvm.Value = .{
34063300 llvm_ptr_val,
3407 try dg.lowerValue(.{ .ty = Type.usize, .val = ptr.len.toValue() }),
3301 try o.lowerValue(.{ .ty = Type.usize, .val = ptr.len.toValue() }),
34083302 };
3409 return dg.context.constStruct(&fields, fields.len, .False);
3303 return o.context.constStruct(&fields, fields.len, .False);
34103304 },
34113305 }
34123306 },
......@@ -3414,7 +3308,7 @@ pub const DeclGen = struct {
34143308 comptime assert(optional_layout_version == 3);
34153309 const payload_ty = tv.ty.optionalChild(mod);
34163310
3417 const llvm_i8 = dg.context.intType(8);
3311 const llvm_i8 = o.context.intType(8);
34183312 const non_null_bit = switch (opt.val) {
34193313 .none => llvm_i8.constNull(),
34203314 else => llvm_i8.constInt(1, .False),
......@@ -3422,16 +3316,16 @@ pub const DeclGen = struct {
34223316 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
34233317 return non_null_bit;
34243318 }
3425 const llvm_ty = try dg.lowerType(tv.ty);
3319 const llvm_ty = try o.lowerType(tv.ty);
34263320 if (tv.ty.optionalReprIsPayload(mod)) return switch (opt.val) {
34273321 .none => llvm_ty.constNull(),
3428 else => |payload| dg.lowerValue(.{ .ty = payload_ty, .val = payload.toValue() }),
3322 else => |payload| o.lowerValue(.{ .ty = payload_ty, .val = payload.toValue() }),
34293323 };
34303324 assert(payload_ty.zigTypeTag(mod) != .Fn);
34313325
34323326 const llvm_field_count = llvm_ty.countStructElementTypes();
34333327 var fields_buf: [3]*llvm.Value = undefined;
3434 fields_buf[0] = try dg.lowerValue(.{
3328 fields_buf[0] = try o.lowerValue(.{
34353329 .ty = payload_ty,
34363330 .val = switch (opt.val) {
34373331 .none => try mod.intern(.{ .undef = payload_ty.toIntern() }),
......@@ -3443,33 +3337,32 @@ pub const DeclGen = struct {
34433337 assert(llvm_field_count == 3);
34443338 fields_buf[2] = llvm_ty.structGetTypeAtIndex(2).getUndef();
34453339 }
3446 return dg.context.constStruct(&fields_buf, llvm_field_count, .False);
3340 return o.context.constStruct(&fields_buf, llvm_field_count, .False);
34473341 },
34483342 .aggregate => |aggregate| switch (mod.intern_pool.indexToKey(tv.ty.toIntern())) {
34493343 .array_type => switch (aggregate.storage) {
3450 .bytes => |bytes| return dg.context.constString(
3344 .bytes => |bytes| return o.context.constString(
34513345 bytes.ptr,
34523346 @intCast(c_uint, tv.ty.arrayLenIncludingSentinel(mod)),
34533347 .True, // Don't null terminate. Bytes has the sentinel, if any.
34543348 ),
34553349 .elems => |elem_vals| {
34563350 const elem_ty = tv.ty.childType(mod);
3457 const gpa = dg.gpa;
34583351 const llvm_elems = try gpa.alloc(*llvm.Value, elem_vals.len);
34593352 defer gpa.free(llvm_elems);
34603353 var need_unnamed = false;
34613354 for (elem_vals, 0..) |elem_val, i| {
3462 llvm_elems[i] = try dg.lowerValue(.{ .ty = elem_ty, .val = elem_val.toValue() });
3463 need_unnamed = need_unnamed or dg.isUnnamedType(elem_ty, llvm_elems[i]);
3355 llvm_elems[i] = try o.lowerValue(.{ .ty = elem_ty, .val = elem_val.toValue() });
3356 need_unnamed = need_unnamed or o.isUnnamedType(elem_ty, llvm_elems[i]);
34643357 }
34653358 if (need_unnamed) {
3466 return dg.context.constStruct(
3359 return o.context.constStruct(
34673360 llvm_elems.ptr,
34683361 @intCast(c_uint, llvm_elems.len),
34693362 .True,
34703363 );
34713364 } else {
3472 const llvm_elem_ty = try dg.lowerType(elem_ty);
3365 const llvm_elem_ty = try o.lowerType(elem_ty);
34733366 return llvm_elem_ty.constArray(
34743367 llvm_elems.ptr,
34753368 @intCast(c_uint, llvm_elems.len),
......@@ -3481,31 +3374,30 @@ pub const DeclGen = struct {
34813374 const sentinel = tv.ty.sentinel(mod);
34823375 const len = @intCast(usize, tv.ty.arrayLen(mod));
34833376 const len_including_sent = len + @intFromBool(sentinel != null);
3484 const gpa = dg.gpa;
34853377 const llvm_elems = try gpa.alloc(*llvm.Value, len_including_sent);
34863378 defer gpa.free(llvm_elems);
34873379
34883380 var need_unnamed = false;
34893381 if (len != 0) {
34903382 for (llvm_elems[0..len]) |*elem| {
3491 elem.* = try dg.lowerValue(.{ .ty = elem_ty, .val = val.toValue() });
3383 elem.* = try o.lowerValue(.{ .ty = elem_ty, .val = val.toValue() });
34923384 }
3493 need_unnamed = need_unnamed or dg.isUnnamedType(elem_ty, llvm_elems[0]);
3385 need_unnamed = need_unnamed or o.isUnnamedType(elem_ty, llvm_elems[0]);
34943386 }
34953387
34963388 if (sentinel) |sent| {
3497 llvm_elems[len] = try dg.lowerValue(.{ .ty = elem_ty, .val = sent });
3498 need_unnamed = need_unnamed or dg.isUnnamedType(elem_ty, llvm_elems[len]);
3389 llvm_elems[len] = try o.lowerValue(.{ .ty = elem_ty, .val = sent });
3390 need_unnamed = need_unnamed or o.isUnnamedType(elem_ty, llvm_elems[len]);
34993391 }
35003392
35013393 if (need_unnamed) {
3502 return dg.context.constStruct(
3394 return o.context.constStruct(
35033395 llvm_elems.ptr,
35043396 @intCast(c_uint, llvm_elems.len),
35053397 .True,
35063398 );
35073399 } else {
3508 const llvm_elem_ty = try dg.lowerType(elem_ty);
3400 const llvm_elem_ty = try o.lowerType(elem_ty);
35093401 return llvm_elem_ty.constArray(
35103402 llvm_elems.ptr,
35113403 @intCast(c_uint, llvm_elems.len),
......@@ -3515,17 +3407,17 @@ pub const DeclGen = struct {
35153407 },
35163408 .vector_type => |vector_type| {
35173409 const elem_ty = vector_type.child.toType();
3518 const llvm_elems = try dg.gpa.alloc(*llvm.Value, vector_type.len);
3519 defer dg.gpa.free(llvm_elems);
3520 const llvm_i8 = dg.context.intType(8);
3410 const llvm_elems = try gpa.alloc(*llvm.Value, vector_type.len);
3411 defer gpa.free(llvm_elems);
3412 const llvm_i8 = o.context.intType(8);
35213413 for (llvm_elems, 0..) |*llvm_elem, i| {
35223414 llvm_elem.* = switch (aggregate.storage) {
35233415 .bytes => |bytes| llvm_i8.constInt(bytes[i], .False),
3524 .elems => |elems| try dg.lowerValue(.{
3416 .elems => |elems| try o.lowerValue(.{
35253417 .ty = elem_ty,
35263418 .val = elems[i].toValue(),
35273419 }),
3528 .repeated_elem => |elem| try dg.lowerValue(.{
3420 .repeated_elem => |elem| try o.lowerValue(.{
35293421 .ty = elem_ty,
35303422 .val = elem.toValue(),
35313423 }),
......@@ -3537,8 +3429,6 @@ pub const DeclGen = struct {
35373429 );
35383430 },
35393431 .anon_struct_type => |tuple| {
3540 const gpa = dg.gpa;
3541
35423432 var llvm_fields: std.ArrayListUnmanaged(*llvm.Value) = .{};
35433433 defer llvm_fields.deinit(gpa);
35443434
......@@ -3560,18 +3450,18 @@ pub const DeclGen = struct {
35603450
35613451 const padding_len = offset - prev_offset;
35623452 if (padding_len > 0) {
3563 const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
3453 const llvm_array_ty = o.context.intType(8).arrayType(@intCast(c_uint, padding_len));
35643454 // TODO make this and all other padding elsewhere in debug
35653455 // builds be 0xaa not undef.
35663456 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
35673457 }
35683458
3569 const field_llvm_val = try dg.lowerValue(.{
3459 const field_llvm_val = try o.lowerValue(.{
35703460 .ty = field_ty.toType(),
35713461 .val = try tv.val.fieldValue(mod, i),
35723462 });
35733463
3574 need_unnamed = need_unnamed or dg.isUnnamedType(field_ty.toType(), field_llvm_val);
3464 need_unnamed = need_unnamed or o.isUnnamedType(field_ty.toType(), field_llvm_val);
35753465
35763466 llvm_fields.appendAssumeCapacity(field_llvm_val);
35773467
......@@ -3582,19 +3472,19 @@ pub const DeclGen = struct {
35823472 offset = std.mem.alignForward(u64, offset, big_align);
35833473 const padding_len = offset - prev_offset;
35843474 if (padding_len > 0) {
3585 const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
3475 const llvm_array_ty = o.context.intType(8).arrayType(@intCast(c_uint, padding_len));
35863476 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
35873477 }
35883478 }
35893479
35903480 if (need_unnamed) {
3591 return dg.context.constStruct(
3481 return o.context.constStruct(
35923482 llvm_fields.items.ptr,
35933483 @intCast(c_uint, llvm_fields.items.len),
35943484 .False,
35953485 );
35963486 } else {
3597 const llvm_struct_ty = try dg.lowerType(tv.ty);
3487 const llvm_struct_ty = try o.lowerType(tv.ty);
35983488 return llvm_struct_ty.constNamedStruct(
35993489 llvm_fields.items.ptr,
36003490 @intCast(c_uint, llvm_fields.items.len),
......@@ -3603,13 +3493,12 @@ pub const DeclGen = struct {
36033493 },
36043494 .struct_type => |struct_type| {
36053495 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
3606 const llvm_struct_ty = try dg.lowerType(tv.ty);
3607 const gpa = dg.gpa;
3496 const llvm_struct_ty = try o.lowerType(tv.ty);
36083497
36093498 if (struct_obj.layout == .Packed) {
36103499 assert(struct_obj.haveLayout());
36113500 const big_bits = struct_obj.backing_int_ty.bitSize(mod);
3612 const int_llvm_ty = dg.context.intType(@intCast(c_uint, big_bits));
3501 const int_llvm_ty = o.context.intType(@intCast(c_uint, big_bits));
36133502 const fields = struct_obj.fields.values();
36143503 comptime assert(Type.packed_struct_layout_version == 2);
36153504 var running_int: *llvm.Value = int_llvm_ty.constNull();
......@@ -3617,12 +3506,12 @@ pub const DeclGen = struct {
36173506 for (fields, 0..) |field, i| {
36183507 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
36193508
3620 const non_int_val = try dg.lowerValue(.{
3509 const non_int_val = try o.lowerValue(.{
36213510 .ty = field.ty,
36223511 .val = try tv.val.fieldValue(mod, i),
36233512 });
36243513 const ty_bit_size = @intCast(u16, field.ty.bitSize(mod));
3625 const small_int_ty = dg.context.intType(ty_bit_size);
3514 const small_int_ty = o.context.intType(ty_bit_size);
36263515 const small_int_val = if (field.ty.isPtrAtRuntime(mod))
36273516 non_int_val.constPtrToInt(small_int_ty)
36283517 else
......@@ -3658,18 +3547,18 @@ pub const DeclGen = struct {
36583547
36593548 const padding_len = offset - prev_offset;
36603549 if (padding_len > 0) {
3661 const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
3550 const llvm_array_ty = o.context.intType(8).arrayType(@intCast(c_uint, padding_len));
36623551 // TODO make this and all other padding elsewhere in debug
36633552 // builds be 0xaa not undef.
36643553 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
36653554 }
36663555
3667 const field_llvm_val = try dg.lowerValue(.{
3556 const field_llvm_val = try o.lowerValue(.{
36683557 .ty = field.ty,
36693558 .val = try tv.val.fieldValue(mod, field_and_index.index),
36703559 });
36713560
3672 need_unnamed = need_unnamed or dg.isUnnamedType(field.ty, field_llvm_val);
3561 need_unnamed = need_unnamed or o.isUnnamedType(field.ty, field_llvm_val);
36733562
36743563 llvm_fields.appendAssumeCapacity(field_llvm_val);
36753564
......@@ -3680,13 +3569,13 @@ pub const DeclGen = struct {
36803569 offset = std.mem.alignForward(u64, offset, big_align);
36813570 const padding_len = offset - prev_offset;
36823571 if (padding_len > 0) {
3683 const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
3572 const llvm_array_ty = o.context.intType(8).arrayType(@intCast(c_uint, padding_len));
36843573 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
36853574 }
36863575 }
36873576
36883577 if (need_unnamed) {
3689 return dg.context.constStruct(
3578 return o.context.constStruct(
36903579 llvm_fields.items.ptr,
36913580 @intCast(c_uint, llvm_fields.items.len),
36923581 .False,
......@@ -3701,7 +3590,7 @@ pub const DeclGen = struct {
37013590 else => unreachable,
37023591 },
37033592 .un => {
3704 const llvm_union_ty = try dg.lowerType(tv.ty);
3593 const llvm_union_ty = try o.lowerType(tv.ty);
37053594 const tag_and_val: Value.Payload.Union.Data = switch (tv.val.toIntern()) {
37063595 .none => tv.val.castTag(.@"union").?.data,
37073596 else => switch (mod.intern_pool.indexToKey(tv.val.toIntern())) {
......@@ -3713,22 +3602,22 @@ pub const DeclGen = struct {
37133602 const layout = tv.ty.unionGetLayout(mod);
37143603
37153604 if (layout.payload_size == 0) {
3716 return lowerValue(dg, .{
3605 return lowerValue(o, .{
37173606 .ty = tv.ty.unionTagTypeSafety(mod).?,
37183607 .val = tag_and_val.tag,
37193608 });
37203609 }
37213610 const union_obj = mod.typeToUnion(tv.ty).?;
3722 const field_index = tv.ty.unionTagFieldIndex(tag_and_val.tag, dg.module).?;
3611 const field_index = tv.ty.unionTagFieldIndex(tag_and_val.tag, o.module).?;
37233612 assert(union_obj.haveFieldTypes());
37243613
37253614 const field_ty = union_obj.fields.values()[field_index].ty;
37263615 if (union_obj.layout == .Packed) {
37273616 if (!field_ty.hasRuntimeBits(mod))
37283617 return llvm_union_ty.constNull();
3729 const non_int_val = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val });
3618 const non_int_val = try lowerValue(o, .{ .ty = field_ty, .val = tag_and_val.val });
37303619 const ty_bit_size = @intCast(u16, field_ty.bitSize(mod));
3731 const small_int_ty = dg.context.intType(ty_bit_size);
3620 const small_int_ty = o.context.intType(ty_bit_size);
37323621 const small_int_val = if (field_ty.isPtrAtRuntime(mod))
37333622 non_int_val.constPtrToInt(small_int_ty)
37343623 else
......@@ -3744,30 +3633,30 @@ pub const DeclGen = struct {
37443633 const payload = p: {
37453634 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {
37463635 const padding_len = @intCast(c_uint, layout.payload_size);
3747 break :p dg.context.intType(8).arrayType(padding_len).getUndef();
3636 break :p o.context.intType(8).arrayType(padding_len).getUndef();
37483637 }
3749 const field = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val });
3750 need_unnamed = need_unnamed or dg.isUnnamedType(field_ty, field);
3638 const field = try lowerValue(o, .{ .ty = field_ty, .val = tag_and_val.val });
3639 need_unnamed = need_unnamed or o.isUnnamedType(field_ty, field);
37513640 const field_size = field_ty.abiSize(mod);
37523641 if (field_size == layout.payload_size) {
37533642 break :p field;
37543643 }
37553644 const padding_len = @intCast(c_uint, layout.payload_size - field_size);
37563645 const fields: [2]*llvm.Value = .{
3757 field, dg.context.intType(8).arrayType(padding_len).getUndef(),
3646 field, o.context.intType(8).arrayType(padding_len).getUndef(),
37583647 };
3759 break :p dg.context.constStruct(&fields, fields.len, .True);
3648 break :p o.context.constStruct(&fields, fields.len, .True);
37603649 };
37613650
37623651 if (layout.tag_size == 0) {
37633652 const fields: [1]*llvm.Value = .{payload};
37643653 if (need_unnamed) {
3765 return dg.context.constStruct(&fields, fields.len, .False);
3654 return o.context.constStruct(&fields, fields.len, .False);
37663655 } else {
37673656 return llvm_union_ty.constNamedStruct(&fields, fields.len);
37683657 }
37693658 }
3770 const llvm_tag_value = try lowerValue(dg, .{
3659 const llvm_tag_value = try lowerValue(o, .{
37713660 .ty = tv.ty.unionTagTypeSafety(mod).?,
37723661 .val = tag_and_val.tag,
37733662 });
......@@ -3779,11 +3668,11 @@ pub const DeclGen = struct {
37793668 fields = .{ payload, llvm_tag_value, undefined };
37803669 }
37813670 if (layout.padding != 0) {
3782 fields[2] = dg.context.intType(8).arrayType(layout.padding).getUndef();
3671 fields[2] = o.context.intType(8).arrayType(layout.padding).getUndef();
37833672 fields_len = 3;
37843673 }
37853674 if (need_unnamed) {
3786 return dg.context.constStruct(&fields, fields_len, .False);
3675 return o.context.constStruct(&fields, fields_len, .False);
37873676 } else {
37883677 return llvm_union_ty.constNamedStruct(&fields, fields_len);
37893678 }
......@@ -3792,24 +3681,24 @@ pub const DeclGen = struct {
37923681 }
37933682 }
37943683
3795 fn lowerIntAsPtr(dg: *DeclGen, val: Value) Error!*llvm.Value {
3796 switch (dg.module.intern_pool.indexToKey(val.toIntern())) {
3797 .undef => return dg.context.pointerType(0).getUndef(),
3684 fn lowerIntAsPtr(o: *Object, val: Value) Error!*llvm.Value {
3685 switch (o.module.intern_pool.indexToKey(val.toIntern())) {
3686 .undef => return o.context.pointerType(0).getUndef(),
37983687 .int => {
37993688 var bigint_space: Value.BigIntSpace = undefined;
3800 const bigint = val.toBigInt(&bigint_space, dg.module);
3801 const llvm_int = lowerBigInt(dg, Type.usize, bigint);
3802 return llvm_int.constIntToPtr(dg.context.pointerType(0));
3689 const bigint = val.toBigInt(&bigint_space, o.module);
3690 const llvm_int = lowerBigInt(o, Type.usize, bigint);
3691 return llvm_int.constIntToPtr(o.context.pointerType(0));
38033692 },
38043693 else => unreachable,
38053694 }
38063695 }
38073696
3808 fn lowerBigInt(dg: *DeclGen, ty: Type, bigint: std.math.big.int.Const) *llvm.Value {
3809 const mod = dg.module;
3697 fn lowerBigInt(o: *Object, ty: Type, bigint: std.math.big.int.Const) *llvm.Value {
3698 const mod = o.module;
38103699 const int_info = ty.intInfo(mod);
38113700 assert(int_info.bits != 0);
3812 const llvm_type = dg.context.intType(int_info.bits);
3701 const llvm_type = o.context.intType(int_info.bits);
38133702
38143703 const unsigned_val = v: {
38153704 if (bigint.limbs.len == 1) {
......@@ -3835,26 +3724,26 @@ pub const DeclGen = struct {
38353724 };
38363725
38373726 fn lowerParentPtrDecl(
3838 dg: *DeclGen,
3727 o: *Object,
38393728 ptr_val: Value,
38403729 decl_index: Module.Decl.Index,
38413730 ) Error!*llvm.Value {
3842 const mod = dg.module;
3731 const mod = o.module;
38433732 const decl = mod.declPtr(decl_index);
38443733 try mod.markDeclAlive(decl);
38453734 const ptr_ty = try mod.singleMutPtrType(decl.ty);
3846 return try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index);
3735 return try o.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index);
38473736 }
38483737
3849 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {
3850 const mod = dg.module;
3738 fn lowerParentPtr(o: *Object, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {
3739 const mod = o.module;
38513740 const target = mod.getTarget();
38523741 return switch (mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr) {
3853 .decl => |decl| dg.lowerParentPtrDecl(ptr_val, decl),
3854 .mut_decl => |mut_decl| dg.lowerParentPtrDecl(ptr_val, mut_decl.decl),
3855 .int => |int| dg.lowerIntAsPtr(int.toValue()),
3742 .decl => |decl| o.lowerParentPtrDecl(ptr_val, decl),
3743 .mut_decl => |mut_decl| o.lowerParentPtrDecl(ptr_val, mut_decl.decl),
3744 .int => |int| o.lowerIntAsPtr(int.toValue()),
38563745 .eu_payload => |eu_ptr| {
3857 const parent_llvm_ptr = try dg.lowerParentPtr(eu_ptr.toValue(), true);
3746 const parent_llvm_ptr = try o.lowerParentPtr(eu_ptr.toValue(), true);
38583747
38593748 const eu_ty = mod.intern_pool.typeOf(eu_ptr).toType().childType(mod);
38603749 const payload_ty = eu_ty.errorUnionPayload(mod);
......@@ -3865,16 +3754,16 @@ pub const DeclGen = struct {
38653754 }
38663755
38673756 const payload_offset: u8 = if (payload_ty.abiAlignment(mod) > Type.anyerror.abiSize(mod)) 2 else 1;
3868 const llvm_u32 = dg.context.intType(32);
3757 const llvm_u32 = o.context.intType(32);
38693758 const indices: [2]*llvm.Value = .{
38703759 llvm_u32.constInt(0, .False),
38713760 llvm_u32.constInt(payload_offset, .False),
38723761 };
3873 const eu_llvm_ty = try dg.lowerType(eu_ty);
3762 const eu_llvm_ty = try o.lowerType(eu_ty);
38743763 return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
38753764 },
38763765 .opt_payload => |opt_ptr| {
3877 const parent_llvm_ptr = try dg.lowerParentPtr(opt_ptr.toValue(), true);
3766 const parent_llvm_ptr = try o.lowerParentPtr(opt_ptr.toValue(), true);
38783767
38793768 const opt_ty = mod.intern_pool.typeOf(opt_ptr).toType().childType(mod);
38803769 const payload_ty = opt_ty.optionalChild(mod);
......@@ -3886,32 +3775,32 @@ pub const DeclGen = struct {
38863775 return parent_llvm_ptr;
38873776 }
38883777
3889 const llvm_u32 = dg.context.intType(32);
3778 const llvm_u32 = o.context.intType(32);
38903779 const indices: [2]*llvm.Value = .{
38913780 llvm_u32.constInt(0, .False),
38923781 llvm_u32.constInt(0, .False),
38933782 };
3894 const opt_llvm_ty = try dg.lowerType(opt_ty);
3783 const opt_llvm_ty = try o.lowerType(opt_ty);
38953784 return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
38963785 },
38973786 .comptime_field => unreachable,
38983787 .elem => |elem_ptr| {
3899 const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.base.toValue(), true);
3788 const parent_llvm_ptr = try o.lowerParentPtr(elem_ptr.base.toValue(), true);
39003789
3901 const llvm_usize = try dg.lowerType(Type.usize);
3790 const llvm_usize = try o.lowerType(Type.usize);
39023791 const indices: [1]*llvm.Value = .{
39033792 llvm_usize.constInt(elem_ptr.index, .False),
39043793 };
39053794 const elem_ty = mod.intern_pool.typeOf(elem_ptr.base).toType().elemType2(mod);
3906 const elem_llvm_ty = try dg.lowerType(elem_ty);
3795 const elem_llvm_ty = try o.lowerType(elem_ty);
39073796 return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
39083797 },
39093798 .field => |field_ptr| {
3910 const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.base.toValue(), byte_aligned);
3799 const parent_llvm_ptr = try o.lowerParentPtr(field_ptr.base.toValue(), byte_aligned);
39113800 const parent_ty = mod.intern_pool.typeOf(field_ptr.base).toType().childType(mod);
39123801
39133802 const field_index = @intCast(u32, field_ptr.index);
3914 const llvm_u32 = dg.context.intType(32);
3803 const llvm_u32 = o.context.intType(32);
39153804 switch (parent_ty.zigTypeTag(mod)) {
39163805 .Union => {
39173806 if (parent_ty.containerLayout(mod) == .Packed) {
......@@ -3932,13 +3821,13 @@ pub const DeclGen = struct {
39323821 llvm_u32.constInt(0, .False),
39333822 llvm_u32.constInt(llvm_pl_index, .False),
39343823 };
3935 const parent_llvm_ty = try dg.lowerType(parent_ty);
3824 const parent_llvm_ty = try o.lowerType(parent_ty);
39363825 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
39373826 },
39383827 .Struct => {
39393828 if (parent_ty.containerLayout(mod) == .Packed) {
39403829 if (!byte_aligned) return parent_llvm_ptr;
3941 const llvm_usize = dg.context.intType(target.ptrBitWidth());
3830 const llvm_usize = o.context.intType(target.ptrBitWidth());
39423831 const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);
39433832 // count bits of fields before this one
39443833 const prev_bits = b: {
......@@ -3951,11 +3840,11 @@ pub const DeclGen = struct {
39513840 };
39523841 const byte_offset = llvm_usize.constInt(prev_bits / 8, .False);
39533842 const field_addr = base_addr.constAdd(byte_offset);
3954 const final_llvm_ty = dg.context.pointerType(0);
3843 const final_llvm_ty = o.context.pointerType(0);
39553844 return field_addr.constIntToPtr(final_llvm_ty);
39563845 }
39573846
3958 const parent_llvm_ty = try dg.lowerType(parent_ty);
3847 const parent_llvm_ty = try o.lowerType(parent_ty);
39593848 if (llvmField(parent_ty, field_index, mod)) |llvm_field| {
39603849 const indices: [2]*llvm.Value = .{
39613850 llvm_u32.constInt(0, .False),
......@@ -3974,7 +3863,7 @@ pub const DeclGen = struct {
39743863 llvm_u32.constInt(0, .False),
39753864 llvm_u32.constInt(field_index, .False),
39763865 };
3977 const parent_llvm_ty = try dg.lowerType(parent_ty);
3866 const parent_llvm_ty = try o.lowerType(parent_ty);
39783867 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
39793868 },
39803869 else => unreachable,
......@@ -3984,11 +3873,11 @@ pub const DeclGen = struct {
39843873 }
39853874
39863875 fn lowerDeclRefValue(
3987 self: *DeclGen,
3876 o: *Object,
39883877 tv: TypedValue,
39893878 decl_index: Module.Decl.Index,
39903879 ) Error!*llvm.Value {
3991 const mod = self.module;
3880 const mod = o.module;
39923881
39933882 // In the case of something like:
39943883 // fn foo() void {}
......@@ -3998,11 +3887,11 @@ pub const DeclGen = struct {
39983887 const decl = mod.declPtr(decl_index);
39993888 if (decl.val.getFunction(mod)) |func| {
40003889 if (func.owner_decl != decl_index) {
4001 return self.lowerDeclRefValue(tv, func.owner_decl);
3890 return o.lowerDeclRefValue(tv, func.owner_decl);
40023891 }
40033892 } else if (decl.val.getExternFunc(mod)) |func| {
40043893 if (func.decl != decl_index) {
4005 return self.lowerDeclRefValue(tv, func.decl);
3894 return o.lowerDeclRefValue(tv, func.decl);
40063895 }
40073896 }
40083897
......@@ -4010,25 +3899,25 @@ pub const DeclGen = struct {
40103899 if ((!is_fn_body and !decl.ty.hasRuntimeBits(mod)) or
40113900 (is_fn_body and mod.typeToFunc(decl.ty).?.is_generic))
40123901 {
4013 return self.lowerPtrToVoid(tv.ty);
3902 return o.lowerPtrToVoid(tv.ty);
40143903 }
40153904
40163905 try mod.markDeclAlive(decl);
40173906
40183907 const llvm_decl_val = if (is_fn_body)
4019 try self.resolveLlvmFunction(decl_index)
3908 try o.resolveLlvmFunction(decl_index)
40203909 else
4021 try self.resolveGlobalDecl(decl_index);
3910 try o.resolveGlobalDecl(decl_index);
40223911
40233912 const target = mod.getTarget();
40243913 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
40253914 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);
40263915 const llvm_val = if (llvm_wanted_addrspace != llvm_actual_addrspace) blk: {
4027 const llvm_decl_wanted_ptr_ty = self.context.pointerType(llvm_wanted_addrspace);
3916 const llvm_decl_wanted_ptr_ty = o.context.pointerType(llvm_wanted_addrspace);
40283917 break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty);
40293918 } else llvm_decl_val;
40303919
4031 const llvm_type = try self.lowerType(tv.ty);
3920 const llvm_type = try o.lowerType(tv.ty);
40323921 if (tv.ty.zigTypeTag(mod) == .Int) {
40333922 return llvm_val.constPtrToInt(llvm_type);
40343923 } else {
......@@ -4036,15 +3925,15 @@ pub const DeclGen = struct {
40363925 }
40373926 }
40383927
4039 fn lowerPtrToVoid(dg: *DeclGen, ptr_ty: Type) !*llvm.Value {
4040 const mod = dg.module;
3928 fn lowerPtrToVoid(o: *Object, ptr_ty: Type) !*llvm.Value {
3929 const mod = o.module;
40413930 // Even though we are pointing at something which has zero bits (e.g. `void`),
40423931 // Pointers are defined to have bits. So we must return something here.
40433932 // The value cannot be undefined, because we use the `nonnull` annotation
40443933 // for non-optional pointers. We also need to respect the alignment, even though
40453934 // the address will never be dereferenced.
4046 const llvm_usize = try dg.lowerType(Type.usize);
4047 const llvm_ptr_ty = try dg.lowerType(ptr_ty);
3935 const llvm_usize = try o.lowerType(Type.usize);
3936 const llvm_ptr_ty = try o.lowerType(ptr_ty);
40483937 if (ptr_ty.ptrInfo(mod).flags.alignment.toByteUnitsOptional()) |alignment| {
40493938 return llvm_usize.constInt(alignment, .False).constIntToPtr(llvm_ptr_ty);
40503939 }
......@@ -4053,7 +3942,7 @@ pub const DeclGen = struct {
40533942 // have an "undef_but_not_null" attribute. As an example, if this `alloc` AIR
40543943 // instruction is followed by a `wrap_optional`, it will return this value
40553944 // verbatim, and the result should test as non-null.
4056 const target = dg.module.getTarget();
3945 const target = mod.getTarget();
40573946 const int = switch (target.ptrBitWidth()) {
40583947 16 => llvm_usize.constInt(0xaaaa, .False),
40593948 32 => llvm_usize.constInt(0xaaaaaaaa, .False),
......@@ -4063,16 +3952,16 @@ pub const DeclGen = struct {
40633952 return int.constIntToPtr(llvm_ptr_ty);
40643953 }
40653954
4066 fn addAttr(dg: DeclGen, val: *llvm.Value, index: llvm.AttributeIndex, name: []const u8) void {
4067 return dg.addAttrInt(val, index, name, 0);
3955 fn addAttr(o: *Object, val: *llvm.Value, index: llvm.AttributeIndex, name: []const u8) void {
3956 return o.addAttrInt(val, index, name, 0);
40683957 }
40693958
4070 fn addArgAttr(dg: DeclGen, fn_val: *llvm.Value, param_index: u32, attr_name: []const u8) void {
4071 return dg.addAttr(fn_val, param_index + 1, attr_name);
3959 fn addArgAttr(o: *Object, fn_val: *llvm.Value, param_index: u32, attr_name: []const u8) void {
3960 return o.addAttr(fn_val, param_index + 1, attr_name);
40723961 }
40733962
4074 fn addArgAttrInt(dg: DeclGen, fn_val: *llvm.Value, param_index: u32, attr_name: []const u8, int: u64) void {
4075 return dg.addAttrInt(fn_val, param_index + 1, attr_name, int);
3963 fn addArgAttrInt(o: *Object, fn_val: *llvm.Value, param_index: u32, attr_name: []const u8, int: u64) void {
3964 return o.addAttrInt(fn_val, param_index + 1, attr_name, int);
40763965 }
40773966
40783967 fn removeAttr(val: *llvm.Value, index: llvm.AttributeIndex, name: []const u8) void {
......@@ -4082,7 +3971,7 @@ pub const DeclGen = struct {
40823971 }
40833972
40843973 fn addAttrInt(
4085 dg: DeclGen,
3974 o: *Object,
40863975 val: *llvm.Value,
40873976 index: llvm.AttributeIndex,
40883977 name: []const u8,
......@@ -4090,18 +3979,18 @@ pub const DeclGen = struct {
40903979 ) void {
40913980 const kind_id = llvm.getEnumAttributeKindForName(name.ptr, name.len);
40923981 assert(kind_id != 0);
4093 const llvm_attr = dg.context.createEnumAttribute(kind_id, int);
3982 const llvm_attr = o.context.createEnumAttribute(kind_id, int);
40943983 val.addAttributeAtIndex(index, llvm_attr);
40953984 }
40963985
40973986 fn addAttrString(
4098 dg: *DeclGen,
3987 o: *Object,
40993988 val: *llvm.Value,
41003989 index: llvm.AttributeIndex,
41013990 name: []const u8,
41023991 value: []const u8,
41033992 ) void {
4104 const llvm_attr = dg.context.createStringAttribute(
3993 const llvm_attr = o.context.createStringAttribute(
41053994 name.ptr,
41063995 @intCast(c_uint, name.len),
41073996 value.ptr,
......@@ -4110,94 +3999,193 @@ pub const DeclGen = struct {
41103999 val.addAttributeAtIndex(index, llvm_attr);
41114000 }
41124001
4113 fn addFnAttr(dg: DeclGen, val: *llvm.Value, name: []const u8) void {
4114 dg.addAttr(val, std.math.maxInt(llvm.AttributeIndex), name);
4002 fn addFnAttr(o: *Object, val: *llvm.Value, name: []const u8) void {
4003 o.addAttr(val, std.math.maxInt(llvm.AttributeIndex), name);
41154004 }
41164005
4117 fn addFnAttrString(dg: *DeclGen, val: *llvm.Value, name: []const u8, value: []const u8) void {
4118 dg.addAttrString(val, std.math.maxInt(llvm.AttributeIndex), name, value);
4006 fn addFnAttrString(o: *Object, val: *llvm.Value, name: []const u8, value: []const u8) void {
4007 o.addAttrString(val, std.math.maxInt(llvm.AttributeIndex), name, value);
41194008 }
41204009
41214010 fn removeFnAttr(fn_val: *llvm.Value, name: []const u8) void {
41224011 removeAttr(fn_val, std.math.maxInt(llvm.AttributeIndex), name);
41234012 }
41244013
4125 fn addFnAttrInt(dg: DeclGen, fn_val: *llvm.Value, name: []const u8, int: u64) void {
4126 return dg.addAttrInt(fn_val, std.math.maxInt(llvm.AttributeIndex), name, int);
4014 fn addFnAttrInt(o: *Object, fn_val: *llvm.Value, name: []const u8, int: u64) void {
4015 return o.addAttrInt(fn_val, std.math.maxInt(llvm.AttributeIndex), name, int);
41274016 }
41284017
41294018 /// If the operand type of an atomic operation is not byte sized we need to
41304019 /// widen it before using it and then truncate the result.
41314020 /// RMW exchange of floating-point values is bitcasted to same-sized integer
41324021 /// types to work around a LLVM deficiency when targeting ARM/AArch64.
4133 fn getAtomicAbiType(dg: *DeclGen, ty: Type, is_rmw_xchg: bool) ?*llvm.Type {
4134 const mod = dg.module;
4022 fn getAtomicAbiType(o: *Object, ty: Type, is_rmw_xchg: bool) ?*llvm.Type {
4023 const mod = o.module;
41354024 const int_ty = switch (ty.zigTypeTag(mod)) {
41364025 .Int => ty,
41374026 .Enum => ty.intTagType(mod),
41384027 .Float => {
41394028 if (!is_rmw_xchg) return null;
4140 return dg.context.intType(@intCast(c_uint, ty.abiSize(mod) * 8));
4029 return o.context.intType(@intCast(c_uint, ty.abiSize(mod) * 8));
41414030 },
4142 .Bool => return dg.context.intType(8),
4031 .Bool => return o.context.intType(8),
41434032 else => return null,
41444033 };
41454034 const bit_count = int_ty.intInfo(mod).bits;
41464035 if (!std.math.isPowerOfTwo(bit_count) or (bit_count % 8) != 0) {
4147 return dg.context.intType(@intCast(c_uint, int_ty.abiSize(mod) * 8));
4036 return o.context.intType(@intCast(c_uint, int_ty.abiSize(mod) * 8));
41484037 } else {
41494038 return null;
41504039 }
41514040 }
41524041
41534042 fn addByValParamAttrs(
4154 dg: DeclGen,
4043 o: *Object,
41554044 llvm_fn: *llvm.Value,
41564045 param_ty: Type,
41574046 param_index: u32,
41584047 fn_info: InternPool.Key.FuncType,
41594048 llvm_arg_i: u32,
41604049 ) void {
4161 const mod = dg.module;
4050 const mod = o.module;
41624051 if (param_ty.isPtrAtRuntime(mod)) {
41634052 const ptr_info = param_ty.ptrInfo(mod);
41644053 if (math.cast(u5, param_index)) |i| {
41654054 if (@truncate(u1, fn_info.noalias_bits >> i) != 0) {
4166 dg.addArgAttr(llvm_fn, llvm_arg_i, "noalias");
4055 o.addArgAttr(llvm_fn, llvm_arg_i, "noalias");
41674056 }
41684057 }
41694058 if (!param_ty.isPtrLikeOptional(mod) and !ptr_info.flags.is_allowzero) {
4170 dg.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");
4059 o.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");
41714060 }
41724061 if (ptr_info.flags.is_const) {
4173 dg.addArgAttr(llvm_fn, llvm_arg_i, "readonly");
4062 o.addArgAttr(llvm_fn, llvm_arg_i, "readonly");
41744063 }
41754064 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse
41764065 @max(ptr_info.child.toType().abiAlignment(mod), 1);
4177 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", elem_align);
4066 o.addArgAttrInt(llvm_fn, llvm_arg_i, "align", elem_align);
41784067 } else if (ccAbiPromoteInt(fn_info.cc, mod, param_ty)) |s| switch (s) {
4179 .signed => dg.addArgAttr(llvm_fn, llvm_arg_i, "signext"),
4180 .unsigned => dg.addArgAttr(llvm_fn, llvm_arg_i, "zeroext"),
4068 .signed => o.addArgAttr(llvm_fn, llvm_arg_i, "signext"),
4069 .unsigned => o.addArgAttr(llvm_fn, llvm_arg_i, "zeroext"),
41814070 };
41824071 }
41834072
41844073 fn addByRefParamAttrs(
4185 dg: DeclGen,
4074 o: *Object,
41864075 llvm_fn: *llvm.Value,
41874076 llvm_arg_i: u32,
41884077 alignment: u32,
41894078 byval_attr: bool,
41904079 param_llvm_ty: *llvm.Type,
41914080 ) void {
4192 dg.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");
4193 dg.addArgAttr(llvm_fn, llvm_arg_i, "readonly");
4194 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", alignment);
4081 o.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");
4082 o.addArgAttr(llvm_fn, llvm_arg_i, "readonly");
4083 o.addArgAttrInt(llvm_fn, llvm_arg_i, "align", alignment);
41954084 if (byval_attr) {
41964085 llvm_fn.addByValAttr(llvm_arg_i, param_llvm_ty);
41974086 }
41984087 }
41994088};
42004089
4090pub const DeclGen = struct {
4091 object: *Object,
4092 decl: *Module.Decl,
4093 decl_index: Module.Decl.Index,
4094 err_msg: ?*Module.ErrorMsg,
4095
4096 fn todo(dg: *DeclGen, comptime format: []const u8, args: anytype) Error {
4097 @setCold(true);
4098 assert(dg.err_msg == null);
4099 const o = dg.object;
4100 const gpa = o.gpa;
4101 const mod = o.module;
4102 const src_loc = LazySrcLoc.nodeOffset(0).toSrcLoc(dg.decl, mod);
4103 dg.err_msg = try Module.ErrorMsg.create(gpa, src_loc, "TODO (LLVM): " ++ format, args);
4104 return error.CodegenFail;
4105 }
4106
4107 fn genDecl(dg: *DeclGen) !void {
4108 const o = dg.object;
4109 const mod = o.module;
4110 const decl = dg.decl;
4111 const decl_index = dg.decl_index;
4112 assert(decl.has_tv);
4113
4114 if (decl.val.getExternFunc(mod)) |extern_func| {
4115 _ = try o.resolveLlvmFunction(extern_func.decl);
4116 } else {
4117 const target = mod.getTarget();
4118 var global = try o.resolveGlobalDecl(decl_index);
4119 global.setAlignment(decl.getAlignment(mod));
4120 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| global.setSection(s);
4121 assert(decl.has_tv);
4122 const init_val = if (decl.val.getVariable(mod)) |variable| init_val: {
4123 break :init_val variable.init;
4124 } else init_val: {
4125 global.setGlobalConstant(.True);
4126 break :init_val decl.val.toIntern();
4127 };
4128 if (init_val != .none) {
4129 const llvm_init = try o.lowerValue(.{ .ty = decl.ty, .val = init_val.toValue() });
4130 if (global.globalGetValueType() == llvm_init.typeOf()) {
4131 global.setInitializer(llvm_init);
4132 } else {
4133 // LLVM does not allow us to change the type of globals. So we must
4134 // create a new global with the correct type, copy all its attributes,
4135 // and then update all references to point to the new global,
4136 // delete the original, and rename the new one to the old one's name.
4137 // This is necessary because LLVM does not support const bitcasting
4138 // a struct with padding bytes, which is needed to lower a const union value
4139 // to LLVM, when a field other than the most-aligned is active. Instead,
4140 // we must lower to an unnamed struct, and pointer cast at usage sites
4141 // of the global. Such an unnamed struct is the cause of the global type
4142 // mismatch, because we don't have the LLVM type until the *value* is created,
4143 // whereas the global needs to be created based on the type alone, because
4144 // lowering the value may reference the global as a pointer.
4145 // Related: https://github.com/ziglang/zig/issues/13265
4146 const llvm_global_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);
4147 const new_global = o.llvm_module.addGlobalInAddressSpace(
4148 llvm_init.typeOf(),
4149 "",
4150 llvm_global_addrspace,
4151 );
4152 new_global.setLinkage(global.getLinkage());
4153 new_global.setUnnamedAddr(global.getUnnamedAddress());
4154 new_global.setAlignment(global.getAlignment());
4155 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
4156 new_global.setSection(s);
4157 new_global.setInitializer(llvm_init);
4158 // TODO: How should this work then the address space of a global changed?
4159 global.replaceAllUsesWith(new_global);
4160 o.decl_map.putAssumeCapacity(decl_index, new_global);
4161 new_global.takeName(global);
4162 global.deleteGlobal();
4163 global = new_global;
4164 }
4165 }
4166
4167 if (o.di_builder) |dib| {
4168 const di_file = try o.getDIFile(o.gpa, mod.namespacePtr(decl.src_namespace).file_scope);
4169
4170 const line_number = decl.src_line + 1;
4171 const is_internal_linkage = !o.module.decl_exports.contains(decl_index);
4172 const di_global = dib.createGlobalVariableExpression(
4173 di_file.toScope(),
4174 mod.intern_pool.stringToSlice(decl.name),
4175 global.getValueName(),
4176 di_file,
4177 line_number,
4178 try o.lowerDebugType(decl.ty, .full),
4179 is_internal_linkage,
4180 );
4181
4182 try o.di_map.put(o.gpa, dg.decl, di_global.getVariable().toNode());
4183 if (!is_internal_linkage or decl.isExtern(mod)) global.attachMetaData(di_global);
4184 }
4185 }
4186 }
4187};
4188
42014189pub const FuncGen = struct {
42024190 gpa: Allocator,
42034191 dg: *DeclGen,
......@@ -4268,15 +4256,13 @@ pub const FuncGen = struct {
42684256 return self.dg.todo(format, args);
42694257 }
42704258
4271 fn llvmModule(self: *FuncGen) *llvm.Module {
4272 return self.dg.object.llvm_module;
4273 }
4274
42754259 fn resolveInst(self: *FuncGen, inst: Air.Inst.Ref) !*llvm.Value {
4276 const gop = try self.func_inst_table.getOrPut(self.dg.gpa, inst);
4260 const gpa = self.gpa;
4261 const gop = try self.func_inst_table.getOrPut(gpa, inst);
42774262 if (gop.found_existing) return gop.value_ptr.*;
42784263
4279 const mod = self.dg.module;
4264 const o = self.dg.object;
4265 const mod = o.module;
42804266 const llvm_val = try self.resolveValue(.{
42814267 .ty = self.typeOf(inst),
42824268 .val = (try self.air.value(inst, mod)).?,
......@@ -4286,8 +4272,9 @@ pub const FuncGen = struct {
42864272 }
42874273
42884274 fn resolveValue(self: *FuncGen, tv: TypedValue) !*llvm.Value {
4289 const mod = self.dg.module;
4290 const llvm_val = try self.dg.lowerValue(tv);
4275 const o = self.dg.object;
4276 const mod = o.module;
4277 const llvm_val = try o.lowerValue(tv);
42914278 if (!isByRef(tv.ty, mod)) return llvm_val;
42924279
42934280 // We have an LLVM value but we need to create a global constant and
......@@ -4295,7 +4282,7 @@ pub const FuncGen = struct {
42954282 const target = mod.getTarget();
42964283 const llvm_wanted_addrspace = toLlvmAddressSpace(.generic, target);
42974284 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(.generic, target);
4298 const global = self.dg.object.llvm_module.addGlobalInAddressSpace(llvm_val.typeOf(), "", llvm_actual_addrspace);
4285 const global = o.llvm_module.addGlobalInAddressSpace(llvm_val.typeOf(), "", llvm_actual_addrspace);
42994286 global.setInitializer(llvm_val);
43004287 global.setLinkage(.Private);
43014288 global.setGlobalConstant(.True);
......@@ -4309,7 +4296,8 @@ pub const FuncGen = struct {
43094296 }
43104297
43114298 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {
4312 const mod = self.dg.module;
4299 const o = self.dg.object;
4300 const mod = o.module;
43134301 const ip = &mod.intern_pool;
43144302 const air_tags = self.air.instructions.items(.tag);
43154303 for (body, 0..) |inst, i| {
......@@ -4563,7 +4551,8 @@ pub const FuncGen = struct {
45634551 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
45644552 const extra = self.air.extraData(Air.Call, pl_op.payload);
45654553 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
4566 const mod = self.dg.module;
4554 const o = self.dg.object;
4555 const mod = o.module;
45674556 const callee_ty = self.typeOf(pl_op.operand);
45684557 const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) {
45694558 .Fn => callee_ty,
......@@ -4580,26 +4569,26 @@ pub const FuncGen = struct {
45804569 defer llvm_args.deinit();
45814570
45824571 const ret_ptr = if (!sret) null else blk: {
4583 const llvm_ret_ty = try self.dg.lowerType(return_type);
4572 const llvm_ret_ty = try o.lowerType(return_type);
45844573 const ret_ptr = self.buildAlloca(llvm_ret_ty, return_type.abiAlignment(mod));
45854574 try llvm_args.append(ret_ptr);
45864575 break :blk ret_ptr;
45874576 };
45884577
45894578 const err_return_tracing = return_type.isError(mod) and
4590 self.dg.module.comp.bin_file.options.error_return_tracing;
4579 o.module.comp.bin_file.options.error_return_tracing;
45914580 if (err_return_tracing) {
45924581 try llvm_args.append(self.err_ret_trace.?);
45934582 }
45944583
4595 var it = iterateParamTypes(self.dg, fn_info);
4584 var it = iterateParamTypes(o, fn_info);
45964585 while (it.nextCall(self, args)) |lowering| switch (lowering) {
45974586 .no_bits => continue,
45984587 .byval => {
45994588 const arg = args[it.zig_index - 1];
46004589 const param_ty = self.typeOf(arg);
46014590 const llvm_arg = try self.resolveInst(arg);
4602 const llvm_param_ty = try self.dg.lowerType(param_ty);
4591 const llvm_param_ty = try o.lowerType(param_ty);
46034592 if (isByRef(param_ty, mod)) {
46044593 const alignment = param_ty.abiAlignment(mod);
46054594 const load_inst = self.builder.buildLoad(llvm_param_ty, llvm_arg, "");
......@@ -4630,7 +4619,7 @@ pub const FuncGen = struct {
46304619 const llvm_arg = try self.resolveInst(arg);
46314620
46324621 const alignment = param_ty.abiAlignment(mod);
4633 const param_llvm_ty = try self.dg.lowerType(param_ty);
4622 const param_llvm_ty = try o.lowerType(param_ty);
46344623 const arg_ptr = self.buildAlloca(param_llvm_ty, alignment);
46354624 if (isByRef(param_ty, mod)) {
46364625 const load_inst = self.builder.buildLoad(param_llvm_ty, llvm_arg, "");
......@@ -4662,7 +4651,7 @@ pub const FuncGen = struct {
46624651 // a local, store as one type, and then load as another type.
46634652 const alignment = @max(
46644653 param_ty.abiAlignment(mod),
4665 self.dg.object.target_data.abiAlignmentOfType(int_llvm_ty),
4654 o.target_data.abiAlignmentOfType(int_llvm_ty),
46664655 );
46674656 const int_ptr = self.buildAlloca(int_llvm_ty, alignment);
46684657 const store_inst = self.builder.buildStore(llvm_arg, int_ptr);
......@@ -4721,7 +4710,7 @@ pub const FuncGen = struct {
47214710 llvm_arg = store_inst;
47224711 }
47234712
4724 const float_ty = try self.dg.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty, mod).?);
4713 const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty, mod).?);
47254714 const array_llvm_ty = float_ty.arrayType(count);
47264715
47274716 const alignment = arg_ty.abiAlignment(mod);
......@@ -4750,7 +4739,7 @@ pub const FuncGen = struct {
47504739 };
47514740
47524741 const call = self.builder.buildCall(
4753 try self.dg.lowerType(zig_fn_ty),
4742 try o.lowerType(zig_fn_ty),
47544743 llvm_fn,
47554744 llvm_args.items.ptr,
47564745 @intCast(c_uint, llvm_args.items.len),
......@@ -4761,7 +4750,7 @@ pub const FuncGen = struct {
47614750
47624751 if (callee_ty.zigTypeTag(mod) == .Pointer) {
47634752 // Add argument attributes for function pointer calls.
4764 it = iterateParamTypes(self.dg, fn_info);
4753 it = iterateParamTypes(o, fn_info);
47654754 it.llvm_index += @intFromBool(sret);
47664755 it.llvm_index += @intFromBool(err_return_tracing);
47674756 while (it.next()) |lowering| switch (lowering) {
......@@ -4769,18 +4758,18 @@ pub const FuncGen = struct {
47694758 const param_index = it.zig_index - 1;
47704759 const param_ty = fn_info.param_types[param_index].toType();
47714760 if (!isByRef(param_ty, mod)) {
4772 self.dg.addByValParamAttrs(call, param_ty, param_index, fn_info, it.llvm_index - 1);
4761 o.addByValParamAttrs(call, param_ty, param_index, fn_info, it.llvm_index - 1);
47734762 }
47744763 },
47754764 .byref => {
47764765 const param_index = it.zig_index - 1;
47774766 const param_ty = fn_info.param_types[param_index].toType();
4778 const param_llvm_ty = try self.dg.lowerType(param_ty);
4767 const param_llvm_ty = try o.lowerType(param_ty);
47794768 const alignment = param_ty.abiAlignment(mod);
4780 self.dg.addByRefParamAttrs(call, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
4769 o.addByRefParamAttrs(call, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
47814770 },
47824771 .byref_mut => {
4783 self.dg.addArgAttr(call, it.llvm_index - 1, "noundef");
4772 o.addArgAttr(call, it.llvm_index - 1, "noundef");
47844773 },
47854774 // No attributes needed for these.
47864775 .no_bits,
......@@ -4800,18 +4789,18 @@ pub const FuncGen = struct {
48004789
48014790 if (math.cast(u5, it.zig_index - 1)) |i| {
48024791 if (@truncate(u1, fn_info.noalias_bits >> i) != 0) {
4803 self.dg.addArgAttr(call, llvm_arg_i, "noalias");
4792 o.addArgAttr(call, llvm_arg_i, "noalias");
48044793 }
48054794 }
48064795 if (param_ty.zigTypeTag(mod) != .Optional) {
4807 self.dg.addArgAttr(call, llvm_arg_i, "nonnull");
4796 o.addArgAttr(call, llvm_arg_i, "nonnull");
48084797 }
48094798 if (ptr_info.flags.is_const) {
4810 self.dg.addArgAttr(call, llvm_arg_i, "readonly");
4799 o.addArgAttr(call, llvm_arg_i, "readonly");
48114800 }
48124801 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse
48134802 @max(ptr_info.child.toType().abiAlignment(mod), 1);
4814 self.dg.addArgAttrInt(call, llvm_arg_i, "align", elem_align);
4803 o.addArgAttrInt(call, llvm_arg_i, "align", elem_align);
48154804 },
48164805 };
48174806 }
......@@ -4824,7 +4813,7 @@ pub const FuncGen = struct {
48244813 return null;
48254814 }
48264815
4827 const llvm_ret_ty = try self.dg.lowerType(return_type);
4816 const llvm_ret_ty = try o.lowerType(return_type);
48284817
48294818 if (ret_ptr) |rp| {
48304819 call.setCallSret(llvm_ret_ty);
......@@ -4838,13 +4827,13 @@ pub const FuncGen = struct {
48384827 }
48394828 }
48404829
4841 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);
4830 const abi_ret_ty = try lowerFnRetTy(o, fn_info);
48424831
48434832 if (abi_ret_ty != llvm_ret_ty) {
48444833 // In this case the function return type is honoring the calling convention by having
48454834 // a different LLVM type than the usual one. We solve this here at the callsite
48464835 // by using our canonical type, then loading it if necessary.
4847 const alignment = self.dg.object.target_data.abiAlignmentOfType(abi_ret_ty);
4836 const alignment = o.target_data.abiAlignmentOfType(abi_ret_ty);
48484837 const rp = self.buildAlloca(llvm_ret_ty, alignment);
48494838 const store_inst = self.builder.buildStore(call, rp);
48504839 store_inst.setAlignment(alignment);
......@@ -4871,7 +4860,8 @@ pub const FuncGen = struct {
48714860 }
48724861
48734862 fn airRet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
4874 const mod = self.dg.module;
4863 const o = self.dg.object;
4864 const mod = o.module;
48754865 const un_op = self.air.instructions.items(.data)[inst].un_op;
48764866 const ret_ty = self.typeOf(un_op);
48774867 if (self.ret_ptr) |ret_ptr| {
......@@ -4887,7 +4877,7 @@ pub const FuncGen = struct {
48874877 // Functions with an empty error set are emitted with an error code
48884878 // return type and return zero so they can be function pointers coerced
48894879 // to functions that return anyerror.
4890 const err_int = try self.dg.lowerType(Type.anyerror);
4880 const err_int = try o.lowerType(Type.anyerror);
48914881 _ = self.builder.buildRet(err_int.constInt(0, .False));
48924882 } else {
48934883 _ = self.builder.buildRetVoid();
......@@ -4895,7 +4885,7 @@ pub const FuncGen = struct {
48954885 return null;
48964886 }
48974887
4898 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);
4888 const abi_ret_ty = try lowerFnRetTy(o, fn_info);
48994889 const operand = try self.resolveInst(un_op);
49004890 const alignment = ret_ty.abiAlignment(mod);
49014891
......@@ -4924,7 +4914,8 @@ pub const FuncGen = struct {
49244914 }
49254915
49264916 fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
4927 const mod = self.dg.module;
4917 const o = self.dg.object;
4918 const mod = o.module;
49284919 const un_op = self.air.instructions.items(.data)[inst].un_op;
49294920 const ptr_ty = self.typeOf(un_op);
49304921 const ret_ty = ptr_ty.childType(mod);
......@@ -4934,7 +4925,7 @@ pub const FuncGen = struct {
49344925 // Functions with an empty error set are emitted with an error code
49354926 // return type and return zero so they can be function pointers coerced
49364927 // to functions that return anyerror.
4937 const err_int = try self.dg.lowerType(Type.anyerror);
4928 const err_int = try o.lowerType(Type.anyerror);
49384929 _ = self.builder.buildRet(err_int.constInt(0, .False));
49394930 } else {
49404931 _ = self.builder.buildRetVoid();
......@@ -4946,7 +4937,7 @@ pub const FuncGen = struct {
49464937 return null;
49474938 }
49484939 const ptr = try self.resolveInst(un_op);
4949 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);
4940 const abi_ret_ty = try lowerFnRetTy(o, fn_info);
49504941 const loaded = self.builder.buildLoad(abi_ret_ty, ptr, "");
49514942 loaded.setAlignment(ret_ty.abiAlignment(mod));
49524943 _ = self.builder.buildRet(loaded);
......@@ -4954,32 +4945,34 @@ pub const FuncGen = struct {
49544945 }
49554946
49564947 fn airCVaArg(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
4948 const o = self.dg.object;
49574949 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
49584950 const list = try self.resolveInst(ty_op.operand);
49594951 const arg_ty = self.air.getRefType(ty_op.ty);
4960 const llvm_arg_ty = try self.dg.lowerType(arg_ty);
4952 const llvm_arg_ty = try o.lowerType(arg_ty);
49614953
49624954 return self.builder.buildVAArg(list, llvm_arg_ty, "");
49634955 }
49644956
49654957 fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
4958 const o = self.dg.object;
49664959 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
49674960 const src_list = try self.resolveInst(ty_op.operand);
49684961 const va_list_ty = self.air.getRefType(ty_op.ty);
4969 const llvm_va_list_ty = try self.dg.lowerType(va_list_ty);
4970 const mod = self.dg.module;
4962 const llvm_va_list_ty = try o.lowerType(va_list_ty);
4963 const mod = o.module;
49714964
49724965 const result_alignment = va_list_ty.abiAlignment(mod);
49734966 const dest_list = self.buildAlloca(llvm_va_list_ty, result_alignment);
49744967
49754968 const llvm_fn_name = "llvm.va_copy";
4976 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
4969 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
49774970 const param_types = [_]*llvm.Type{
49784971 self.context.pointerType(0),
49794972 self.context.pointerType(0),
49804973 };
49814974 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);
4982 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
4975 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type);
49834976 };
49844977
49854978 const args: [2]*llvm.Value = .{ dest_list, src_list };
......@@ -4995,14 +4988,15 @@ pub const FuncGen = struct {
49954988 }
49964989
49974990 fn airCVaEnd(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
4991 const o = self.dg.object;
49984992 const un_op = self.air.instructions.items(.data)[inst].un_op;
49994993 const list = try self.resolveInst(un_op);
50004994
50014995 const llvm_fn_name = "llvm.va_end";
5002 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
4996 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
50034997 const param_types = [_]*llvm.Type{self.context.pointerType(0)};
50044998 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);
5005 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
4999 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type);
50065000 };
50075001 const args: [1]*llvm.Value = .{list};
50085002 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
......@@ -5010,18 +5004,19 @@ pub const FuncGen = struct {
50105004 }
50115005
50125006 fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5013 const mod = self.dg.module;
5007 const o = self.dg.object;
5008 const mod = o.module;
50145009 const va_list_ty = self.typeOfIndex(inst);
5015 const llvm_va_list_ty = try self.dg.lowerType(va_list_ty);
5010 const llvm_va_list_ty = try o.lowerType(va_list_ty);
50165011
50175012 const result_alignment = va_list_ty.abiAlignment(mod);
50185013 const list = self.buildAlloca(llvm_va_list_ty, result_alignment);
50195014
50205015 const llvm_fn_name = "llvm.va_start";
5021 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
5016 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
50225017 const param_types = [_]*llvm.Type{self.context.pointerType(0)};
50235018 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);
5024 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
5019 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type);
50255020 };
50265021 const args: [1]*llvm.Value = .{list};
50275022 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
......@@ -5075,7 +5070,8 @@ pub const FuncGen = struct {
50755070 operand_ty: Type,
50765071 op: math.CompareOperator,
50775072 ) Allocator.Error!*llvm.Value {
5078 const mod = self.dg.module;
5073 const o = self.dg.object;
5074 const mod = o.module;
50795075 const scalar_ty = operand_ty.scalarType(mod);
50805076 const int_ty = switch (scalar_ty.zigTypeTag(mod)) {
50815077 .Enum => scalar_ty.intTagType(mod),
......@@ -5090,7 +5086,7 @@ pub const FuncGen = struct {
50905086 // We need to emit instructions to check for equality/inequality
50915087 // of optionals that are not pointers.
50925088 const is_by_ref = isByRef(scalar_ty, mod);
5093 const opt_llvm_ty = try self.dg.lowerType(scalar_ty);
5089 const opt_llvm_ty = try o.lowerType(scalar_ty);
50945090 const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref);
50955091 const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref);
50965092 const llvm_i2 = self.context.intType(2);
......@@ -5169,7 +5165,8 @@ pub const FuncGen = struct {
51695165 }
51705166
51715167 fn airBlock(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5172 const mod = self.dg.module;
5168 const o = self.dg.object;
5169 const mod = o.module;
51735170 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
51745171 const extra = self.air.extraData(Air.Block, ty_pl.payload);
51755172 const body = self.air.extra[extra.end..][0..extra.data.body_len];
......@@ -5199,7 +5196,7 @@ pub const FuncGen = struct {
51995196 const is_body = inst_ty.zigTypeTag(mod) == .Fn;
52005197 if (!is_body and !inst_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
52015198
5202 const raw_llvm_ty = try self.dg.lowerType(inst_ty);
5199 const raw_llvm_ty = try o.lowerType(inst_ty);
52035200
52045201 const llvm_ty = ty: {
52055202 // If the zig tag type is a function, this represents an actual function body; not
......@@ -5222,12 +5219,13 @@ pub const FuncGen = struct {
52225219 }
52235220
52245221 fn airBr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5222 const o = self.dg.object;
52255223 const branch = self.air.instructions.items(.data)[inst].br;
52265224 const block = self.blocks.get(branch.block_inst).?;
52275225
52285226 // Add the values to the lists only if the break provides a value.
52295227 const operand_ty = self.typeOf(branch.operand);
5230 const mod = self.dg.module;
5228 const mod = o.module;
52315229 if (operand_ty.hasRuntimeBitsIgnoreComptime(mod) or operand_ty.zigTypeTag(mod) == .Fn) {
52325230 const val = try self.resolveInst(branch.operand);
52335231
......@@ -5264,7 +5262,8 @@ pub const FuncGen = struct {
52645262 }
52655263
52665264 fn airTry(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
5267 const mod = self.dg.module;
5265 const o = self.dg.object;
5266 const mod = o.module;
52685267 const inst = body_tail[0];
52695268 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
52705269 const err_union = try self.resolveInst(pl_op.operand);
......@@ -5278,7 +5277,8 @@ pub const FuncGen = struct {
52785277 }
52795278
52805279 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5281 const mod = self.dg.module;
5280 const o = self.dg.object;
5281 const mod = o.module;
52825282 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
52835283 const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);
52845284 const err_union_ptr = try self.resolveInst(extra.data.ptr);
......@@ -5297,14 +5297,15 @@ pub const FuncGen = struct {
52975297 can_elide_load: bool,
52985298 is_unused: bool,
52995299 ) !?*llvm.Value {
5300 const mod = fg.dg.module;
5300 const o = fg.dg.object;
5301 const mod = o.module;
53015302 const payload_ty = err_union_ty.errorUnionPayload(mod);
53025303 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);
5303 const err_union_llvm_ty = try fg.dg.lowerType(err_union_ty);
5304 const err_union_llvm_ty = try o.lowerType(err_union_ty);
53045305
53055306 if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
53065307 const is_err = err: {
5307 const err_set_ty = try fg.dg.lowerType(Type.anyerror);
5308 const err_set_ty = try o.lowerType(Type.anyerror);
53085309 const zero = err_set_ty.constNull();
53095310 if (!payload_has_bits) {
53105311 // TODO add alignment to this load
......@@ -5359,7 +5360,8 @@ pub const FuncGen = struct {
53595360 }
53605361
53615362 fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5362 const mod = self.dg.module;
5363 const o = self.dg.object;
5364 const mod = o.module;
53635365 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
53645366 const cond = try self.resolveInst(pl_op.operand);
53655367 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
......@@ -5409,7 +5411,8 @@ pub const FuncGen = struct {
54095411 }
54105412
54115413 fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5412 const mod = self.dg.module;
5414 const o = self.dg.object;
5415 const mod = o.module;
54135416 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
54145417 const loop = self.air.extraData(Air.Block, ty_pl.payload);
54155418 const body = self.air.extra[loop.end..][0..loop.data.body_len];
......@@ -5432,13 +5435,14 @@ pub const FuncGen = struct {
54325435 }
54335436
54345437 fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5435 const mod = self.dg.module;
5438 const o = self.dg.object;
5439 const mod = o.module;
54365440 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
54375441 const operand_ty = self.typeOf(ty_op.operand);
54385442 const array_ty = operand_ty.childType(mod);
5439 const llvm_usize = try self.dg.lowerType(Type.usize);
5443 const llvm_usize = try o.lowerType(Type.usize);
54405444 const len = llvm_usize.constInt(array_ty.arrayLen(mod), .False);
5441 const slice_llvm_ty = try self.dg.lowerType(self.typeOfIndex(inst));
5445 const slice_llvm_ty = try o.lowerType(self.typeOfIndex(inst));
54425446 const operand = try self.resolveInst(ty_op.operand);
54435447 if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
54445448 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), operand, 0, "");
......@@ -5447,14 +5451,15 @@ pub const FuncGen = struct {
54475451 const indices: [2]*llvm.Value = .{
54485452 llvm_usize.constNull(), llvm_usize.constNull(),
54495453 };
5450 const array_llvm_ty = try self.dg.lowerType(array_ty);
5454 const array_llvm_ty = try o.lowerType(array_ty);
54515455 const ptr = self.builder.buildInBoundsGEP(array_llvm_ty, operand, &indices, indices.len, "");
54525456 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, "");
54535457 return self.builder.buildInsertValue(partial, len, 1, "");
54545458 }
54555459
54565460 fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5457 const mod = self.dg.module;
5461 const o = self.dg.object;
5462 const mod = o.module;
54585463 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
54595464
54605465 const operand = try self.resolveInst(ty_op.operand);
......@@ -5463,7 +5468,7 @@ pub const FuncGen = struct {
54635468
54645469 const dest_ty = self.typeOfIndex(inst);
54655470 const dest_scalar_ty = dest_ty.scalarType(mod);
5466 const dest_llvm_ty = try self.dg.lowerType(dest_ty);
5471 const dest_llvm_ty = try o.lowerType(dest_ty);
54675472 const target = mod.getTarget();
54685473
54695474 if (intrinsicsAllowed(dest_scalar_ty, target)) {
......@@ -5513,7 +5518,8 @@ pub const FuncGen = struct {
55135518 fn airIntFromFloat(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
55145519 self.builder.setFastMath(want_fast_math);
55155520
5516 const mod = self.dg.module;
5521 const o = self.dg.object;
5522 const mod = o.module;
55175523 const target = mod.getTarget();
55185524 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
55195525
......@@ -5523,7 +5529,7 @@ pub const FuncGen = struct {
55235529
55245530 const dest_ty = self.typeOfIndex(inst);
55255531 const dest_scalar_ty = dest_ty.scalarType(mod);
5526 const dest_llvm_ty = try self.dg.lowerType(dest_ty);
5532 const dest_llvm_ty = try o.lowerType(dest_ty);
55275533
55285534 if (intrinsicsAllowed(operand_scalar_ty, target)) {
55295535 // TODO set fast math flag
......@@ -5555,7 +5561,7 @@ pub const FuncGen = struct {
55555561 compiler_rt_dest_abbrev,
55565562 }) catch unreachable;
55575563
5558 const operand_llvm_ty = try self.dg.lowerType(operand_ty);
5564 const operand_llvm_ty = try o.lowerType(operand_ty);
55595565 const param_types = [1]*llvm.Type{operand_llvm_ty};
55605566 const libc_fn = self.getLibcFunction(fn_name, &param_types, libc_ret_ty);
55615567 const params = [1]*llvm.Value{operand};
......@@ -5568,7 +5574,8 @@ pub const FuncGen = struct {
55685574 }
55695575
55705576 fn sliceOrArrayPtr(fg: *FuncGen, ptr: *llvm.Value, ty: Type) *llvm.Value {
5571 const mod = fg.dg.module;
5577 const o = fg.dg.object;
5578 const mod = o.module;
55725579 if (ty.isSlice(mod)) {
55735580 return fg.builder.buildExtractValue(ptr, 0, "");
55745581 } else {
......@@ -5577,7 +5584,8 @@ pub const FuncGen = struct {
55775584 }
55785585
55795586 fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: *llvm.Value, ty: Type) *llvm.Value {
5580 const mod = fg.dg.module;
5587 const o = fg.dg.object;
5588 const mod = o.module;
55815589 const target = mod.getTarget();
55825590 const llvm_usize_ty = fg.context.intType(target.ptrBitWidth());
55835591 switch (ty.ptrSize(mod)) {
......@@ -5606,24 +5614,26 @@ pub const FuncGen = struct {
56065614 }
56075615
56085616 fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*llvm.Value {
5609 const mod = self.dg.module;
5617 const o = self.dg.object;
5618 const mod = o.module;
56105619 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
56115620 const slice_ptr = try self.resolveInst(ty_op.operand);
56125621 const slice_ptr_ty = self.typeOf(ty_op.operand);
5613 const slice_llvm_ty = try self.dg.lowerPtrElemTy(slice_ptr_ty.childType(mod));
5622 const slice_llvm_ty = try o.lowerPtrElemTy(slice_ptr_ty.childType(mod));
56145623
56155624 return self.builder.buildStructGEP(slice_llvm_ty, slice_ptr, index, "");
56165625 }
56175626
56185627 fn airSliceElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
5619 const mod = self.dg.module;
5628 const o = self.dg.object;
5629 const mod = o.module;
56205630 const inst = body_tail[0];
56215631 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
56225632 const slice_ty = self.typeOf(bin_op.lhs);
56235633 const slice = try self.resolveInst(bin_op.lhs);
56245634 const index = try self.resolveInst(bin_op.rhs);
56255635 const elem_ty = slice_ty.childType(mod);
5626 const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);
5636 const llvm_elem_ty = try o.lowerPtrElemTy(elem_ty);
56275637 const base_ptr = self.builder.buildExtractValue(slice, 0, "");
56285638 const indices: [1]*llvm.Value = .{index};
56295639 const ptr = self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
......@@ -5638,28 +5648,30 @@ pub const FuncGen = struct {
56385648 }
56395649
56405650 fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5641 const mod = self.dg.module;
5651 const o = self.dg.object;
5652 const mod = o.module;
56425653 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
56435654 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
56445655 const slice_ty = self.typeOf(bin_op.lhs);
56455656
56465657 const slice = try self.resolveInst(bin_op.lhs);
56475658 const index = try self.resolveInst(bin_op.rhs);
5648 const llvm_elem_ty = try self.dg.lowerPtrElemTy(slice_ty.childType(mod));
5659 const llvm_elem_ty = try o.lowerPtrElemTy(slice_ty.childType(mod));
56495660 const base_ptr = self.builder.buildExtractValue(slice, 0, "");
56505661 const indices: [1]*llvm.Value = .{index};
56515662 return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
56525663 }
56535664
56545665 fn airArrayElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
5655 const mod = self.dg.module;
5666 const o = self.dg.object;
5667 const mod = o.module;
56565668 const inst = body_tail[0];
56575669
56585670 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
56595671 const array_ty = self.typeOf(bin_op.lhs);
56605672 const array_llvm_val = try self.resolveInst(bin_op.lhs);
56615673 const rhs = try self.resolveInst(bin_op.rhs);
5662 const array_llvm_ty = try self.dg.lowerType(array_ty);
5674 const array_llvm_ty = try o.lowerType(array_ty);
56635675 const elem_ty = array_ty.childType(mod);
56645676 if (isByRef(array_ty, mod)) {
56655677 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
......@@ -5671,7 +5683,7 @@ pub const FuncGen = struct {
56715683 return self.loadByRef(elem_ptr, elem_ty, elem_ty.abiAlignment(mod), false);
56725684 } else {
56735685 const lhs_index = Air.refToIndex(bin_op.lhs).?;
5674 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
5686 const elem_llvm_ty = try o.lowerType(elem_ty);
56755687 if (self.air.instructions.items(.tag)[lhs_index] == .load) {
56765688 const load_data = self.air.instructions.items(.data)[lhs_index];
56775689 const load_ptr = load_data.ty_op.operand;
......@@ -5695,12 +5707,13 @@ pub const FuncGen = struct {
56955707 }
56965708
56975709 fn airPtrElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
5698 const mod = self.dg.module;
5710 const o = self.dg.object;
5711 const mod = o.module;
56995712 const inst = body_tail[0];
57005713 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
57015714 const ptr_ty = self.typeOf(bin_op.lhs);
57025715 const elem_ty = ptr_ty.childType(mod);
5703 const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);
5716 const llvm_elem_ty = try o.lowerPtrElemTy(elem_ty);
57045717 const base_ptr = try self.resolveInst(bin_op.lhs);
57055718 const rhs = try self.resolveInst(bin_op.rhs);
57065719 // TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch
......@@ -5723,12 +5736,13 @@ pub const FuncGen = struct {
57235736 }
57245737
57255738 fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5726 const mod = self.dg.module;
5739 const o = self.dg.object;
5740 const mod = o.module;
57275741 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
57285742 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
57295743 const ptr_ty = self.typeOf(bin_op.lhs);
57305744 const elem_ty = ptr_ty.childType(mod);
5731 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty);
5745 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return o.lowerPtrToVoid(ptr_ty);
57325746
57335747 const base_ptr = try self.resolveInst(bin_op.lhs);
57345748 const rhs = try self.resolveInst(bin_op.rhs);
......@@ -5736,7 +5750,7 @@ pub const FuncGen = struct {
57365750 const elem_ptr = self.air.getRefType(ty_pl.ty);
57375751 if (elem_ptr.ptrInfo(mod).flags.vector_index != .none) return base_ptr;
57385752
5739 const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);
5753 const llvm_elem_ty = try o.lowerPtrElemTy(elem_ty);
57405754 if (ptr_ty.isSinglePointer(mod)) {
57415755 // If this is a single-item pointer to an array, we need another index in the GEP.
57425756 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
......@@ -5767,7 +5781,8 @@ pub const FuncGen = struct {
57675781 }
57685782
57695783 fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
5770 const mod = self.dg.module;
5784 const o = self.dg.object;
5785 const mod = o.module;
57715786 const inst = body_tail[0];
57725787 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
57735788 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
......@@ -5789,7 +5804,7 @@ pub const FuncGen = struct {
57895804 const containing_int = struct_llvm_val;
57905805 const shift_amt = containing_int.typeOf().constInt(bit_offset, .False);
57915806 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");
5792 const elem_llvm_ty = try self.dg.lowerType(field_ty);
5807 const elem_llvm_ty = try o.lowerType(field_ty);
57935808 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
57945809 const elem_bits = @intCast(c_uint, field_ty.bitSize(mod));
57955810 const same_size_int = self.context.intType(elem_bits);
......@@ -5811,7 +5826,7 @@ pub const FuncGen = struct {
58115826 .Union => {
58125827 assert(struct_ty.containerLayout(mod) == .Packed);
58135828 const containing_int = struct_llvm_val;
5814 const elem_llvm_ty = try self.dg.lowerType(field_ty);
5829 const elem_llvm_ty = try o.lowerType(field_ty);
58155830 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
58165831 const elem_bits = @intCast(c_uint, field_ty.bitSize(mod));
58175832 const same_size_int = self.context.intType(elem_bits);
......@@ -5833,7 +5848,7 @@ pub const FuncGen = struct {
58335848 .Struct => {
58345849 assert(struct_ty.containerLayout(mod) != .Packed);
58355850 const llvm_field = llvmField(struct_ty, field_index, mod).?;
5836 const struct_llvm_ty = try self.dg.lowerType(struct_ty);
5851 const struct_llvm_ty = try o.lowerType(struct_ty);
58375852 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field.index, "");
58385853 const field_ptr_ty = try mod.ptrType(.{
58395854 .child = llvm_field.ty.toIntern(),
......@@ -5852,11 +5867,11 @@ pub const FuncGen = struct {
58525867 }
58535868 },
58545869 .Union => {
5855 const union_llvm_ty = try self.dg.lowerType(struct_ty);
5870 const union_llvm_ty = try o.lowerType(struct_ty);
58565871 const layout = struct_ty.unionGetLayout(mod);
58575872 const payload_index = @intFromBool(layout.tag_align >= layout.payload_align);
58585873 const field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, "");
5859 const llvm_field_ty = try self.dg.lowerType(field_ty);
5874 const llvm_field_ty = try o.lowerType(field_ty);
58605875 if (isByRef(field_ty, mod)) {
58615876 if (canElideLoad(self, body_tail))
58625877 return field_ptr;
......@@ -5871,17 +5886,18 @@ pub const FuncGen = struct {
58715886 }
58725887
58735888 fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5874 const mod = self.dg.module;
5889 const o = self.dg.object;
5890 const mod = o.module;
58755891 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
58765892 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
58775893
58785894 const field_ptr = try self.resolveInst(extra.field_ptr);
58795895
5880 const target = self.dg.module.getTarget();
5896 const target = o.module.getTarget();
58815897 const parent_ty = self.air.getRefType(ty_pl.ty).childType(mod);
58825898 const field_offset = parent_ty.structFieldOffset(extra.field_index, mod);
58835899
5884 const res_ty = try self.dg.lowerType(self.air.getRefType(ty_pl.ty));
5900 const res_ty = try o.lowerType(self.air.getRefType(ty_pl.ty));
58855901 if (field_offset == 0) {
58865902 return field_ptr;
58875903 }
......@@ -5919,14 +5935,15 @@ pub const FuncGen = struct {
59195935 }
59205936
59215937 fn airDbgInlineBegin(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5922 const dib = self.dg.object.di_builder orelse return null;
5938 const o = self.dg.object;
5939 const dib = o.di_builder orelse return null;
59235940 const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;
59245941
5925 const mod = self.dg.module;
5942 const mod = o.module;
59265943 const func = mod.funcPtr(ty_fn.func);
59275944 const decl_index = func.owner_decl;
59285945 const decl = mod.declPtr(decl_index);
5929 const di_file = try self.dg.object.getDIFile(self.gpa, mod.namespacePtr(decl.src_namespace).file_scope);
5946 const di_file = try o.getDIFile(self.gpa, mod.namespacePtr(decl.src_namespace).file_scope);
59305947 self.di_file = di_file;
59315948 const line_number = decl.src_line + 1;
59325949 const cur_debug_location = self.builder.getCurrentDebugLocation2();
......@@ -5955,7 +5972,7 @@ pub const FuncGen = struct {
59555972 .section_is_generic = false,
59565973 .addrspace_is_generic = false,
59575974 });
5958 const fn_di_ty = try self.dg.object.lowerDebugType(fn_ty, .full);
5975 const fn_di_ty = try o.lowerDebugType(fn_ty, .full);
59595976 const subprogram = dib.createFunction(
59605977 di_file.toScope(),
59615978 mod.intern_pool.stringToSlice(decl.name),
......@@ -5978,13 +5995,14 @@ pub const FuncGen = struct {
59785995 }
59795996
59805997 fn airDbgInlineEnd(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5981 if (self.dg.object.di_builder == null) return null;
5998 const o = self.dg.object;
5999 if (o.di_builder == null) return null;
59826000 const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;
59836001
5984 const mod = self.dg.module;
6002 const mod = o.module;
59856003 const func = mod.funcPtr(ty_fn.func);
59866004 const decl = mod.declPtr(func.owner_decl);
5987 const di_file = try self.dg.object.getDIFile(self.gpa, mod.namespacePtr(decl.src_namespace).file_scope);
6005 const di_file = try o.getDIFile(self.gpa, mod.namespacePtr(decl.src_namespace).file_scope);
59886006 self.di_file = di_file;
59896007 const old = self.dbg_inlined.pop();
59906008 self.di_scope = old.scope;
......@@ -5993,7 +6011,8 @@ pub const FuncGen = struct {
59936011 }
59946012
59956013 fn airDbgBlockBegin(self: *FuncGen) !?*llvm.Value {
5996 const dib = self.dg.object.di_builder orelse return null;
6014 const o = self.dg.object;
6015 const dib = o.di_builder orelse return null;
59976016 const old_scope = self.di_scope.?;
59986017 try self.dbg_block_stack.append(self.gpa, old_scope);
59996018 const lexical_block = dib.createLexicalBlock(old_scope, self.di_file.?, self.prev_dbg_line, self.prev_dbg_column);
......@@ -6002,14 +6021,16 @@ pub const FuncGen = struct {
60026021 }
60036022
60046023 fn airDbgBlockEnd(self: *FuncGen) !?*llvm.Value {
6005 if (self.dg.object.di_builder == null) return null;
6024 const o = self.dg.object;
6025 if (o.di_builder == null) return null;
60066026 self.di_scope = self.dbg_block_stack.pop();
60076027 return null;
60086028 }
60096029
60106030 fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6011 const mod = self.dg.module;
6012 const dib = self.dg.object.di_builder orelse return null;
6031 const o = self.dg.object;
6032 const mod = o.module;
6033 const dib = o.di_builder orelse return null;
60136034 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
60146035 const operand = try self.resolveInst(pl_op.operand);
60156036 const name = self.air.nullTerminatedString(pl_op.payload);
......@@ -6020,7 +6041,7 @@ pub const FuncGen = struct {
60206041 name.ptr,
60216042 self.di_file.?,
60226043 self.prev_dbg_line,
6023 try self.dg.object.lowerDebugType(ptr_ty.childType(mod), .full),
6044 try o.lowerDebugType(ptr_ty.childType(mod), .full),
60246045 true, // always preserve
60256046 0, // flags
60266047 );
......@@ -6035,13 +6056,14 @@ pub const FuncGen = struct {
60356056 }
60366057
60376058 fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6038 const dib = self.dg.object.di_builder orelse return null;
6059 const o = self.dg.object;
6060 const dib = o.di_builder orelse return null;
60396061 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
60406062 const operand = try self.resolveInst(pl_op.operand);
60416063 const operand_ty = self.typeOf(pl_op.operand);
60426064 const name = self.air.nullTerminatedString(pl_op.payload);
60436065
6044 if (needDbgVarWorkaround(self.dg)) {
6066 if (needDbgVarWorkaround(o)) {
60456067 return null;
60466068 }
60476069
......@@ -6050,7 +6072,7 @@ pub const FuncGen = struct {
60506072 name.ptr,
60516073 self.di_file.?,
60526074 self.prev_dbg_line,
6053 try self.dg.object.lowerDebugType(operand_ty, .full),
6075 try o.lowerDebugType(operand_ty, .full),
60546076 true, // always preserve
60556077 0, // flags
60566078 );
......@@ -6060,10 +6082,10 @@ pub const FuncGen = struct {
60606082 null;
60616083 const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at);
60626084 const insert_block = self.builder.getInsertBlock();
6063 const mod = self.dg.module;
6085 const mod = o.module;
60646086 if (isByRef(operand_ty, mod)) {
60656087 _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block);
6066 } else if (self.dg.module.comp.bin_file.options.optimize_mode == .Debug) {
6088 } else if (o.module.comp.bin_file.options.optimize_mode == .Debug) {
60676089 const alignment = operand_ty.abiAlignment(mod);
60686090 const alloca = self.buildAlloca(operand.typeOf(), alignment);
60696091 const store_inst = self.builder.buildStore(operand, alloca);
......@@ -6082,6 +6104,7 @@ pub const FuncGen = struct {
60826104 // We don't have such an assembler implemented yet though. For now,
60836105 // this implementation feeds the inline assembly code directly to LLVM.
60846106
6107 const o = self.dg.object;
60856108 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
60866109 const extra = self.air.extraData(Air.Asm, ty_pl.payload);
60876110 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;
......@@ -6112,7 +6135,7 @@ pub const FuncGen = struct {
61126135 // This stores whether we need to add an elementtype attribute and
61136136 // if so, the element type itself.
61146137 const llvm_param_attrs = try arena.alloc(?*llvm.Type, max_param_count);
6115 const mod = self.dg.module;
6138 const mod = o.module;
61166139 const target = mod.getTarget();
61176140
61186141 var llvm_ret_i: usize = 0;
......@@ -6142,7 +6165,7 @@ pub const FuncGen = struct {
61426165 const output_inst = try self.resolveInst(output);
61436166 const output_ty = self.typeOf(output);
61446167 assert(output_ty.zigTypeTag(mod) == .Pointer);
6145 const elem_llvm_ty = try self.dg.lowerPtrElemTy(output_ty.childType(mod));
6168 const elem_llvm_ty = try o.lowerPtrElemTy(output_ty.childType(mod));
61466169
61476170 if (llvm_ret_indirect[i]) {
61486171 // Pass the result by reference as an indirect output (e.g. "=*m")
......@@ -6159,7 +6182,7 @@ pub const FuncGen = struct {
61596182 }
61606183 } else {
61616184 const ret_ty = self.typeOfIndex(inst);
6162 llvm_ret_types[llvm_ret_i] = try self.dg.lowerType(ret_ty);
6185 llvm_ret_types[llvm_ret_i] = try o.lowerType(ret_ty);
61636186 llvm_ret_i += 1;
61646187 }
61656188
......@@ -6196,13 +6219,13 @@ pub const FuncGen = struct {
61966219 const arg_ty = self.typeOf(input);
61976220 var llvm_elem_ty: ?*llvm.Type = null;
61986221 if (isByRef(arg_ty, mod)) {
6199 llvm_elem_ty = try self.dg.lowerPtrElemTy(arg_ty);
6222 llvm_elem_ty = try o.lowerPtrElemTy(arg_ty);
62006223 if (constraintAllowsMemory(constraint)) {
62016224 llvm_param_values[llvm_param_i] = arg_llvm_value;
62026225 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
62036226 } else {
62046227 const alignment = arg_ty.abiAlignment(mod);
6205 const arg_llvm_ty = try self.dg.lowerType(arg_ty);
6228 const arg_llvm_ty = try o.lowerType(arg_ty);
62066229 const load_inst = self.builder.buildLoad(arg_llvm_ty, arg_llvm_value, "");
62076230 load_inst.setAlignment(alignment);
62086231 llvm_param_values[llvm_param_i] = load_inst;
......@@ -6243,7 +6266,7 @@ pub const FuncGen = struct {
62436266 // an elementtype(<ty>) attribute.
62446267 if (constraint[0] == '*') {
62456268 llvm_param_attrs[llvm_param_i] = llvm_elem_ty orelse
6246 try self.dg.lowerPtrElemTy(arg_ty.childType(mod));
6269 try o.lowerPtrElemTy(arg_ty.childType(mod));
62476270 } else {
62486271 llvm_param_attrs[llvm_param_i] = null;
62496272 }
......@@ -6434,12 +6457,13 @@ pub const FuncGen = struct {
64346457 operand_is_ptr: bool,
64356458 pred: llvm.IntPredicate,
64366459 ) !?*llvm.Value {
6437 const mod = self.dg.module;
6460 const o = self.dg.object;
6461 const mod = o.module;
64386462 const un_op = self.air.instructions.items(.data)[inst].un_op;
64396463 const operand = try self.resolveInst(un_op);
64406464 const operand_ty = self.typeOf(un_op);
64416465 const optional_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
6442 const optional_llvm_ty = try self.dg.lowerType(optional_ty);
6466 const optional_llvm_ty = try o.lowerType(optional_ty);
64436467 const payload_ty = optional_ty.optionalChild(mod);
64446468 if (optional_ty.optionalReprIsPayload(mod)) {
64456469 const loaded = if (operand_is_ptr)
......@@ -6448,7 +6472,7 @@ pub const FuncGen = struct {
64486472 operand;
64496473 if (payload_ty.isSlice(mod)) {
64506474 const slice_ptr = self.builder.buildExtractValue(loaded, 0, "");
6451 const ptr_ty = try self.dg.lowerType(payload_ty.slicePtrFieldType(mod));
6475 const ptr_ty = try o.lowerType(payload_ty.slicePtrFieldType(mod));
64526476 return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), "");
64536477 }
64546478 return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), "");
......@@ -6480,13 +6504,14 @@ pub const FuncGen = struct {
64806504 op: llvm.IntPredicate,
64816505 operand_is_ptr: bool,
64826506 ) !?*llvm.Value {
6483 const mod = self.dg.module;
6507 const o = self.dg.object;
6508 const mod = o.module;
64846509 const un_op = self.air.instructions.items(.data)[inst].un_op;
64856510 const operand = try self.resolveInst(un_op);
64866511 const operand_ty = self.typeOf(un_op);
64876512 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
64886513 const payload_ty = err_union_ty.errorUnionPayload(mod);
6489 const err_set_ty = try self.dg.lowerType(Type.anyerror);
6514 const err_set_ty = try o.lowerType(Type.anyerror);
64906515 const zero = err_set_ty.constNull();
64916516
64926517 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
......@@ -6500,7 +6525,7 @@ pub const FuncGen = struct {
65006525
65016526 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
65026527 const loaded = if (operand_is_ptr)
6503 self.builder.buildLoad(try self.dg.lowerType(err_union_ty), operand, "")
6528 self.builder.buildLoad(try o.lowerType(err_union_ty), operand, "")
65046529 else
65056530 operand;
65066531 return self.builder.buildICmp(op, loaded, zero, "");
......@@ -6509,7 +6534,7 @@ pub const FuncGen = struct {
65096534 const err_field_index = errUnionErrorOffset(payload_ty, mod);
65106535
65116536 if (operand_is_ptr or isByRef(err_union_ty, mod)) {
6512 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
6537 const err_union_llvm_ty = try o.lowerType(err_union_ty);
65136538 const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, err_field_index, "");
65146539 const loaded = self.builder.buildLoad(err_set_ty, err_field_ptr, "");
65156540 return self.builder.buildICmp(op, loaded, zero, "");
......@@ -6520,7 +6545,8 @@ pub const FuncGen = struct {
65206545 }
65216546
65226547 fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6523 const mod = self.dg.module;
6548 const o = self.dg.object;
6549 const mod = o.module;
65246550 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
65256551 const operand = try self.resolveInst(ty_op.operand);
65266552 const optional_ty = self.typeOf(ty_op.operand).childType(mod);
......@@ -6534,14 +6560,15 @@ pub const FuncGen = struct {
65346560 // The payload and the optional are the same value.
65356561 return operand;
65366562 }
6537 const optional_llvm_ty = try self.dg.lowerType(optional_ty);
6563 const optional_llvm_ty = try o.lowerType(optional_ty);
65386564 return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, "");
65396565 }
65406566
65416567 fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
65426568 comptime assert(optional_layout_version == 3);
65436569
6544 const mod = self.dg.module;
6570 const o = self.dg.object;
6571 const mod = o.module;
65456572 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
65466573 const operand = try self.resolveInst(ty_op.operand);
65476574 const optional_ty = self.typeOf(ty_op.operand).childType(mod);
......@@ -6559,7 +6586,7 @@ pub const FuncGen = struct {
65596586 }
65606587
65616588 // First set the non-null bit.
6562 const optional_llvm_ty = try self.dg.lowerType(optional_ty);
6589 const optional_llvm_ty = try o.lowerType(optional_ty);
65636590 const non_null_ptr = self.builder.buildStructGEP(optional_llvm_ty, operand, 1, "");
65646591 // TODO set alignment on this store
65656592 _ = self.builder.buildStore(non_null_bit, non_null_ptr);
......@@ -6572,7 +6599,8 @@ pub const FuncGen = struct {
65726599 }
65736600
65746601 fn airOptionalPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
6575 const mod = self.dg.module;
6602 const o = self.dg.object;
6603 const mod = o.module;
65766604 const inst = body_tail[0];
65776605 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
65786606 const operand = try self.resolveInst(ty_op.operand);
......@@ -6585,7 +6613,7 @@ pub const FuncGen = struct {
65856613 return operand;
65866614 }
65876615
6588 const opt_llvm_ty = try self.dg.lowerType(optional_ty);
6616 const opt_llvm_ty = try o.lowerType(optional_ty);
65896617 const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false;
65906618 return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load);
65916619 }
......@@ -6595,7 +6623,8 @@ pub const FuncGen = struct {
65956623 body_tail: []const Air.Inst.Index,
65966624 operand_is_ptr: bool,
65976625 ) !?*llvm.Value {
6598 const mod = self.dg.module;
6626 const o = self.dg.object;
6627 const mod = o.module;
65996628 const inst = body_tail[0];
66006629 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
66016630 const operand = try self.resolveInst(ty_op.operand);
......@@ -6608,7 +6637,7 @@ pub const FuncGen = struct {
66086637 return if (operand_is_ptr) operand else null;
66096638 }
66106639 const offset = errUnionPayloadOffset(payload_ty, mod);
6611 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
6640 const err_union_llvm_ty = try o.lowerType(err_union_ty);
66126641 if (operand_is_ptr) {
66136642 return self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");
66146643 } else if (isByRef(err_union_ty, mod)) {
......@@ -6631,13 +6660,14 @@ pub const FuncGen = struct {
66316660 inst: Air.Inst.Index,
66326661 operand_is_ptr: bool,
66336662 ) !?*llvm.Value {
6634 const mod = self.dg.module;
6663 const o = self.dg.object;
6664 const mod = o.module;
66356665 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
66366666 const operand = try self.resolveInst(ty_op.operand);
66376667 const operand_ty = self.typeOf(ty_op.operand);
66386668 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
66396669 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
6640 const err_llvm_ty = try self.dg.lowerType(Type.anyerror);
6670 const err_llvm_ty = try o.lowerType(Type.anyerror);
66416671 if (operand_is_ptr) {
66426672 return operand;
66436673 } else {
......@@ -6645,7 +6675,7 @@ pub const FuncGen = struct {
66456675 }
66466676 }
66476677
6648 const err_set_llvm_ty = try self.dg.lowerType(Type.anyerror);
6678 const err_set_llvm_ty = try o.lowerType(Type.anyerror);
66496679
66506680 const payload_ty = err_union_ty.errorUnionPayload(mod);
66516681 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
......@@ -6656,7 +6686,7 @@ pub const FuncGen = struct {
66566686 const offset = errUnionErrorOffset(payload_ty, mod);
66576687
66586688 if (operand_is_ptr or isByRef(err_union_ty, mod)) {
6659 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
6689 const err_union_llvm_ty = try o.lowerType(err_union_ty);
66606690 const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");
66616691 return self.builder.buildLoad(err_set_llvm_ty, err_field_ptr, "");
66626692 }
......@@ -6665,18 +6695,19 @@ pub const FuncGen = struct {
66656695 }
66666696
66676697 fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6668 const mod = self.dg.module;
6698 const o = self.dg.object;
6699 const mod = o.module;
66696700 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
66706701 const operand = try self.resolveInst(ty_op.operand);
66716702 const err_union_ty = self.typeOf(ty_op.operand).childType(mod);
66726703
66736704 const payload_ty = err_union_ty.errorUnionPayload(mod);
6674 const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = try mod.intValue(Type.err_int, 0) });
6705 const non_error_val = try o.lowerValue(.{ .ty = Type.anyerror, .val = try mod.intValue(Type.err_int, 0) });
66756706 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
66766707 _ = self.builder.buildStore(non_error_val, operand);
66776708 return operand;
66786709 }
6679 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
6710 const err_union_llvm_ty = try o.lowerType(err_union_ty);
66806711 {
66816712 const error_offset = errUnionErrorOffset(payload_ty, mod);
66826713 // First set the non-error value.
......@@ -6704,14 +6735,15 @@ pub const FuncGen = struct {
67046735 }
67056736
67066737 fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6738 const o = self.dg.object;
67076739 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
67086740 //const struct_ty = try self.resolveInst(ty_pl.ty);
67096741 const struct_ty = self.air.getRefType(ty_pl.ty);
67106742 const field_index = ty_pl.payload;
67116743
6712 const mod = self.dg.module;
6744 const mod = o.module;
67136745 const llvm_field = llvmField(struct_ty, field_index, mod).?;
6714 const struct_llvm_ty = try self.dg.lowerType(struct_ty);
6746 const struct_llvm_ty = try o.lowerType(struct_ty);
67156747 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field.index, "");
67166748 const field_ptr_ty = try mod.ptrType(.{
67176749 .child = llvm_field.ty.toIntern(),
......@@ -6723,7 +6755,8 @@ pub const FuncGen = struct {
67236755 }
67246756
67256757 fn airWrapOptional(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6726 const mod = self.dg.module;
6758 const o = self.dg.object;
6759 const mod = o.module;
67276760 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
67286761 const payload_ty = self.typeOf(ty_op.operand);
67296762 const non_null_bit = self.context.intType(8).constInt(1, .False);
......@@ -6734,7 +6767,7 @@ pub const FuncGen = struct {
67346767 if (optional_ty.optionalReprIsPayload(mod)) {
67356768 return operand;
67366769 }
6737 const llvm_optional_ty = try self.dg.lowerType(optional_ty);
6770 const llvm_optional_ty = try o.lowerType(optional_ty);
67386771 if (isByRef(optional_ty, mod)) {
67396772 const optional_ptr = self.buildAlloca(llvm_optional_ty, optional_ty.abiAlignment(mod));
67406773 const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, "");
......@@ -6749,7 +6782,8 @@ pub const FuncGen = struct {
67496782 }
67506783
67516784 fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6752 const mod = self.dg.module;
6785 const o = self.dg.object;
6786 const mod = o.module;
67536787 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
67546788 const err_un_ty = self.typeOfIndex(inst);
67556789 const operand = try self.resolveInst(ty_op.operand);
......@@ -6757,8 +6791,8 @@ pub const FuncGen = struct {
67576791 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
67586792 return operand;
67596793 }
6760 const ok_err_code = (try self.dg.lowerType(Type.anyerror)).constNull();
6761 const err_un_llvm_ty = try self.dg.lowerType(err_un_ty);
6794 const ok_err_code = (try o.lowerType(Type.anyerror)).constNull();
6795 const err_un_llvm_ty = try o.lowerType(err_un_ty);
67626796
67636797 const payload_offset = errUnionPayloadOffset(payload_ty, mod);
67646798 const error_offset = errUnionErrorOffset(payload_ty, mod);
......@@ -6778,7 +6812,8 @@ pub const FuncGen = struct {
67786812 }
67796813
67806814 fn airWrapErrUnionErr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6781 const mod = self.dg.module;
6815 const o = self.dg.object;
6816 const mod = o.module;
67826817 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
67836818 const err_un_ty = self.typeOfIndex(inst);
67846819 const payload_ty = err_un_ty.errorUnionPayload(mod);
......@@ -6786,7 +6821,7 @@ pub const FuncGen = struct {
67866821 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
67876822 return operand;
67886823 }
6789 const err_un_llvm_ty = try self.dg.lowerType(err_un_ty);
6824 const err_un_llvm_ty = try o.lowerType(err_un_ty);
67906825
67916826 const payload_offset = errUnionPayloadOffset(payload_ty, mod);
67926827 const error_offset = errUnionErrorOffset(payload_ty, mod);
......@@ -6831,7 +6866,8 @@ pub const FuncGen = struct {
68316866 }
68326867
68336868 fn airVectorStoreElem(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6834 const mod = self.dg.module;
6869 const o = self.dg.object;
6870 const mod = o.module;
68356871 const data = self.air.instructions.items(.data)[inst].vector_store_elem;
68366872 const extra = self.air.extraData(Air.Bin, data.payload).data;
68376873
......@@ -6841,7 +6877,7 @@ pub const FuncGen = struct {
68416877 const operand = try self.resolveInst(extra.rhs);
68426878
68436879 const loaded_vector = blk: {
6844 const elem_llvm_ty = try self.dg.lowerType(vector_ptr_ty.childType(mod));
6880 const elem_llvm_ty = try o.lowerType(vector_ptr_ty.childType(mod));
68456881 const load_inst = self.builder.buildLoad(elem_llvm_ty, vector_ptr, "");
68466882 load_inst.setAlignment(vector_ptr_ty.ptrAlignment(mod));
68476883 load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr(mod)));
......@@ -6853,7 +6889,8 @@ pub const FuncGen = struct {
68536889 }
68546890
68556891 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6856 const mod = self.dg.module;
6892 const o = self.dg.object;
6893 const mod = o.module;
68576894 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
68586895 const lhs = try self.resolveInst(bin_op.lhs);
68596896 const rhs = try self.resolveInst(bin_op.rhs);
......@@ -6865,7 +6902,8 @@ pub const FuncGen = struct {
68656902 }
68666903
68676904 fn airMax(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6868 const mod = self.dg.module;
6905 const o = self.dg.object;
6906 const mod = o.module;
68696907 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
68706908 const lhs = try self.resolveInst(bin_op.lhs);
68716909 const rhs = try self.resolveInst(bin_op.rhs);
......@@ -6877,12 +6915,13 @@ pub const FuncGen = struct {
68776915 }
68786916
68796917 fn airSlice(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6918 const o = self.dg.object;
68806919 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
68816920 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
68826921 const ptr = try self.resolveInst(bin_op.lhs);
68836922 const len = try self.resolveInst(bin_op.rhs);
68846923 const inst_ty = self.typeOfIndex(inst);
6885 const llvm_slice_ty = try self.dg.lowerType(inst_ty);
6924 const llvm_slice_ty = try o.lowerType(inst_ty);
68866925
68876926 // In case of slicing a global, the result type looks something like `{ i8*, i64 }`
68886927 // but `ptr` is pointing to the global directly.
......@@ -6893,7 +6932,8 @@ pub const FuncGen = struct {
68936932 fn airAdd(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
68946933 self.builder.setFastMath(want_fast_math);
68956934
6896 const mod = self.dg.module;
6935 const o = self.dg.object;
6936 const mod = o.module;
68976937 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
68986938 const lhs = try self.resolveInst(bin_op.lhs);
68996939 const rhs = try self.resolveInst(bin_op.rhs);
......@@ -6916,7 +6956,8 @@ pub const FuncGen = struct {
69166956 }
69176957
69186958 fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6919 const mod = self.dg.module;
6959 const o = self.dg.object;
6960 const mod = o.module;
69206961 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
69216962 const lhs = try self.resolveInst(bin_op.lhs);
69226963 const rhs = try self.resolveInst(bin_op.rhs);
......@@ -6932,7 +6973,8 @@ pub const FuncGen = struct {
69326973 fn airSub(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
69336974 self.builder.setFastMath(want_fast_math);
69346975
6935 const mod = self.dg.module;
6976 const o = self.dg.object;
6977 const mod = o.module;
69366978 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
69376979 const lhs = try self.resolveInst(bin_op.lhs);
69386980 const rhs = try self.resolveInst(bin_op.rhs);
......@@ -6955,7 +6997,8 @@ pub const FuncGen = struct {
69556997 }
69566998
69576999 fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6958 const mod = self.dg.module;
7000 const o = self.dg.object;
7001 const mod = o.module;
69597002 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
69607003 const lhs = try self.resolveInst(bin_op.lhs);
69617004 const rhs = try self.resolveInst(bin_op.rhs);
......@@ -6970,7 +7013,8 @@ pub const FuncGen = struct {
69707013 fn airMul(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
69717014 self.builder.setFastMath(want_fast_math);
69727015
6973 const mod = self.dg.module;
7016 const o = self.dg.object;
7017 const mod = o.module;
69747018 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
69757019 const lhs = try self.resolveInst(bin_op.lhs);
69767020 const rhs = try self.resolveInst(bin_op.rhs);
......@@ -6993,7 +7037,8 @@ pub const FuncGen = struct {
69937037 }
69947038
69957039 fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6996 const mod = self.dg.module;
7040 const o = self.dg.object;
7041 const mod = o.module;
69977042 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
69987043 const lhs = try self.resolveInst(bin_op.lhs);
69997044 const rhs = try self.resolveInst(bin_op.rhs);
......@@ -7019,7 +7064,8 @@ pub const FuncGen = struct {
70197064 fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
70207065 self.builder.setFastMath(want_fast_math);
70217066
7022 const mod = self.dg.module;
7067 const o = self.dg.object;
7068 const mod = o.module;
70237069 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
70247070 const lhs = try self.resolveInst(bin_op.lhs);
70257071 const rhs = try self.resolveInst(bin_op.rhs);
......@@ -7037,7 +7083,8 @@ pub const FuncGen = struct {
70377083 fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
70387084 self.builder.setFastMath(want_fast_math);
70397085
7040 const mod = self.dg.module;
7086 const o = self.dg.object;
7087 const mod = o.module;
70417088 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
70427089 const lhs = try self.resolveInst(bin_op.lhs);
70437090 const rhs = try self.resolveInst(bin_op.rhs);
......@@ -7049,11 +7096,11 @@ pub const FuncGen = struct {
70497096 return self.buildFloatOp(.floor, inst_ty, 1, .{result});
70507097 }
70517098 if (scalar_ty.isSignedInt(mod)) {
7052 const inst_llvm_ty = try self.dg.lowerType(inst_ty);
7099 const inst_llvm_ty = try o.lowerType(inst_ty);
70537100 const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1;
70547101 const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: {
70557102 const vec_len = inst_ty.vectorLen(mod);
7056 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
7103 const scalar_llvm_ty = try o.lowerType(scalar_ty);
70577104
70587105 const shifts = try self.gpa.alloc(*llvm.Value, vec_len);
70597106 defer self.gpa.free(shifts);
......@@ -7077,7 +7124,8 @@ pub const FuncGen = struct {
70777124 fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
70787125 self.builder.setFastMath(want_fast_math);
70797126
7080 const mod = self.dg.module;
7127 const o = self.dg.object;
7128 const mod = o.module;
70817129 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
70827130 const lhs = try self.resolveInst(bin_op.lhs);
70837131 const rhs = try self.resolveInst(bin_op.rhs);
......@@ -7092,7 +7140,8 @@ pub const FuncGen = struct {
70927140 fn airRem(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
70937141 self.builder.setFastMath(want_fast_math);
70947142
7095 const mod = self.dg.module;
7143 const o = self.dg.object;
7144 const mod = o.module;
70967145 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
70977146 const lhs = try self.resolveInst(bin_op.lhs);
70987147 const rhs = try self.resolveInst(bin_op.rhs);
......@@ -7107,12 +7156,13 @@ pub const FuncGen = struct {
71077156 fn airMod(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
71087157 self.builder.setFastMath(want_fast_math);
71097158
7110 const mod = self.dg.module;
7159 const o = self.dg.object;
7160 const mod = o.module;
71117161 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
71127162 const lhs = try self.resolveInst(bin_op.lhs);
71137163 const rhs = try self.resolveInst(bin_op.rhs);
71147164 const inst_ty = self.typeOfIndex(inst);
7115 const inst_llvm_ty = try self.dg.lowerType(inst_ty);
7165 const inst_llvm_ty = try o.lowerType(inst_ty);
71167166 const scalar_ty = inst_ty.scalarType(mod);
71177167
71187168 if (scalar_ty.isRuntimeFloat()) {
......@@ -7127,7 +7177,7 @@ pub const FuncGen = struct {
71277177 const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1;
71287178 const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: {
71297179 const vec_len = inst_ty.vectorLen(mod);
7130 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
7180 const scalar_llvm_ty = try o.lowerType(scalar_ty);
71317181
71327182 const shifts = try self.gpa.alloc(*llvm.Value, vec_len);
71337183 defer self.gpa.free(shifts);
......@@ -7149,13 +7199,14 @@ pub const FuncGen = struct {
71497199 }
71507200
71517201 fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7152 const mod = self.dg.module;
7202 const o = self.dg.object;
7203 const mod = o.module;
71537204 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
71547205 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
71557206 const ptr = try self.resolveInst(bin_op.lhs);
71567207 const offset = try self.resolveInst(bin_op.rhs);
71577208 const ptr_ty = self.typeOf(bin_op.lhs);
7158 const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType(mod));
7209 const llvm_elem_ty = try o.lowerPtrElemTy(ptr_ty.childType(mod));
71597210 switch (ptr_ty.ptrSize(mod)) {
71607211 .One => {
71617212 // It's a pointer to an array, so according to LLVM we need an extra GEP index.
......@@ -7175,14 +7226,15 @@ pub const FuncGen = struct {
71757226 }
71767227
71777228 fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7178 const mod = self.dg.module;
7229 const o = self.dg.object;
7230 const mod = o.module;
71797231 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
71807232 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
71817233 const ptr = try self.resolveInst(bin_op.lhs);
71827234 const offset = try self.resolveInst(bin_op.rhs);
71837235 const negative_offset = self.builder.buildNeg(offset, "");
71847236 const ptr_ty = self.typeOf(bin_op.lhs);
7185 const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType(mod));
7237 const llvm_elem_ty = try o.lowerPtrElemTy(ptr_ty.childType(mod));
71867238 switch (ptr_ty.ptrSize(mod)) {
71877239 .One => {
71887240 // It's a pointer to an array, so according to LLVM we need an extra GEP index.
......@@ -7209,7 +7261,8 @@ pub const FuncGen = struct {
72097261 signed_intrinsic: []const u8,
72107262 unsigned_intrinsic: []const u8,
72117263 ) !?*llvm.Value {
7212 const mod = self.dg.module;
7264 const o = self.dg.object;
7265 const mod = o.module;
72137266 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
72147267 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
72157268
......@@ -7222,8 +7275,8 @@ pub const FuncGen = struct {
72227275
72237276 const intrinsic_name = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic;
72247277
7225 const llvm_lhs_ty = try self.dg.lowerType(lhs_ty);
7226 const llvm_dest_ty = try self.dg.lowerType(dest_ty);
7278 const llvm_lhs_ty = try o.lowerType(lhs_ty);
7279 const llvm_dest_ty = try o.lowerType(dest_ty);
72277280
72287281 const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty});
72297282 const result_struct = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &[_]*llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, "");
......@@ -7287,13 +7340,14 @@ pub const FuncGen = struct {
72877340 param_types: []const *llvm.Type,
72887341 return_type: *llvm.Type,
72897342 ) *llvm.Value {
7290 return self.dg.object.llvm_module.getNamedFunction(fn_name.ptr) orelse b: {
7291 const alias = self.dg.object.llvm_module.getNamedGlobalAlias(fn_name.ptr, fn_name.len);
7343 const o = self.dg.object;
7344 return o.llvm_module.getNamedFunction(fn_name.ptr) orelse b: {
7345 const alias = o.llvm_module.getNamedGlobalAlias(fn_name.ptr, fn_name.len);
72927346 break :b if (alias) |a| a.getAliasee() else null;
72937347 } orelse b: {
72947348 const params_len = @intCast(c_uint, param_types.len);
72957349 const fn_type = llvm.functionType(return_type, param_types.ptr, params_len, .False);
7296 const f = self.dg.object.llvm_module.addFunction(fn_name, fn_type);
7350 const f = o.llvm_module.addFunction(fn_name, fn_type);
72977351 break :b f;
72987352 };
72997353 }
......@@ -7306,10 +7360,11 @@ pub const FuncGen = struct {
73067360 ty: Type,
73077361 params: [2]*llvm.Value,
73087362 ) !*llvm.Value {
7309 const mod = self.dg.module;
7310 const target = self.dg.module.getTarget();
7363 const o = self.dg.object;
7364 const mod = o.module;
7365 const target = o.module.getTarget();
73117366 const scalar_ty = ty.scalarType(mod);
7312 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
7367 const scalar_llvm_ty = try o.lowerType(scalar_ty);
73137368
73147369 if (intrinsicsAllowed(scalar_ty, target)) {
73157370 const llvm_predicate: llvm.RealPredicate = switch (pred) {
......@@ -7408,11 +7463,12 @@ pub const FuncGen = struct {
74087463 comptime params_len: usize,
74097464 params: [params_len]*llvm.Value,
74107465 ) !*llvm.Value {
7411 const mod = self.dg.module;
7466 const o = self.dg.object;
7467 const mod = o.module;
74127468 const target = mod.getTarget();
74137469 const scalar_ty = ty.scalarType(mod);
7414 const llvm_ty = try self.dg.lowerType(ty);
7415 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
7470 const llvm_ty = try o.lowerType(ty);
7471 const scalar_llvm_ty = try o.lowerType(scalar_ty);
74167472
74177473 const intrinsics_allowed = op != .tan and intrinsicsAllowed(scalar_ty, target);
74187474 var fn_name_buf: [64]u8 = undefined;
......@@ -7508,7 +7564,8 @@ pub const FuncGen = struct {
75087564 }
75097565
75107566 fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7511 const mod = self.dg.module;
7567 const o = self.dg.object;
7568 const mod = o.module;
75127569 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
75137570 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
75147571
......@@ -7521,10 +7578,10 @@ pub const FuncGen = struct {
75217578 const rhs_scalar_ty = rhs_ty.scalarType(mod);
75227579
75237580 const dest_ty = self.typeOfIndex(inst);
7524 const llvm_dest_ty = try self.dg.lowerType(dest_ty);
7581 const llvm_dest_ty = try o.lowerType(dest_ty);
75257582
75267583 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))
7527 self.builder.buildZExt(rhs, try self.dg.lowerType(lhs_ty), "")
7584 self.builder.buildZExt(rhs, try o.lowerType(lhs_ty), "")
75287585 else
75297586 rhs;
75307587
......@@ -7582,7 +7639,8 @@ pub const FuncGen = struct {
75827639 }
75837640
75847641 fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7585 const mod = self.dg.module;
7642 const o = self.dg.object;
7643 const mod = o.module;
75867644 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
75877645
75887646 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7594,7 +7652,7 @@ pub const FuncGen = struct {
75947652 const rhs_scalar_ty = rhs_ty.scalarType(mod);
75957653
75967654 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))
7597 self.builder.buildZExt(rhs, try self.dg.lowerType(lhs_ty), "")
7655 self.builder.buildZExt(rhs, try o.lowerType(lhs_ty), "")
75987656 else
75997657 rhs;
76007658 if (lhs_scalar_ty.isSignedInt(mod)) return self.builder.buildNSWShl(lhs, casted_rhs, "");
......@@ -7602,7 +7660,8 @@ pub const FuncGen = struct {
76027660 }
76037661
76047662 fn airShl(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7605 const mod = self.dg.module;
7663 const o = self.dg.object;
7664 const mod = o.module;
76067665 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
76077666
76087667 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7614,14 +7673,15 @@ pub const FuncGen = struct {
76147673 const rhs_scalar_ty = rhs_type.scalarType(mod);
76157674
76167675 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))
7617 self.builder.buildZExt(rhs, try self.dg.lowerType(lhs_type), "")
7676 self.builder.buildZExt(rhs, try o.lowerType(lhs_type), "")
76187677 else
76197678 rhs;
76207679 return self.builder.buildShl(lhs, casted_rhs, "");
76217680 }
76227681
76237682 fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7624 const mod = self.dg.module;
7683 const o = self.dg.object;
7684 const mod = o.module;
76257685 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
76267686
76277687 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7648,7 +7708,7 @@ pub const FuncGen = struct {
76487708 // poison value."
76497709 // However Zig semantics says that saturating shift left can never produce
76507710 // undefined; instead it saturates.
7651 const lhs_scalar_llvm_ty = try self.dg.lowerType(lhs_scalar_ty);
7711 const lhs_scalar_llvm_ty = try o.lowerType(lhs_scalar_ty);
76527712 const bits = lhs_scalar_llvm_ty.constInt(lhs_bits, .False);
76537713 const lhs_max = lhs_scalar_llvm_ty.constAllOnes();
76547714 if (rhs_ty.zigTypeTag(mod) == .Vector) {
......@@ -7664,7 +7724,8 @@ pub const FuncGen = struct {
76647724 }
76657725
76667726 fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !?*llvm.Value {
7667 const mod = self.dg.module;
7727 const o = self.dg.object;
7728 const mod = o.module;
76687729 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
76697730
76707731 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7676,7 +7737,7 @@ pub const FuncGen = struct {
76767737 const rhs_scalar_ty = rhs_ty.scalarType(mod);
76777738
76787739 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))
7679 self.builder.buildZExt(rhs, try self.dg.lowerType(lhs_ty), "")
7740 self.builder.buildZExt(rhs, try o.lowerType(lhs_ty), "")
76807741 else
76817742 rhs;
76827743 const is_signed_int = lhs_scalar_ty.isSignedInt(mod);
......@@ -7697,11 +7758,12 @@ pub const FuncGen = struct {
76977758 }
76987759
76997760 fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7700 const mod = self.dg.module;
7761 const o = self.dg.object;
7762 const mod = o.module;
77017763 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
77027764 const dest_ty = self.typeOfIndex(inst);
77037765 const dest_info = dest_ty.intInfo(mod);
7704 const dest_llvm_ty = try self.dg.lowerType(dest_ty);
7766 const dest_llvm_ty = try o.lowerType(dest_ty);
77057767 const operand = try self.resolveInst(ty_op.operand);
77067768 const operand_ty = self.typeOf(ty_op.operand);
77077769 const operand_info = operand_ty.intInfo(mod);
......@@ -7719,14 +7781,16 @@ pub const FuncGen = struct {
77197781 }
77207782
77217783 fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7784 const o = self.dg.object;
77227785 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
77237786 const operand = try self.resolveInst(ty_op.operand);
7724 const dest_llvm_ty = try self.dg.lowerType(self.typeOfIndex(inst));
7787 const dest_llvm_ty = try o.lowerType(self.typeOfIndex(inst));
77257788 return self.builder.buildTrunc(operand, dest_llvm_ty, "");
77267789 }
77277790
77287791 fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7729 const mod = self.dg.module;
7792 const o = self.dg.object;
7793 const mod = o.module;
77307794 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
77317795 const operand = try self.resolveInst(ty_op.operand);
77327796 const operand_ty = self.typeOf(ty_op.operand);
......@@ -7736,11 +7800,11 @@ pub const FuncGen = struct {
77367800 const src_bits = operand_ty.floatBits(target);
77377801
77387802 if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) {
7739 const dest_llvm_ty = try self.dg.lowerType(dest_ty);
7803 const dest_llvm_ty = try o.lowerType(dest_ty);
77407804 return self.builder.buildFPTrunc(operand, dest_llvm_ty, "");
77417805 } else {
7742 const operand_llvm_ty = try self.dg.lowerType(operand_ty);
7743 const dest_llvm_ty = try self.dg.lowerType(dest_ty);
7806 const operand_llvm_ty = try o.lowerType(operand_ty);
7807 const dest_llvm_ty = try o.lowerType(dest_ty);
77447808
77457809 var fn_name_buf: [64]u8 = undefined;
77467810 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__trunc{s}f{s}f2", .{
......@@ -7756,7 +7820,8 @@ pub const FuncGen = struct {
77567820 }
77577821
77587822 fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7759 const mod = self.dg.module;
7823 const o = self.dg.object;
7824 const mod = o.module;
77607825 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
77617826 const operand = try self.resolveInst(ty_op.operand);
77627827 const operand_ty = self.typeOf(ty_op.operand);
......@@ -7766,11 +7831,11 @@ pub const FuncGen = struct {
77667831 const src_bits = operand_ty.floatBits(target);
77677832
77687833 if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) {
7769 const dest_llvm_ty = try self.dg.lowerType(dest_ty);
7834 const dest_llvm_ty = try o.lowerType(dest_ty);
77707835 return self.builder.buildFPExt(operand, dest_llvm_ty, "");
77717836 } else {
7772 const operand_llvm_ty = try self.dg.lowerType(operand_ty);
7773 const dest_llvm_ty = try self.dg.lowerType(dest_ty);
7837 const operand_llvm_ty = try o.lowerType(operand_ty);
7838 const dest_llvm_ty = try o.lowerType(dest_ty);
77747839
77757840 var fn_name_buf: [64]u8 = undefined;
77767841 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__extend{s}f{s}f2", .{
......@@ -7786,11 +7851,12 @@ pub const FuncGen = struct {
77867851 }
77877852
77887853 fn airIntFromPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7854 const o = self.dg.object;
77897855 const un_op = self.air.instructions.items(.data)[inst].un_op;
77907856 const operand = try self.resolveInst(un_op);
77917857 const ptr_ty = self.typeOf(un_op);
77927858 const operand_ptr = self.sliceOrArrayPtr(operand, ptr_ty);
7793 const dest_llvm_ty = try self.dg.lowerType(self.typeOfIndex(inst));
7859 const dest_llvm_ty = try o.lowerType(self.typeOfIndex(inst));
77947860 return self.builder.buildPtrToInt(operand_ptr, dest_llvm_ty, "");
77957861 }
77967862
......@@ -7803,10 +7869,11 @@ pub const FuncGen = struct {
78037869 }
78047870
78057871 fn bitCast(self: *FuncGen, operand: *llvm.Value, operand_ty: Type, inst_ty: Type) !*llvm.Value {
7806 const mod = self.dg.module;
7872 const o = self.dg.object;
7873 const mod = o.module;
78077874 const operand_is_ref = isByRef(operand_ty, mod);
78087875 const result_is_ref = isByRef(inst_ty, mod);
7809 const llvm_dest_ty = try self.dg.lowerType(inst_ty);
7876 const llvm_dest_ty = try o.lowerType(inst_ty);
78107877
78117878 if (operand_is_ref and result_is_ref) {
78127879 // They are both pointers, so just return the same opaque pointer :)
......@@ -7836,7 +7903,7 @@ pub const FuncGen = struct {
78367903 } else {
78377904 // If the ABI size of the element type is not evenly divisible by size in bits;
78387905 // a simple bitcast will not work, and we fall back to extractelement.
7839 const llvm_usize = try self.dg.lowerType(Type.usize);
7906 const llvm_usize = try o.lowerType(Type.usize);
78407907 const llvm_u32 = self.context.intType(32);
78417908 const zero = llvm_usize.constNull();
78427909 const vector_len = operand_ty.arrayLen(mod);
......@@ -7853,7 +7920,7 @@ pub const FuncGen = struct {
78537920 return array_ptr;
78547921 } else if (operand_ty.zigTypeTag(mod) == .Array and inst_ty.zigTypeTag(mod) == .Vector) {
78557922 const elem_ty = operand_ty.childType(mod);
7856 const llvm_vector_ty = try self.dg.lowerType(inst_ty);
7923 const llvm_vector_ty = try o.lowerType(inst_ty);
78577924 if (!operand_is_ref) {
78587925 return self.dg.todo("implement bitcast non-ref array to vector", .{});
78597926 }
......@@ -7868,9 +7935,9 @@ pub const FuncGen = struct {
78687935 } else {
78697936 // If the ABI size of the element type is not evenly divisible by size in bits;
78707937 // a simple bitcast will not work, and we fall back to extractelement.
7871 const array_llvm_ty = try self.dg.lowerType(operand_ty);
7872 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
7873 const llvm_usize = try self.dg.lowerType(Type.usize);
7938 const array_llvm_ty = try o.lowerType(operand_ty);
7939 const elem_llvm_ty = try o.lowerType(elem_ty);
7940 const llvm_usize = try o.lowerType(Type.usize);
78747941 const llvm_u32 = self.context.intType(32);
78757942 const zero = llvm_usize.constNull();
78767943 const vector_len = operand_ty.arrayLen(mod);
......@@ -7926,13 +7993,14 @@ pub const FuncGen = struct {
79267993 }
79277994
79287995 fn airArg(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7929 const mod = self.dg.module;
7996 const o = self.dg.object;
7997 const mod = o.module;
79307998 const arg_val = self.args[self.arg_index];
79317999 self.arg_index += 1;
79328000
79338001 const inst_ty = self.typeOfIndex(inst);
7934 if (self.dg.object.di_builder) |dib| {
7935 if (needDbgVarWorkaround(self.dg)) {
8002 if (o.di_builder) |dib| {
8003 if (needDbgVarWorkaround(o)) {
79368004 return arg_val;
79378005 }
79388006
......@@ -7945,7 +8013,7 @@ pub const FuncGen = struct {
79458013 func.getParamName(mod, src_index).ptr, // TODO test 0 bit args
79468014 self.di_file.?,
79478015 lbrace_line,
7948 try self.dg.object.lowerDebugType(inst_ty, .full),
8016 try o.lowerDebugType(inst_ty, .full),
79498017 true, // always preserve
79508018 0, // flags
79518019 self.arg_index, // includes +1 because 0 is return type
......@@ -7955,7 +8023,7 @@ pub const FuncGen = struct {
79558023 const insert_block = self.builder.getInsertBlock();
79568024 if (isByRef(inst_ty, mod)) {
79578025 _ = dib.insertDeclareAtEnd(arg_val, di_local_var, debug_loc, insert_block);
7958 } else if (self.dg.module.comp.bin_file.options.optimize_mode == .Debug) {
8026 } else if (o.module.comp.bin_file.options.optimize_mode == .Debug) {
79598027 const alignment = inst_ty.abiAlignment(mod);
79608028 const alloca = self.buildAlloca(arg_val.typeOf(), alignment);
79618029 const store_inst = self.builder.buildStore(arg_val, alloca);
......@@ -7970,34 +8038,41 @@ pub const FuncGen = struct {
79708038 }
79718039
79728040 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7973 const mod = self.dg.module;
8041 const o = self.dg.object;
8042 const mod = o.module;
79748043 const ptr_ty = self.typeOfIndex(inst);
79758044 const pointee_type = ptr_ty.childType(mod);
7976 if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty);
8045 if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(mod))
8046 return o.lowerPtrToVoid(ptr_ty);
79778047
7978 const pointee_llvm_ty = try self.dg.lowerType(pointee_type);
8048 const pointee_llvm_ty = try o.lowerType(pointee_type);
79798049 const alignment = ptr_ty.ptrAlignment(mod);
79808050 return self.buildAlloca(pointee_llvm_ty, alignment);
79818051 }
79828052
79838053 fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7984 const mod = self.dg.module;
8054 const o = self.dg.object;
8055 const mod = o.module;
79858056 const ptr_ty = self.typeOfIndex(inst);
79868057 const ret_ty = ptr_ty.childType(mod);
7987 if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty);
8058 if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return o.lowerPtrToVoid(ptr_ty);
79888059 if (self.ret_ptr) |ret_ptr| return ret_ptr;
7989 const ret_llvm_ty = try self.dg.lowerType(ret_ty);
8060 const ret_llvm_ty = try o.lowerType(ret_ty);
79908061 return self.buildAlloca(ret_llvm_ty, ptr_ty.ptrAlignment(mod));
79918062 }
79928063
79938064 /// Use this instead of builder.buildAlloca, because this function makes sure to
79948065 /// put the alloca instruction at the top of the function!
79958066 fn buildAlloca(self: *FuncGen, llvm_ty: *llvm.Type, alignment: ?c_uint) *llvm.Value {
7996 return buildAllocaInner(self.context, self.builder, self.llvm_func, self.di_scope != null, llvm_ty, alignment, self.dg.module.getTarget());
8067 const o = self.dg.object;
8068 const mod = o.module;
8069 const target = mod.getTarget();
8070 return buildAllocaInner(self.context, self.builder, self.llvm_func, self.di_scope != null, llvm_ty, alignment, target);
79978071 }
79988072
79998073 fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !?*llvm.Value {
8000 const mod = self.dg.module;
8074 const o = self.dg.object;
8075 const mod = o.module;
80018076 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
80028077 const dest_ptr = try self.resolveInst(bin_op.lhs);
80038078 const ptr_ty = self.typeOf(bin_op.lhs);
......@@ -8014,7 +8089,7 @@ pub const FuncGen = struct {
80148089 else
80158090 u8_llvm_ty.getUndef();
80168091 const operand_size = operand_ty.abiSize(mod);
8017 const usize_llvm_ty = try self.dg.lowerType(Type.usize);
8092 const usize_llvm_ty = try o.lowerType(Type.usize);
80188093 const len = usize_llvm_ty.constInt(operand_size, .False);
80198094 const dest_ptr_align = ptr_ty.ptrAlignment(mod);
80208095 _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr(mod));
......@@ -8036,7 +8111,8 @@ pub const FuncGen = struct {
80368111 ///
80378112 /// The first instruction of `body_tail` is the one whose copy we want to elide.
80388113 fn canElideLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) bool {
8039 const mod = fg.dg.module;
8114 const o = fg.dg.object;
8115 const mod = o.module;
80408116 const ip = &mod.intern_pool;
80418117 for (body_tail[1..]) |body_inst| {
80428118 switch (fg.liveness.categorizeOperand(fg.air, body_inst, body_tail[0], ip)) {
......@@ -8051,7 +8127,8 @@ pub const FuncGen = struct {
80518127 }
80528128
80538129 fn airLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
8054 const mod = fg.dg.module;
8130 const o = fg.dg.object;
8131 const mod = o.module;
80558132 const inst = body_tail[0];
80568133 const ty_op = fg.air.instructions.items(.data)[inst].ty_op;
80578134 const ptr_ty = fg.typeOf(ty_op.operand);
......@@ -8083,8 +8160,9 @@ pub const FuncGen = struct {
80838160
80848161 fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
80858162 _ = inst;
8086 const mod = self.dg.module;
8087 const llvm_usize = try self.dg.lowerType(Type.usize);
8163 const o = self.dg.object;
8164 const mod = o.module;
8165 const llvm_usize = try o.lowerType(Type.usize);
80888166 const target = mod.getTarget();
80898167 if (!target_util.supportsReturnAddress(target)) {
80908168 // https://github.com/ziglang/zig/issues/11946
......@@ -8100,18 +8178,19 @@ pub const FuncGen = struct {
81008178
81018179 fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
81028180 _ = inst;
8181 const o = self.dg.object;
81038182 const llvm_i32 = self.context.intType(32);
81048183 const llvm_fn_name = "llvm.frameaddress.p0";
8105 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
8184 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
81068185 const llvm_p0i8 = self.context.pointerType(0);
81078186 const param_types = [_]*llvm.Type{llvm_i32};
81088187 const fn_type = llvm.functionType(llvm_p0i8, &param_types, param_types.len, .False);
8109 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
8188 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type);
81108189 };
81118190
81128191 const params = [_]*llvm.Value{llvm_i32.constNull()};
81138192 const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, "");
8114 const llvm_usize = try self.dg.lowerType(Type.usize);
8193 const llvm_usize = try o.lowerType(Type.usize);
81158194 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
81168195 }
81178196
......@@ -8124,14 +8203,15 @@ pub const FuncGen = struct {
81248203 }
81258204
81268205 fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*llvm.Value {
8127 const mod = self.dg.module;
8206 const o = self.dg.object;
8207 const mod = o.module;
81288208 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
81298209 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
81308210 const ptr = try self.resolveInst(extra.ptr);
81318211 var expected_value = try self.resolveInst(extra.expected_value);
81328212 var new_value = try self.resolveInst(extra.new_value);
81338213 const operand_ty = self.typeOf(extra.ptr).childType(mod);
8134 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
8214 const opt_abi_ty = o.getAtomicAbiType(operand_ty, false);
81358215 if (opt_abi_ty) |abi_ty| {
81368216 // operand needs widening and truncating
81378217 if (operand_ty.isSignedInt(mod)) {
......@@ -8156,7 +8236,7 @@ pub const FuncGen = struct {
81568236
81578237 var payload = self.builder.buildExtractValue(result, 0, "");
81588238 if (opt_abi_ty != null) {
8159 payload = self.builder.buildTrunc(payload, try self.dg.lowerType(operand_ty), "");
8239 payload = self.builder.buildTrunc(payload, try o.lowerType(operand_ty), "");
81608240 }
81618241 const success_bit = self.builder.buildExtractValue(result, 1, "");
81628242
......@@ -8171,7 +8251,8 @@ pub const FuncGen = struct {
81718251 }
81728252
81738253 fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8174 const mod = self.dg.module;
8254 const o = self.dg.object;
8255 const mod = o.module;
81758256 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
81768257 const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;
81778258 const ptr = try self.resolveInst(pl_op.operand);
......@@ -8183,7 +8264,7 @@ pub const FuncGen = struct {
81838264 const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float);
81848265 const ordering = toLlvmAtomicOrdering(extra.ordering());
81858266 const single_threaded = llvm.Bool.fromBool(self.single_threaded);
8186 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, op == .Xchg);
8267 const opt_abi_ty = o.getAtomicAbiType(operand_ty, op == .Xchg);
81878268 if (opt_abi_ty) |abi_ty| {
81888269 // operand needs widening and truncating or bitcasting.
81898270 const casted_operand = if (is_float)
......@@ -8200,7 +8281,7 @@ pub const FuncGen = struct {
82008281 ordering,
82018282 single_threaded,
82028283 );
8203 const operand_llvm_ty = try self.dg.lowerType(operand_ty);
8284 const operand_llvm_ty = try o.lowerType(operand_ty);
82048285 if (is_float) {
82058286 return self.builder.buildBitCast(uncasted_result, operand_llvm_ty, "");
82068287 } else {
......@@ -8213,7 +8294,7 @@ pub const FuncGen = struct {
82138294 }
82148295
82158296 // It's a pointer but we need to treat it as an int.
8216 const usize_llvm_ty = try self.dg.lowerType(Type.usize);
8297 const usize_llvm_ty = try o.lowerType(Type.usize);
82178298 const casted_operand = self.builder.buildPtrToInt(operand, usize_llvm_ty, "");
82188299 const uncasted_result = self.builder.buildAtomicRmw(
82198300 op,
......@@ -8222,12 +8303,13 @@ pub const FuncGen = struct {
82228303 ordering,
82238304 single_threaded,
82248305 );
8225 const operand_llvm_ty = try self.dg.lowerType(operand_ty);
8306 const operand_llvm_ty = try o.lowerType(operand_ty);
82268307 return self.builder.buildIntToPtr(uncasted_result, operand_llvm_ty, "");
82278308 }
82288309
82298310 fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8230 const mod = self.dg.module;
8311 const o = self.dg.object;
8312 const mod = o.module;
82318313 const atomic_load = self.air.instructions.items(.data)[inst].atomic_load;
82328314 const ptr = try self.resolveInst(atomic_load.ptr);
82338315 const ptr_ty = self.typeOf(atomic_load.ptr);
......@@ -8236,11 +8318,11 @@ pub const FuncGen = struct {
82368318 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod))
82378319 return null;
82388320 const ordering = toLlvmAtomicOrdering(atomic_load.order);
8239 const opt_abi_llvm_ty = self.dg.getAtomicAbiType(elem_ty, false);
8321 const opt_abi_llvm_ty = o.getAtomicAbiType(elem_ty, false);
82408322 const ptr_alignment = @intCast(u32, ptr_info.flags.alignment.toByteUnitsOptional() orelse
82418323 ptr_info.child.toType().abiAlignment(mod));
82428324 const ptr_volatile = llvm.Bool.fromBool(ptr_info.flags.is_volatile);
8243 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
8325 const elem_llvm_ty = try o.lowerType(elem_ty);
82448326
82458327 if (opt_abi_llvm_ty) |abi_llvm_ty| {
82468328 // operand needs widening and truncating
......@@ -8262,14 +8344,15 @@ pub const FuncGen = struct {
82628344 inst: Air.Inst.Index,
82638345 ordering: llvm.AtomicOrdering,
82648346 ) !?*llvm.Value {
8265 const mod = self.dg.module;
8347 const o = self.dg.object;
8348 const mod = o.module;
82668349 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
82678350 const ptr_ty = self.typeOf(bin_op.lhs);
82688351 const operand_ty = ptr_ty.childType(mod);
82698352 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return null;
82708353 const ptr = try self.resolveInst(bin_op.lhs);
82718354 var element = try self.resolveInst(bin_op.rhs);
8272 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
8355 const opt_abi_ty = o.getAtomicAbiType(operand_ty, false);
82738356
82748357 if (opt_abi_ty) |abi_ty| {
82758358 // operand needs widening
......@@ -8284,7 +8367,8 @@ pub const FuncGen = struct {
82848367 }
82858368
82868369 fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !?*llvm.Value {
8287 const mod = self.dg.module;
8370 const o = self.dg.object;
8371 const mod = o.module;
82888372 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
82898373 const dest_slice = try self.resolveInst(bin_op.lhs);
82908374 const ptr_ty = self.typeOf(bin_op.lhs);
......@@ -8366,7 +8450,7 @@ pub const FuncGen = struct {
83668450 .One => llvm_usize_ty.constInt(ptr_ty.childType(mod).arrayLen(mod), .False),
83678451 .Many, .C => unreachable,
83688452 };
8369 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
8453 const elem_llvm_ty = try o.lowerType(elem_ty);
83708454 const len_gep = [_]*llvm.Value{len};
83718455 const end_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, dest_ptr, &len_gep, len_gep.len, "");
83728456 _ = self.builder.buildBr(loop_block);
......@@ -8407,6 +8491,8 @@ pub const FuncGen = struct {
84078491 }
84088492
84098493 fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8494 const o = self.dg.object;
8495 const mod = o.module;
84108496 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
84118497 const dest_slice = try self.resolveInst(bin_op.lhs);
84128498 const dest_ptr_ty = self.typeOf(bin_op.lhs);
......@@ -8415,7 +8501,6 @@ pub const FuncGen = struct {
84158501 const src_ptr = self.sliceOrArrayPtr(src_slice, src_ptr_ty);
84168502 const len = self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty);
84178503 const dest_ptr = self.sliceOrArrayPtr(dest_slice, dest_ptr_ty);
8418 const mod = self.dg.module;
84198504 const is_volatile = src_ptr_ty.isVolatilePtr(mod) or dest_ptr_ty.isVolatilePtr(mod);
84208505 _ = self.builder.buildMemCpy(
84218506 dest_ptr,
......@@ -8429,7 +8514,8 @@ pub const FuncGen = struct {
84298514 }
84308515
84318516 fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8432 const mod = self.dg.module;
8517 const o = self.dg.object;
8518 const mod = o.module;
84338519 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
84348520 const un_ty = self.typeOf(bin_op.lhs).childType(mod);
84358521 const layout = un_ty.unionGetLayout(mod);
......@@ -8441,7 +8527,7 @@ pub const FuncGen = struct {
84418527 _ = self.builder.buildStore(new_tag, union_ptr);
84428528 return null;
84438529 }
8444 const un_llvm_ty = try self.dg.lowerType(un_ty);
8530 const un_llvm_ty = try o.lowerType(un_ty);
84458531 const tag_index = @intFromBool(layout.tag_align < layout.payload_align);
84468532 const tag_field_ptr = self.builder.buildStructGEP(un_llvm_ty, union_ptr, tag_index, "");
84478533 // TODO alignment on this store
......@@ -8450,14 +8536,15 @@ pub const FuncGen = struct {
84508536 }
84518537
84528538 fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8453 const mod = self.dg.module;
8539 const o = self.dg.object;
8540 const mod = o.module;
84548541 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
84558542 const un_ty = self.typeOf(ty_op.operand);
84568543 const layout = un_ty.unionGetLayout(mod);
84578544 if (layout.tag_size == 0) return null;
84588545 const union_handle = try self.resolveInst(ty_op.operand);
84598546 if (isByRef(un_ty, mod)) {
8460 const llvm_un_ty = try self.dg.lowerType(un_ty);
8547 const llvm_un_ty = try o.lowerType(un_ty);
84618548 if (layout.payload_size == 0) {
84628549 return self.builder.buildLoad(llvm_un_ty, union_handle, "");
84638550 }
......@@ -8492,19 +8579,20 @@ pub const FuncGen = struct {
84928579 }
84938580
84948581 fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {
8495 const mod = self.dg.module;
8582 const o = self.dg.object;
8583 const mod = o.module;
84968584 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
84978585 const operand_ty = self.typeOf(ty_op.operand);
84988586 const operand = try self.resolveInst(ty_op.operand);
84998587
85008588 const llvm_i1 = self.context.intType(1);
8501 const operand_llvm_ty = try self.dg.lowerType(operand_ty);
8589 const operand_llvm_ty = try o.lowerType(operand_ty);
85028590 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
85038591
85048592 const params = [_]*llvm.Value{ operand, llvm_i1.constNull() };
85058593 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
85068594 const result_ty = self.typeOfIndex(inst);
8507 const result_llvm_ty = try self.dg.lowerType(result_ty);
8595 const result_llvm_ty = try o.lowerType(result_ty);
85088596
85098597 const bits = operand_ty.intInfo(mod).bits;
85108598 const result_bits = result_ty.intInfo(mod).bits;
......@@ -8518,18 +8606,19 @@ pub const FuncGen = struct {
85188606 }
85198607
85208608 fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {
8521 const mod = self.dg.module;
8609 const o = self.dg.object;
8610 const mod = o.module;
85228611 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
85238612 const operand_ty = self.typeOf(ty_op.operand);
85248613 const operand = try self.resolveInst(ty_op.operand);
85258614
85268615 const params = [_]*llvm.Value{operand};
8527 const operand_llvm_ty = try self.dg.lowerType(operand_ty);
8616 const operand_llvm_ty = try o.lowerType(operand_ty);
85288617 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
85298618
85308619 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
85318620 const result_ty = self.typeOfIndex(inst);
8532 const result_llvm_ty = try self.dg.lowerType(result_ty);
8621 const result_llvm_ty = try o.lowerType(result_ty);
85338622
85348623 const bits = operand_ty.intInfo(mod).bits;
85358624 const result_bits = result_ty.intInfo(mod).bits;
......@@ -8543,14 +8632,15 @@ pub const FuncGen = struct {
85438632 }
85448633
85458634 fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {
8546 const mod = self.dg.module;
8635 const o = self.dg.object;
8636 const mod = o.module;
85478637 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
85488638 const operand_ty = self.typeOf(ty_op.operand);
85498639 var bits = operand_ty.intInfo(mod).bits;
85508640 assert(bits % 8 == 0);
85518641
85528642 var operand = try self.resolveInst(ty_op.operand);
8553 var operand_llvm_ty = try self.dg.lowerType(operand_ty);
8643 var operand_llvm_ty = try o.lowerType(operand_ty);
85548644
85558645 if (bits % 16 == 8) {
85568646 // If not an even byte-multiple, we need zero-extend + shift-left 1 byte
......@@ -8584,7 +8674,7 @@ pub const FuncGen = struct {
85848674 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
85858675
85868676 const result_ty = self.typeOfIndex(inst);
8587 const result_llvm_ty = try self.dg.lowerType(result_ty);
8677 const result_llvm_ty = try o.lowerType(result_ty);
85888678 const result_bits = result_ty.intInfo(mod).bits;
85898679 if (bits > result_bits) {
85908680 return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, "");
......@@ -8596,7 +8686,8 @@ pub const FuncGen = struct {
85968686 }
85978687
85988688 fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8599 const mod = self.dg.module;
8689 const o = self.dg.object;
8690 const mod = o.module;
86008691 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
86018692 const operand = try self.resolveInst(ty_op.operand);
86028693 const error_set_ty = self.air.getRefType(ty_op.ty);
......@@ -8609,7 +8700,7 @@ pub const FuncGen = struct {
86098700
86108701 for (names) |name| {
86118702 const err_int = @intCast(Module.ErrorInt, mod.global_error_set.getIndex(name).?);
8612 const this_tag_int_value = try self.dg.lowerValue(.{
8703 const this_tag_int_value = try o.lowerValue(.{
86138704 .ty = Type.err_int,
86148705 .val = try mod.intValue(Type.err_int, err_int),
86158706 });
......@@ -8646,13 +8737,14 @@ pub const FuncGen = struct {
86468737 }
86478738
86488739 fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !*llvm.Value {
8649 const mod = self.dg.module;
8740 const o = self.dg.object;
8741 const mod = o.module;
86508742 const enum_type = mod.intern_pool.indexToKey(enum_ty.toIntern()).enum_type;
86518743
86528744 // TODO: detect when the type changes and re-emit this function.
8653 const gop = try self.dg.object.named_enum_map.getOrPut(self.dg.gpa, enum_type.decl);
8745 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_type.decl);
86548746 if (gop.found_existing) return gop.value_ptr.*;
8655 errdefer assert(self.dg.object.named_enum_map.remove(enum_type.decl));
8747 errdefer assert(o.named_enum_map.remove(enum_type.decl));
86568748
86578749 var arena_allocator = std.heap.ArenaAllocator.init(self.gpa);
86588750 defer arena_allocator.deinit();
......@@ -8661,14 +8753,14 @@ pub const FuncGen = struct {
86618753 const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);
86628754 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{}", .{fqn.fmt(&mod.intern_pool)});
86638755
8664 const param_types = [_]*llvm.Type{try self.dg.lowerType(enum_type.tag_ty.toType())};
8756 const param_types = [_]*llvm.Type{try o.lowerType(enum_type.tag_ty.toType())};
86658757
8666 const llvm_ret_ty = try self.dg.lowerType(Type.bool);
8758 const llvm_ret_ty = try o.lowerType(Type.bool);
86678759 const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False);
8668 const fn_val = self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
8760 const fn_val = o.llvm_module.addFunction(llvm_fn_name, fn_type);
86698761 fn_val.setLinkage(.Internal);
86708762 fn_val.setFunctionCallConv(.Fast);
8671 self.dg.addCommonFnAttributes(fn_val);
8763 o.addCommonFnAttributes(fn_val);
86728764 gop.value_ptr.* = fn_val;
86738765
86748766 const prev_block = self.builder.getInsertBlock();
......@@ -8692,7 +8784,7 @@ pub const FuncGen = struct {
86928784 for (enum_type.names, 0..) |_, field_index_usize| {
86938785 const field_index = @intCast(u32, field_index_usize);
86948786 const this_tag_int_value = int: {
8695 break :int try self.dg.lowerValue(.{
8787 break :int try o.lowerValue(.{
86968788 .ty = enum_ty,
86978789 .val = try mod.enumValueFieldIndex(enum_ty, field_index),
86988790 });
......@@ -8718,13 +8810,14 @@ pub const FuncGen = struct {
87188810 }
87198811
87208812 fn getEnumTagNameFunction(self: *FuncGen, enum_ty: Type) !*llvm.Value {
8721 const mod = self.dg.module;
8813 const o = self.dg.object;
8814 const mod = o.module;
87228815 const enum_type = mod.intern_pool.indexToKey(enum_ty.toIntern()).enum_type;
87238816
87248817 // TODO: detect when the type changes and re-emit this function.
8725 const gop = try self.dg.object.decl_map.getOrPut(self.dg.gpa, enum_type.decl);
8818 const gop = try o.decl_map.getOrPut(o.gpa, enum_type.decl);
87268819 if (gop.found_existing) return gop.value_ptr.*;
8727 errdefer assert(self.dg.object.decl_map.remove(enum_type.decl));
8820 errdefer assert(o.decl_map.remove(enum_type.decl));
87288821
87298822 var arena_allocator = std.heap.ArenaAllocator.init(self.gpa);
87308823 defer arena_allocator.deinit();
......@@ -8734,17 +8827,17 @@ pub const FuncGen = struct {
87348827 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{fqn.fmt(&mod.intern_pool)});
87358828
87368829 const slice_ty = Type.slice_const_u8_sentinel_0;
8737 const llvm_ret_ty = try self.dg.lowerType(slice_ty);
8738 const usize_llvm_ty = try self.dg.lowerType(Type.usize);
8830 const llvm_ret_ty = try o.lowerType(slice_ty);
8831 const usize_llvm_ty = try o.lowerType(Type.usize);
87398832 const slice_alignment = slice_ty.abiAlignment(mod);
87408833
8741 const param_types = [_]*llvm.Type{try self.dg.lowerType(enum_type.tag_ty.toType())};
8834 const param_types = [_]*llvm.Type{try o.lowerType(enum_type.tag_ty.toType())};
87428835
87438836 const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False);
8744 const fn_val = self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
8837 const fn_val = o.llvm_module.addFunction(llvm_fn_name, fn_type);
87458838 fn_val.setLinkage(.Internal);
87468839 fn_val.setFunctionCallConv(.Fast);
8747 self.dg.addCommonFnAttributes(fn_val);
8840 o.addCommonFnAttributes(fn_val);
87488841 gop.value_ptr.* = fn_val;
87498842
87508843 const prev_block = self.builder.getInsertBlock();
......@@ -8773,7 +8866,7 @@ pub const FuncGen = struct {
87738866 const name = mod.intern_pool.stringToSlice(name_ip);
87748867 const str_init = self.context.constString(name.ptr, @intCast(c_uint, name.len), .False);
87758868 const str_init_llvm_ty = str_init.typeOf();
8776 const str_global = self.dg.object.llvm_module.addGlobal(str_init_llvm_ty, "");
8869 const str_global = o.llvm_module.addGlobal(str_init_llvm_ty, "");
87778870 str_global.setInitializer(str_init);
87788871 str_global.setLinkage(.Private);
87798872 str_global.setGlobalConstant(.True);
......@@ -8785,7 +8878,7 @@ pub const FuncGen = struct {
87858878 usize_llvm_ty.constInt(name.len, .False),
87868879 };
87878880 const slice_init = llvm_ret_ty.constNamedStruct(&slice_fields, slice_fields.len);
8788 const slice_global = self.dg.object.llvm_module.addGlobal(slice_init.typeOf(), "");
8881 const slice_global = o.llvm_module.addGlobal(slice_init.typeOf(), "");
87898882 slice_global.setInitializer(slice_init);
87908883 slice_global.setLinkage(.Private);
87918884 slice_global.setGlobalConstant(.True);
......@@ -8793,7 +8886,7 @@ pub const FuncGen = struct {
87938886 slice_global.setAlignment(slice_alignment);
87948887
87958888 const return_block = self.context.appendBasicBlock(fn_val, "Name");
8796 const this_tag_int_value = try self.dg.lowerValue(.{
8889 const this_tag_int_value = try o.lowerValue(.{
87978890 .ty = enum_ty,
87988891 .val = try mod.enumValueFieldIndex(enum_ty, field_index),
87998892 });
......@@ -8811,29 +8904,32 @@ pub const FuncGen = struct {
88118904 }
88128905
88138906 fn getCmpLtErrorsLenFunction(self: *FuncGen) !*llvm.Value {
8814 if (self.dg.object.llvm_module.getNamedFunction(lt_errors_fn_name)) |llvm_fn| {
8907 const o = self.dg.object;
8908
8909 if (o.llvm_module.getNamedFunction(lt_errors_fn_name)) |llvm_fn| {
88158910 return llvm_fn;
88168911 }
88178912
88188913 // Function signature: fn (anyerror) bool
88198914
8820 const ret_llvm_ty = try self.dg.lowerType(Type.bool);
8821 const anyerror_llvm_ty = try self.dg.lowerType(Type.anyerror);
8915 const ret_llvm_ty = try o.lowerType(Type.bool);
8916 const anyerror_llvm_ty = try o.lowerType(Type.anyerror);
88228917 const param_types = [_]*llvm.Type{anyerror_llvm_ty};
88238918
88248919 const fn_type = llvm.functionType(ret_llvm_ty, &param_types, param_types.len, .False);
8825 const llvm_fn = self.dg.object.llvm_module.addFunction(lt_errors_fn_name, fn_type);
8920 const llvm_fn = o.llvm_module.addFunction(lt_errors_fn_name, fn_type);
88268921 llvm_fn.setLinkage(.Internal);
88278922 llvm_fn.setFunctionCallConv(.Fast);
8828 self.dg.addCommonFnAttributes(llvm_fn);
8923 o.addCommonFnAttributes(llvm_fn);
88298924 return llvm_fn;
88308925 }
88318926
88328927 fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8928 const o = self.dg.object;
88338929 const un_op = self.air.instructions.items(.data)[inst].un_op;
88348930 const operand = try self.resolveInst(un_op);
88358931 const slice_ty = self.typeOfIndex(inst);
8836 const slice_llvm_ty = try self.dg.lowerType(slice_ty);
8932 const slice_llvm_ty = try o.lowerType(slice_ty);
88378933
88388934 const error_name_table_ptr = try self.getErrorNameTable();
88398935 const ptr_slice_llvm_ty = self.context.pointerType(0);
......@@ -8844,7 +8940,8 @@ pub const FuncGen = struct {
88448940 }
88458941
88468942 fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8847 const mod = self.dg.module;
8943 const o = self.dg.object;
8944 const mod = o.module;
88488945 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
88498946 const scalar = try self.resolveInst(ty_op.operand);
88508947 const vector_ty = self.typeOfIndex(inst);
......@@ -8863,7 +8960,8 @@ pub const FuncGen = struct {
88638960 }
88648961
88658962 fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8866 const mod = self.dg.module;
8963 const o = self.dg.object;
8964 const mod = o.module;
88678965 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
88688966 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
88698967 const a = try self.resolveInst(extra.a);
......@@ -8916,7 +9014,8 @@ pub const FuncGen = struct {
89169014 vector_len: usize,
89179015 accum_init: *llvm.Value,
89189016 ) !*llvm.Value {
8919 const llvm_usize_ty = try self.dg.lowerType(Type.usize);
9017 const o = self.dg.object;
9018 const llvm_usize_ty = try o.lowerType(Type.usize);
89209019 const llvm_vector_len = llvm_usize_ty.constInt(vector_len, .False);
89219020 const llvm_result_ty = accum_init.typeOf();
89229021
......@@ -8963,7 +9062,8 @@ pub const FuncGen = struct {
89639062
89649063 fn airReduce(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
89659064 self.builder.setFastMath(want_fast_math);
8966 const mod = self.dg.module;
9065 const o = self.dg.object;
9066 const mod = o.module;
89679067 const target = mod.getTarget();
89689068
89699069 const reduce = self.air.instructions.items(.data)[inst].reduce;
......@@ -8992,7 +9092,7 @@ pub const FuncGen = struct {
89929092 .Add => switch (scalar_ty.zigTypeTag(mod)) {
89939093 .Int => return self.builder.buildAddReduce(operand),
89949094 .Float => if (intrinsicsAllowed(scalar_ty, target)) {
8995 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
9095 const scalar_llvm_ty = try o.lowerType(scalar_ty);
89969096 const neutral_value = scalar_llvm_ty.constReal(-0.0);
89979097 return self.builder.buildFPAddReduce(neutral_value, operand);
89989098 },
......@@ -9001,7 +9101,7 @@ pub const FuncGen = struct {
90019101 .Mul => switch (scalar_ty.zigTypeTag(mod)) {
90029102 .Int => return self.builder.buildMulReduce(operand),
90039103 .Float => if (intrinsicsAllowed(scalar_ty, target)) {
9004 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
9104 const scalar_llvm_ty = try o.lowerType(scalar_ty);
90059105 const neutral_value = scalar_llvm_ty.constReal(1.0);
90069106 return self.builder.buildFPMulReduce(neutral_value, operand);
90079107 },
......@@ -9029,10 +9129,10 @@ pub const FuncGen = struct {
90299129 else => unreachable,
90309130 };
90319131
9032 const param_llvm_ty = try self.dg.lowerType(scalar_ty);
9132 const param_llvm_ty = try o.lowerType(scalar_ty);
90339133 const param_types = [2]*llvm.Type{ param_llvm_ty, param_llvm_ty };
90349134 const libc_fn = self.getLibcFunction(fn_name, &param_types, param_llvm_ty);
9035 const init_value = try self.dg.lowerValue(.{
9135 const init_value = try o.lowerValue(.{
90369136 .ty = scalar_ty,
90379137 .val = try mod.floatValue(scalar_ty, switch (reduce.operation) {
90389138 .Min => std.math.nan(f32),
......@@ -9046,12 +9146,13 @@ pub const FuncGen = struct {
90469146 }
90479147
90489148 fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9049 const mod = self.dg.module;
9149 const o = self.dg.object;
9150 const mod = o.module;
90509151 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
90519152 const result_ty = self.typeOfIndex(inst);
90529153 const len = @intCast(usize, result_ty.arrayLen(mod));
90539154 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
9054 const llvm_result_ty = try self.dg.lowerType(result_ty);
9155 const llvm_result_ty = try o.lowerType(result_ty);
90559156
90569157 switch (result_ty.zigTypeTag(mod)) {
90579158 .Vector => {
......@@ -9139,7 +9240,7 @@ pub const FuncGen = struct {
91399240 .Array => {
91409241 assert(isByRef(result_ty, mod));
91419242
9142 const llvm_usize = try self.dg.lowerType(Type.usize);
9243 const llvm_usize = try o.lowerType(Type.usize);
91439244 const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod));
91449245
91459246 const array_info = result_ty.arrayInfo(mod);
......@@ -9177,11 +9278,12 @@ pub const FuncGen = struct {
91779278 }
91789279
91799280 fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9180 const mod = self.dg.module;
9281 const o = self.dg.object;
9282 const mod = o.module;
91819283 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
91829284 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
91839285 const union_ty = self.typeOfIndex(inst);
9184 const union_llvm_ty = try self.dg.lowerType(union_ty);
9286 const union_llvm_ty = try o.lowerType(union_ty);
91859287 const layout = union_ty.unionGetLayout(mod);
91869288 const union_obj = mod.typeToUnion(union_ty).?;
91879289
......@@ -9223,7 +9325,7 @@ pub const FuncGen = struct {
92239325 const llvm_payload = try self.resolveInst(extra.init);
92249326 assert(union_obj.haveFieldTypes());
92259327 const field = union_obj.fields.values()[extra.field_index];
9226 const field_llvm_ty = try self.dg.lowerType(field.ty);
9328 const field_llvm_ty = try o.lowerType(field.ty);
92279329 const field_size = field.ty.abiSize(mod);
92289330 const field_align = field.normalAlignment(mod);
92299331
......@@ -9246,7 +9348,7 @@ pub const FuncGen = struct {
92469348 const fields: [1]*llvm.Type = .{payload};
92479349 break :t self.context.structType(&fields, fields.len, .False);
92489350 }
9249 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);
9351 const tag_llvm_ty = try o.lowerType(union_obj.tag_ty);
92509352 var fields: [3]*llvm.Type = undefined;
92519353 var fields_len: c_uint = 2;
92529354 if (layout.tag_align >= layout.payload_align) {
......@@ -9299,7 +9401,7 @@ pub const FuncGen = struct {
92999401 index_type.constInt(@intFromBool(layout.tag_align < layout.payload_align), .False),
93009402 };
93019403 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, indices.len, "");
9302 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);
9404 const tag_llvm_ty = try o.lowerType(union_obj.tag_ty);
93039405 const llvm_tag = tag_llvm_ty.constInt(tag_int, .False);
93049406 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);
93059407 store_inst.setAlignment(union_obj.tag_ty.abiAlignment(mod));
......@@ -9309,6 +9411,7 @@ pub const FuncGen = struct {
93099411 }
93109412
93119413 fn airPrefetch(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9414 const o = self.dg.object;
93129415 const prefetch = self.air.instructions.items(.data)[inst].prefetch;
93139416
93149417 comptime assert(@intFromEnum(std.builtin.PrefetchOptions.Rw.read) == 0);
......@@ -9326,7 +9429,7 @@ pub const FuncGen = struct {
93269429 // by the target.
93279430 // To work around this, don't emit llvm.prefetch in this case.
93289431 // See https://bugs.llvm.org/show_bug.cgi?id=21037
9329 const mod = self.dg.module;
9432 const mod = o.module;
93309433 const target = mod.getTarget();
93319434 switch (prefetch.cache) {
93329435 .instruction => switch (target.cpu.arch) {
......@@ -9352,14 +9455,14 @@ pub const FuncGen = struct {
93529455 const llvm_u32 = self.context.intType(32);
93539456
93549457 const llvm_fn_name = "llvm.prefetch.p0";
9355 const fn_val = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
9458 const fn_val = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
93569459 // declare void @llvm.prefetch(i8*, i32, i32, i32)
93579460 const llvm_void = self.context.voidType();
93589461 const param_types = [_]*llvm.Type{
93599462 llvm_ptr_u8, llvm_u32, llvm_u32, llvm_u32,
93609463 };
93619464 const fn_type = llvm.functionType(llvm_void, &param_types, param_types.len, .False);
9362 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
9465 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type);
93639466 };
93649467
93659468 const ptr = try self.resolveInst(prefetch.ptr);
......@@ -9375,11 +9478,12 @@ pub const FuncGen = struct {
93759478 }
93769479
93779480 fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9481 const o = self.dg.object;
93789482 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
93799483 const inst_ty = self.typeOfIndex(inst);
93809484 const operand = try self.resolveInst(ty_op.operand);
93819485
9382 const llvm_dest_ty = try self.dg.lowerType(inst_ty);
9486 const llvm_dest_ty = try o.lowerType(inst_ty);
93839487 return self.builder.buildAddrSpaceCast(operand, llvm_dest_ty, "");
93849488 }
93859489
......@@ -9399,7 +9503,8 @@ pub const FuncGen = struct {
93999503 }
94009504
94019505 fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9402 const target = self.dg.module.getTarget();
9506 const o = self.dg.object;
9507 const target = o.module.getTarget();
94039508 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
94049509
94059510 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
......@@ -9408,7 +9513,8 @@ pub const FuncGen = struct {
94089513 }
94099514
94109515 fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9411 const target = self.dg.module.getTarget();
9516 const o = self.dg.object;
9517 const target = o.module.getTarget();
94129518 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
94139519
94149520 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
......@@ -9437,7 +9543,8 @@ pub const FuncGen = struct {
94379543 }
94389544
94399545 fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9440 const target = self.dg.module.getTarget();
9546 const o = self.dg.object;
9547 const target = o.module.getTarget();
94419548 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
94429549
94439550 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
......@@ -9446,23 +9553,24 @@ pub const FuncGen = struct {
94469553 }
94479554
94489555 fn getErrorNameTable(self: *FuncGen) !*llvm.Value {
9449 if (self.dg.object.error_name_table) |table| {
9556 const o = self.dg.object;
9557 if (o.error_name_table) |table| {
94509558 return table;
94519559 }
94529560
9453 const mod = self.dg.module;
9561 const mod = o.module;
94549562 const slice_ty = Type.slice_const_u8_sentinel_0;
94559563 const slice_alignment = slice_ty.abiAlignment(mod);
94569564 const llvm_slice_ptr_ty = self.context.pointerType(0); // TODO: Address space
94579565
9458 const error_name_table_global = self.dg.object.llvm_module.addGlobal(llvm_slice_ptr_ty, "__zig_err_name_table");
9566 const error_name_table_global = o.llvm_module.addGlobal(llvm_slice_ptr_ty, "__zig_err_name_table");
94599567 error_name_table_global.setInitializer(llvm_slice_ptr_ty.getUndef());
94609568 error_name_table_global.setLinkage(.Private);
94619569 error_name_table_global.setGlobalConstant(.True);
94629570 error_name_table_global.setUnnamedAddr(.True);
94639571 error_name_table_global.setAlignment(slice_alignment);
94649572
9465 self.dg.object.error_name_table = error_name_table_global;
9573 o.error_name_table = error_name_table_global;
94669574 return error_name_table_global;
94679575 }
94689576
......@@ -9494,7 +9602,8 @@ pub const FuncGen = struct {
94949602 opt_ty: Type,
94959603 can_elide_load: bool,
94969604 ) !*llvm.Value {
9497 const mod = fg.dg.module;
9605 const o = fg.dg.object;
9606 const mod = o.module;
94989607 const payload_ty = opt_ty.optionalChild(mod);
94999608
95009609 if (isByRef(opt_ty, mod)) {
......@@ -9508,7 +9617,7 @@ pub const FuncGen = struct {
95089617
95099618 return fg.loadByRef(payload_ptr, payload_ty, payload_alignment, false);
95109619 }
9511 const payload_llvm_ty = try fg.dg.lowerType(payload_ty);
9620 const payload_llvm_ty = try o.lowerType(payload_ty);
95129621 const load_inst = fg.builder.buildLoad(payload_llvm_ty, payload_ptr, "");
95139622 load_inst.setAlignment(payload_alignment);
95149623 return load_inst;
......@@ -9524,9 +9633,10 @@ pub const FuncGen = struct {
95249633 payload: *llvm.Value,
95259634 non_null_bit: *llvm.Value,
95269635 ) !?*llvm.Value {
9527 const optional_llvm_ty = try self.dg.lowerType(optional_ty);
9636 const o = self.dg.object;
9637 const optional_llvm_ty = try o.lowerType(optional_ty);
95289638 const non_null_field = self.builder.buildZExt(non_null_bit, self.context.intType(8), "");
9529 const mod = self.dg.module;
9639 const mod = o.module;
95309640
95319641 if (isByRef(optional_ty, mod)) {
95329642 const payload_alignment = optional_ty.abiAlignment(mod);
......@@ -9557,7 +9667,8 @@ pub const FuncGen = struct {
95579667 struct_ptr_ty: Type,
95589668 field_index: u32,
95599669 ) !?*llvm.Value {
9560 const mod = self.dg.module;
9670 const o = self.dg.object;
9671 const mod = o.module;
95619672 const struct_ty = struct_ptr_ty.childType(mod);
95629673 switch (struct_ty.zigTypeTag(mod)) {
95639674 .Struct => switch (struct_ty.containerLayout(mod)) {
......@@ -9578,13 +9689,13 @@ pub const FuncGen = struct {
95789689 const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, mod);
95799690 if (byte_offset == 0) return struct_ptr;
95809691 const byte_llvm_ty = self.context.intType(8);
9581 const llvm_usize = try self.dg.lowerType(Type.usize);
9692 const llvm_usize = try o.lowerType(Type.usize);
95829693 const llvm_index = llvm_usize.constInt(byte_offset, .False);
95839694 const indices: [1]*llvm.Value = .{llvm_index};
95849695 return self.builder.buildInBoundsGEP(byte_llvm_ty, struct_ptr, &indices, indices.len, "");
95859696 },
95869697 else => {
9587 const struct_llvm_ty = try self.dg.lowerPtrElemTy(struct_ty);
9698 const struct_llvm_ty = try o.lowerPtrElemTy(struct_ty);
95889699
95899700 if (llvmField(struct_ty, field_index, mod)) |llvm_field| {
95909701 return self.builder.buildStructGEP(struct_llvm_ty, struct_ptr, llvm_field.index, "");
......@@ -9604,7 +9715,7 @@ pub const FuncGen = struct {
96049715 const layout = struct_ty.unionGetLayout(mod);
96059716 if (layout.payload_size == 0 or struct_ty.containerLayout(mod) == .Packed) return struct_ptr;
96069717 const payload_index = @intFromBool(layout.tag_align >= layout.payload_align);
9607 const union_llvm_ty = try self.dg.lowerType(struct_ty);
9718 const union_llvm_ty = try o.lowerType(struct_ty);
96089719 const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_ptr, payload_index, "");
96099720 return union_field_ptr;
96109721 },
......@@ -9612,10 +9723,11 @@ pub const FuncGen = struct {
96129723 }
96139724 }
96149725
9615 fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *llvm.Type) *llvm.Value {
9726 fn getIntrinsic(fg: *FuncGen, name: []const u8, types: []const *llvm.Type) *llvm.Value {
96169727 const id = llvm.lookupIntrinsicID(name.ptr, name.len);
96179728 assert(id != 0);
9618 return self.llvmModule().getIntrinsicDeclaration(id, types.ptr, types.len);
9729 const o = fg.dg.object;
9730 return o.llvm_module.getIntrinsicDeclaration(id, types.ptr, types.len);
96199731 }
96209732
96219733 /// Load a by-ref type by constructing a new alloca and performing a memcpy.
......@@ -9626,8 +9738,9 @@ pub const FuncGen = struct {
96269738 ptr_alignment: u32,
96279739 is_volatile: bool,
96289740 ) !*llvm.Value {
9629 const mod = fg.dg.module;
9630 const pointee_llvm_ty = try fg.dg.lowerType(pointee_type);
9741 const o = fg.dg.object;
9742 const mod = o.module;
9743 const pointee_llvm_ty = try o.lowerType(pointee_type);
96319744 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(mod));
96329745 const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align);
96339746 const llvm_usize = fg.context.intType(Type.usize.intInfo(mod).bits);
......@@ -9647,7 +9760,8 @@ pub const FuncGen = struct {
96479760 /// alloca and copies the value into it, then returns the alloca instruction.
96489761 /// For isByRef=false types, it creates a load instruction and returns it.
96499762 fn load(self: *FuncGen, ptr: *llvm.Value, ptr_ty: Type) !?*llvm.Value {
9650 const mod = self.dg.module;
9763 const o = self.dg.object;
9764 const mod = o.module;
96519765 const info = ptr_ty.ptrInfo(mod);
96529766 const elem_ty = info.child.toType();
96539767 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
......@@ -9659,7 +9773,7 @@ pub const FuncGen = struct {
96599773 assert(info.flags.vector_index != .runtime);
96609774 if (info.flags.vector_index != .none) {
96619775 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False);
9662 const vec_elem_ty = try self.dg.lowerType(elem_ty);
9776 const vec_elem_ty = try o.lowerType(elem_ty);
96639777 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);
96649778
96659779 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");
......@@ -9673,7 +9787,7 @@ pub const FuncGen = struct {
96739787 if (isByRef(elem_ty, mod)) {
96749788 return self.loadByRef(ptr, elem_ty, ptr_alignment, info.flags.is_volatile);
96759789 }
9676 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
9790 const elem_llvm_ty = try o.lowerType(elem_ty);
96779791 const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, "");
96789792 llvm_inst.setAlignment(ptr_alignment);
96799793 llvm_inst.setVolatile(ptr_volatile);
......@@ -9688,7 +9802,7 @@ pub const FuncGen = struct {
96889802 const elem_bits = @intCast(c_uint, ptr_ty.childType(mod).bitSize(mod));
96899803 const shift_amt = containing_int.typeOf().constInt(info.packed_offset.bit_offset, .False);
96909804 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");
9691 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
9805 const elem_llvm_ty = try o.lowerType(elem_ty);
96929806
96939807 if (isByRef(elem_ty, mod)) {
96949808 const result_align = elem_ty.abiAlignment(mod);
......@@ -9723,7 +9837,8 @@ pub const FuncGen = struct {
97239837 elem: *llvm.Value,
97249838 ordering: llvm.AtomicOrdering,
97259839 ) !void {
9726 const mod = self.dg.module;
9840 const o = self.dg.object;
9841 const mod = o.module;
97279842 const info = ptr_ty.ptrInfo(mod);
97289843 const elem_ty = info.child.toType();
97299844 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
......@@ -9735,7 +9850,7 @@ pub const FuncGen = struct {
97359850 assert(info.flags.vector_index != .runtime);
97369851 if (info.flags.vector_index != .none) {
97379852 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False);
9738 const vec_elem_ty = try self.dg.lowerType(elem_ty);
9853 const vec_elem_ty = try o.lowerType(elem_ty);
97399854 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);
97409855
97419856 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");
......@@ -9805,7 +9920,8 @@ pub const FuncGen = struct {
98059920
98069921 fn valgrindMarkUndef(fg: *FuncGen, ptr: *llvm.Value, len: *llvm.Value) void {
98079922 const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545;
9808 const target = fg.dg.module.getTarget();
9923 const o = fg.dg.object;
9924 const target = o.module.getTarget();
98099925 const usize_llvm_ty = fg.context.intType(target.ptrBitWidth());
98109926 const zero = usize_llvm_ty.constInt(0, .False);
98119927 const req = usize_llvm_ty.constInt(VG_USERREQ__MAKE_MEM_UNDEFINED, .False);
......@@ -9823,7 +9939,8 @@ pub const FuncGen = struct {
98239939 a4: *llvm.Value,
98249940 a5: *llvm.Value,
98259941 ) *llvm.Value {
9826 const mod = fg.dg.module;
9942 const o = fg.dg.object;
9943 const mod = o.module;
98279944 const target = mod.getTarget();
98289945 if (!target_util.hasValgrindSupport(target)) return default_value;
98299946
......@@ -9907,12 +10024,14 @@ pub const FuncGen = struct {
990710024 }
990810025
990910026 fn typeOf(fg: *FuncGen, inst: Air.Inst.Ref) Type {
9910 const mod = fg.dg.module;
10027 const o = fg.dg.object;
10028 const mod = o.module;
991110029 return fg.air.typeOf(inst, &mod.intern_pool);
991210030 }
991310031
991410032 fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type {
9915 const mod = fg.dg.module;
10033 const o = fg.dg.object;
10034 const mod = o.module;
991610035 return fg.air.typeOfIndex(inst, &mod.intern_pool);
991710036 }
991810037};
......@@ -10370,160 +10489,160 @@ fn firstParamSRetSystemV(ty: Type, mod: *Module) bool {
1037010489/// In order to support the C calling convention, some return types need to be lowered
1037110490/// completely differently in the function prototype to honor the C ABI, and then
1037210491/// be effectively bitcasted to the actual return type.
10373fn lowerFnRetTy(dg: *DeclGen, fn_info: InternPool.Key.FuncType) !*llvm.Type {
10374 const mod = dg.module;
10492fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type {
10493 const mod = o.module;
1037510494 const return_type = fn_info.return_type.toType();
1037610495 if (!return_type.hasRuntimeBitsIgnoreComptime(mod)) {
1037710496 // If the return type is an error set or an error union, then we make this
1037810497 // anyerror return type instead, so that it can be coerced into a function
1037910498 // pointer type which has anyerror as the return type.
1038010499 if (return_type.isError(mod)) {
10381 return dg.lowerType(Type.anyerror);
10500 return o.lowerType(Type.anyerror);
1038210501 } else {
10383 return dg.context.voidType();
10502 return o.context.voidType();
1038410503 }
1038510504 }
1038610505 const target = mod.getTarget();
1038710506 switch (fn_info.cc) {
1038810507 .Unspecified, .Inline => {
1038910508 if (isByRef(return_type, mod)) {
10390 return dg.context.voidType();
10509 return o.context.voidType();
1039110510 } else {
10392 return dg.lowerType(return_type);
10511 return o.lowerType(return_type);
1039310512 }
1039410513 },
1039510514 .C => {
1039610515 switch (target.cpu.arch) {
10397 .mips, .mipsel => return dg.lowerType(return_type),
10516 .mips, .mipsel => return o.lowerType(return_type),
1039810517 .x86_64 => switch (target.os.tag) {
10399 .windows => return lowerWin64FnRetTy(dg, fn_info),
10400 else => return lowerSystemVFnRetTy(dg, fn_info),
10518 .windows => return lowerWin64FnRetTy(o, fn_info),
10519 else => return lowerSystemVFnRetTy(o, fn_info),
1040110520 },
1040210521 .wasm32 => {
1040310522 if (isScalar(mod, return_type)) {
10404 return dg.lowerType(return_type);
10523 return o.lowerType(return_type);
1040510524 }
1040610525 const classes = wasm_c_abi.classifyType(return_type, mod);
1040710526 if (classes[0] == .indirect or classes[0] == .none) {
10408 return dg.context.voidType();
10527 return o.context.voidType();
1040910528 }
1041010529
1041110530 assert(classes[0] == .direct and classes[1] == .none);
1041210531 const scalar_type = wasm_c_abi.scalarType(return_type, mod);
1041310532 const abi_size = scalar_type.abiSize(mod);
10414 return dg.context.intType(@intCast(c_uint, abi_size * 8));
10533 return o.context.intType(@intCast(c_uint, abi_size * 8));
1041510534 },
1041610535 .aarch64, .aarch64_be => {
1041710536 switch (aarch64_c_abi.classifyType(return_type, mod)) {
10418 .memory => return dg.context.voidType(),
10419 .float_array => return dg.lowerType(return_type),
10420 .byval => return dg.lowerType(return_type),
10537 .memory => return o.context.voidType(),
10538 .float_array => return o.lowerType(return_type),
10539 .byval => return o.lowerType(return_type),
1042110540 .integer => {
1042210541 const bit_size = return_type.bitSize(mod);
10423 return dg.context.intType(@intCast(c_uint, bit_size));
10542 return o.context.intType(@intCast(c_uint, bit_size));
1042410543 },
10425 .double_integer => return dg.context.intType(64).arrayType(2),
10544 .double_integer => return o.context.intType(64).arrayType(2),
1042610545 }
1042710546 },
1042810547 .arm, .armeb => {
1042910548 switch (arm_c_abi.classifyType(return_type, mod, .ret)) {
10430 .memory, .i64_array => return dg.context.voidType(),
10549 .memory, .i64_array => return o.context.voidType(),
1043110550 .i32_array => |len| if (len == 1) {
10432 return dg.context.intType(32);
10551 return o.context.intType(32);
1043310552 } else {
10434 return dg.context.voidType();
10553 return o.context.voidType();
1043510554 },
10436 .byval => return dg.lowerType(return_type),
10555 .byval => return o.lowerType(return_type),
1043710556 }
1043810557 },
1043910558 .riscv32, .riscv64 => {
1044010559 switch (riscv_c_abi.classifyType(return_type, mod)) {
10441 .memory => return dg.context.voidType(),
10560 .memory => return o.context.voidType(),
1044210561 .integer => {
1044310562 const bit_size = return_type.bitSize(mod);
10444 return dg.context.intType(@intCast(c_uint, bit_size));
10563 return o.context.intType(@intCast(c_uint, bit_size));
1044510564 },
1044610565 .double_integer => {
1044710566 var llvm_types_buffer: [2]*llvm.Type = .{
10448 dg.context.intType(64),
10449 dg.context.intType(64),
10567 o.context.intType(64),
10568 o.context.intType(64),
1045010569 };
10451 return dg.context.structType(&llvm_types_buffer, 2, .False);
10570 return o.context.structType(&llvm_types_buffer, 2, .False);
1045210571 },
10453 .byval => return dg.lowerType(return_type),
10572 .byval => return o.lowerType(return_type),
1045410573 }
1045510574 },
1045610575 // TODO investigate C ABI for other architectures
10457 else => return dg.lowerType(return_type),
10576 else => return o.lowerType(return_type),
1045810577 }
1045910578 },
10460 .Win64 => return lowerWin64FnRetTy(dg, fn_info),
10461 .SysV => return lowerSystemVFnRetTy(dg, fn_info),
10579 .Win64 => return lowerWin64FnRetTy(o, fn_info),
10580 .SysV => return lowerSystemVFnRetTy(o, fn_info),
1046210581 .Stdcall => {
1046310582 if (isScalar(mod, return_type)) {
10464 return dg.lowerType(return_type);
10583 return o.lowerType(return_type);
1046510584 } else {
10466 return dg.context.voidType();
10585 return o.context.voidType();
1046710586 }
1046810587 },
10469 else => return dg.lowerType(return_type),
10588 else => return o.lowerType(return_type),
1047010589 }
1047110590}
1047210591
10473fn lowerWin64FnRetTy(dg: *DeclGen, fn_info: InternPool.Key.FuncType) !*llvm.Type {
10474 const mod = dg.module;
10592fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type {
10593 const mod = o.module;
1047510594 const return_type = fn_info.return_type.toType();
1047610595 switch (x86_64_abi.classifyWindows(return_type, mod)) {
1047710596 .integer => {
1047810597 if (isScalar(mod, return_type)) {
10479 return dg.lowerType(return_type);
10598 return o.lowerType(return_type);
1048010599 } else {
1048110600 const abi_size = return_type.abiSize(mod);
10482 return dg.context.intType(@intCast(c_uint, abi_size * 8));
10601 return o.context.intType(@intCast(c_uint, abi_size * 8));
1048310602 }
1048410603 },
10485 .win_i128 => return dg.context.intType(64).vectorType(2),
10486 .memory => return dg.context.voidType(),
10487 .sse => return dg.lowerType(return_type),
10604 .win_i128 => return o.context.intType(64).vectorType(2),
10605 .memory => return o.context.voidType(),
10606 .sse => return o.lowerType(return_type),
1048810607 else => unreachable,
1048910608 }
1049010609}
1049110610
10492fn lowerSystemVFnRetTy(dg: *DeclGen, fn_info: InternPool.Key.FuncType) !*llvm.Type {
10493 const mod = dg.module;
10611fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type {
10612 const mod = o.module;
1049410613 const return_type = fn_info.return_type.toType();
1049510614 if (isScalar(mod, return_type)) {
10496 return dg.lowerType(return_type);
10615 return o.lowerType(return_type);
1049710616 }
1049810617 const classes = x86_64_abi.classifySystemV(return_type, mod, .ret);
1049910618 if (classes[0] == .memory) {
10500 return dg.context.voidType();
10619 return o.context.voidType();
1050110620 }
1050210621 var llvm_types_buffer: [8]*llvm.Type = undefined;
1050310622 var llvm_types_index: u32 = 0;
1050410623 for (classes) |class| {
1050510624 switch (class) {
1050610625 .integer => {
10507 llvm_types_buffer[llvm_types_index] = dg.context.intType(64);
10626 llvm_types_buffer[llvm_types_index] = o.context.intType(64);
1050810627 llvm_types_index += 1;
1050910628 },
1051010629 .sse, .sseup => {
10511 llvm_types_buffer[llvm_types_index] = dg.context.doubleType();
10630 llvm_types_buffer[llvm_types_index] = o.context.doubleType();
1051210631 llvm_types_index += 1;
1051310632 },
1051410633 .float => {
10515 llvm_types_buffer[llvm_types_index] = dg.context.floatType();
10634 llvm_types_buffer[llvm_types_index] = o.context.floatType();
1051610635 llvm_types_index += 1;
1051710636 },
1051810637 .float_combine => {
10519 llvm_types_buffer[llvm_types_index] = dg.context.floatType().vectorType(2);
10638 llvm_types_buffer[llvm_types_index] = o.context.floatType().vectorType(2);
1052010639 llvm_types_index += 1;
1052110640 },
1052210641 .x87 => {
1052310642 if (llvm_types_index != 0 or classes[2] != .none) {
10524 return dg.context.voidType();
10643 return o.context.voidType();
1052510644 }
10526 llvm_types_buffer[llvm_types_index] = dg.context.x86FP80Type();
10645 llvm_types_buffer[llvm_types_index] = o.context.x86FP80Type();
1052710646 llvm_types_index += 1;
1052810647 },
1052910648 .x87up => continue,
......@@ -10537,13 +10656,13 @@ fn lowerSystemVFnRetTy(dg: *DeclGen, fn_info: InternPool.Key.FuncType) !*llvm.Ty
1053710656 }
1053810657 if (classes[0] == .integer and classes[1] == .none) {
1053910658 const abi_size = return_type.abiSize(mod);
10540 return dg.context.intType(@intCast(c_uint, abi_size * 8));
10659 return o.context.intType(@intCast(c_uint, abi_size * 8));
1054110660 }
10542 return dg.context.structType(&llvm_types_buffer, llvm_types_index, .False);
10661 return o.context.structType(&llvm_types_buffer, llvm_types_index, .False);
1054310662}
1054410663
1054510664const ParamTypeIterator = struct {
10546 dg: *DeclGen,
10665 object: *Object,
1054710666 fn_info: InternPool.Key.FuncType,
1054810667 zig_index: u32,
1054910668 llvm_index: u32,
......@@ -10586,7 +10705,7 @@ const ParamTypeIterator = struct {
1058610705 }
1058710706
1058810707 fn nextInner(it: *ParamTypeIterator, ty: Type) ?Lowering {
10589 const mod = it.dg.module;
10708 const mod = it.object.module;
1059010709 const target = mod.getTarget();
1059110710
1059210711 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) {
......@@ -10641,7 +10760,7 @@ const ParamTypeIterator = struct {
1064110760 .byval => return .byval,
1064210761 .integer => {
1064310762 it.llvm_types_len = 1;
10644 it.llvm_types_buffer[0] = it.dg.context.intType(64);
10763 it.llvm_types_buffer[0] = it.object.context.intType(64);
1064510764 return .multiple_llvm_types;
1064610765 },
1064710766 .double_integer => return Lowering{ .i64_array = 2 },
......@@ -10703,7 +10822,7 @@ const ParamTypeIterator = struct {
1070310822 }
1070410823
1070510824 fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering {
10706 const mod = it.dg.module;
10825 const mod = it.object.module;
1070710826 switch (x86_64_abi.classifyWindows(ty, mod)) {
1070810827 .integer => {
1070910828 if (isScalar(mod, ty)) {
......@@ -10736,7 +10855,7 @@ const ParamTypeIterator = struct {
1073610855 }
1073710856
1073810857 fn nextSystemV(it: *ParamTypeIterator, ty: Type) ?Lowering {
10739 const mod = it.dg.module;
10858 const mod = it.object.module;
1074010859 const classes = x86_64_abi.classifySystemV(ty, mod, .arg);
1074110860 if (classes[0] == .memory) {
1074210861 it.zig_index += 1;
......@@ -10754,19 +10873,19 @@ const ParamTypeIterator = struct {
1075410873 for (classes) |class| {
1075510874 switch (class) {
1075610875 .integer => {
10757 llvm_types_buffer[llvm_types_index] = it.dg.context.intType(64);
10876 llvm_types_buffer[llvm_types_index] = it.object.context.intType(64);
1075810877 llvm_types_index += 1;
1075910878 },
1076010879 .sse, .sseup => {
10761 llvm_types_buffer[llvm_types_index] = it.dg.context.doubleType();
10880 llvm_types_buffer[llvm_types_index] = it.object.context.doubleType();
1076210881 llvm_types_index += 1;
1076310882 },
1076410883 .float => {
10765 llvm_types_buffer[llvm_types_index] = it.dg.context.floatType();
10884 llvm_types_buffer[llvm_types_index] = it.object.context.floatType();
1076610885 llvm_types_index += 1;
1076710886 },
1076810887 .float_combine => {
10769 llvm_types_buffer[llvm_types_index] = it.dg.context.floatType().vectorType(2);
10888 llvm_types_buffer[llvm_types_index] = it.object.context.floatType().vectorType(2);
1077010889 llvm_types_index += 1;
1077110890 },
1077210891 .x87 => {
......@@ -10797,9 +10916,9 @@ const ParamTypeIterator = struct {
1079710916 }
1079810917};
1079910918
10800fn iterateParamTypes(dg: *DeclGen, fn_info: InternPool.Key.FuncType) ParamTypeIterator {
10919fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) ParamTypeIterator {
1080110920 return .{
10802 .dg = dg,
10921 .object = object,
1080310922 .fn_info = fn_info,
1080410923 .zig_index = 0,
1080510924 .llvm_index = 0,
......@@ -11055,8 +11174,8 @@ const lt_errors_fn_name = "__zig_lt_errors_len";
1105511174
1105611175/// Without this workaround, LLVM crashes with "unknown codeview register H1"
1105711176/// https://github.com/llvm/llvm-project/issues/56484
11058fn needDbgVarWorkaround(dg: *DeclGen) bool {
11059 const target = dg.module.getTarget();
11177fn needDbgVarWorkaround(o: *Object) bool {
11178 const target = o.module.getTarget();
1106011179 if (target.os.tag == .windows and target.cpu.arch == .aarch64) {
1106111180 return true;
1106211181 }