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 {...@@ -568,20 +568,20 @@ pub const Object = struct {
568 return slice.ptr;568 return slice.ptr;
569 }569 }
570570
571 fn genErrorNameTable(self: *Object) !void {571 fn genErrorNameTable(o: *Object) !void {
572 // If self.error_name_table is null, there was no instruction that actually referenced the error table.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 = self.error_name_table orelse return;573 const error_name_table_ptr_global = o.error_name_table orelse return;
574574
575 const mod = self.module;575 const mod = o.module;
576 const target = mod.getTarget();576 const target = mod.getTarget();
577577
578 const llvm_ptr_ty = self.context.pointerType(0); // TODO: Address space578 const llvm_ptr_ty = o.context.pointerType(0); // TODO: Address space
579 const llvm_usize_ty = self.context.intType(target.ptrBitWidth());579 const llvm_usize_ty = o.context.intType(target.ptrBitWidth());
580 const type_fields = [_]*llvm.Type{580 const type_fields = [_]*llvm.Type{
581 llvm_ptr_ty,581 llvm_ptr_ty,
582 llvm_usize_ty,582 llvm_usize_ty,
583 };583 };
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);
585 const slice_ty = Type.slice_const_u8_sentinel_0;585 const slice_ty = Type.slice_const_u8_sentinel_0;
586 const slice_alignment = slice_ty.abiAlignment(mod);586 const slice_alignment = slice_ty.abiAlignment(mod);
587587
...@@ -592,8 +592,8 @@ pub const Object = struct {...@@ -592,8 +592,8 @@ pub const Object = struct {
592 llvm_errors[0] = llvm_slice_ty.getUndef();592 llvm_errors[0] = llvm_slice_ty.getUndef();
593 for (llvm_errors[1..], error_name_list[1..]) |*llvm_error, name_nts| {593 for (llvm_errors[1..], error_name_list[1..]) |*llvm_error, name_nts| {
594 const name = mod.intern_pool.stringToSlice(name_nts);594 const name = mod.intern_pool.stringToSlice(name_nts);
595 const str_init = self.context.constString(name.ptr, @intCast(c_uint, name.len), .False);595 const str_init = o.context.constString(name.ptr, @intCast(c_uint, name.len), .False);
596 const str_global = self.llvm_module.addGlobal(str_init.typeOf(), "");596 const str_global = o.llvm_module.addGlobal(str_init.typeOf(), "");
597 str_global.setInitializer(str_init);597 str_global.setInitializer(str_init);
598 str_global.setLinkage(.Private);598 str_global.setLinkage(.Private);
599 str_global.setGlobalConstant(.True);599 str_global.setGlobalConstant(.True);
...@@ -609,7 +609,7 @@ pub const Object = struct {...@@ -609,7 +609,7 @@ pub const Object = struct {
609609
610 const error_name_table_init = llvm_slice_ty.constArray(llvm_errors.ptr, @intCast(c_uint, error_name_list.len));610 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(), "");
613 error_name_table_global.setInitializer(error_name_table_init);613 error_name_table_global.setInitializer(error_name_table_init);
614 error_name_table_global.setLinkage(.Private);614 error_name_table_global.setLinkage(.Private);
615 error_name_table_global.setGlobalConstant(.True);615 error_name_table_global.setGlobalConstant(.True);
...@@ -873,35 +873,32 @@ pub const Object = struct {...@@ -873,35 +873,32 @@ pub const Object = struct {
873 const target = mod.getTarget();873 const target = mod.getTarget();
874874
875 var dg: DeclGen = .{875 var dg: DeclGen = .{
876 .context = o.context,
877 .object = o,876 .object = o,
878 .module = mod,
879 .decl_index = decl_index,877 .decl_index = decl_index,
880 .decl = decl,878 .decl = decl,
881 .err_msg = null,879 .err_msg = null,
882 .gpa = mod.gpa,
883 };880 };
884881
885 const llvm_func = try dg.resolveLlvmFunction(decl_index);882 const llvm_func = try o.resolveLlvmFunction(decl_index);
886883
887 if (mod.align_stack_fns.get(func_index)) |align_info| {884 if (mod.align_stack_fns.get(func_index)) |align_info| {
888 dg.addFnAttrInt(llvm_func, "alignstack", align_info.alignment.toByteUnitsOptional().?);885 o.addFnAttrInt(llvm_func, "alignstack", align_info.alignment.toByteUnitsOptional().?);
889 dg.addFnAttr(llvm_func, "noinline");886 o.addFnAttr(llvm_func, "noinline");
890 } else {887 } else {
891 DeclGen.removeFnAttr(llvm_func, "alignstack");888 Object.removeFnAttr(llvm_func, "alignstack");
892 if (!func.is_noinline) DeclGen.removeFnAttr(llvm_func, "noinline");889 if (!func.is_noinline) Object.removeFnAttr(llvm_func, "noinline");
893 }890 }
894891
895 if (func.is_cold) {892 if (func.is_cold) {
896 dg.addFnAttr(llvm_func, "cold");893 o.addFnAttr(llvm_func, "cold");
897 } else {894 } else {
898 DeclGen.removeFnAttr(llvm_func, "cold");895 Object.removeFnAttr(llvm_func, "cold");
899 }896 }
900897
901 if (func.is_noinline) {898 if (func.is_noinline) {
902 dg.addFnAttr(llvm_func, "noinline");899 o.addFnAttr(llvm_func, "noinline");
903 } else {900 } else {
904 DeclGen.removeFnAttr(llvm_func, "noinline");901 Object.removeFnAttr(llvm_func, "noinline");
905 }902 }
906903
907 // TODO: disable this if safety is off for the function scope904 // TODO: disable this if safety is off for the function scope
...@@ -909,15 +906,15 @@ pub const Object = struct {...@@ -909,15 +906,15 @@ pub const Object = struct {
909 if (ssp_buf_size != 0) {906 if (ssp_buf_size != 0) {
910 var buf: [12]u8 = undefined;907 var buf: [12]u8 = undefined;
911 const arg = std.fmt.bufPrintZ(&buf, "{d}", .{ssp_buf_size}) catch unreachable;908 const arg = std.fmt.bufPrintZ(&buf, "{d}", .{ssp_buf_size}) catch unreachable;
912 dg.addFnAttr(llvm_func, "sspstrong");909 o.addFnAttr(llvm_func, "sspstrong");
913 dg.addFnAttrString(llvm_func, "stack-protector-buffer-size", arg);910 o.addFnAttrString(llvm_func, "stack-protector-buffer-size", arg);
914 }911 }
915912
916 // TODO: disable this if safety is off for the function scope913 // TODO: disable this if safety is off for the function scope
917 if (mod.comp.bin_file.options.stack_check) {914 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");
919 } else if (target.os.tag == .uefi) {916 } else if (target.os.tag == .uefi) {
920 dg.addFnAttrString(llvm_func, "no-stack-arg-probe", "");917 o.addFnAttrString(llvm_func, "no-stack-arg-probe", "");
921 }918 }
922919
923 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |section|920 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |section|
...@@ -929,20 +926,20 @@ pub const Object = struct {...@@ -929,20 +926,20 @@ pub const Object = struct {
929 bb.deleteBasicBlock();926 bb.deleteBasicBlock();
930 }927 }
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");
935 builder.positionBuilderAtEnd(entry_block);932 builder.positionBuilderAtEnd(entry_block);
936933
937 // This gets the LLVM values from the function and stores them in `dg.args`.934 // This gets the LLVM values from the function and stores them in `dg.args`.
938 const fn_info = mod.typeToFunc(decl.ty).?;935 const fn_info = mod.typeToFunc(decl.ty).?;
939 const sret = firstParamSRet(fn_info, mod);936 const sret = firstParamSRet(fn_info, mod);
940 const ret_ptr = if (sret) llvm_func.getParam(0) else null;937 const ret_ptr = if (sret) llvm_func.getParam(0) else null;
941 const gpa = dg.gpa;938 const gpa = o.gpa;
942939
943 if (ccAbiPromoteInt(fn_info.cc, mod, fn_info.return_type.toType())) |s| switch (s) {940 if (ccAbiPromoteInt(fn_info.cc, mod, fn_info.return_type.toType())) |s| switch (s) {
944 .signed => dg.addAttr(llvm_func, 0, "signext"),941 .signed => o.addAttr(llvm_func, 0, "signext"),
945 .unsigned => dg.addAttr(llvm_func, 0, "zeroext"),942 .unsigned => o.addAttr(llvm_func, 0, "zeroext"),
946 };943 };
947944
948 const err_return_tracing = fn_info.return_type.toType().isError(mod) and945 const err_return_tracing = fn_info.return_type.toType().isError(mod) and
...@@ -961,7 +958,7 @@ pub const Object = struct {...@@ -961,7 +958,7 @@ pub const Object = struct {
961958
962 {959 {
963 var llvm_arg_i = @as(c_uint, @intFromBool(ret_ptr != null)) + @intFromBool(err_return_tracing);960 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);
965 while (it.next()) |lowering| switch (lowering) {962 while (it.next()) |lowering| switch (lowering) {
966 .no_bits => continue,963 .no_bits => continue,
967 .byval => {964 .byval => {
...@@ -974,24 +971,24 @@ pub const Object = struct {...@@ -974,24 +971,24 @@ pub const Object = struct {
974 if (isByRef(param_ty, mod)) {971 if (isByRef(param_ty, mod)) {
975 const alignment = param_ty.abiAlignment(mod);972 const alignment = param_ty.abiAlignment(mod);
976 const param_llvm_ty = param.typeOf();973 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);
978 const store_inst = builder.buildStore(param, arg_ptr);975 const store_inst = builder.buildStore(param, arg_ptr);
979 store_inst.setAlignment(alignment);976 store_inst.setAlignment(alignment);
980 args.appendAssumeCapacity(arg_ptr);977 args.appendAssumeCapacity(arg_ptr);
981 } else {978 } else {
982 args.appendAssumeCapacity(param);979 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);
985 }982 }
986 llvm_arg_i += 1;983 llvm_arg_i += 1;
987 },984 },
988 .byref => {985 .byref => {
989 const param_ty = fn_info.param_types[it.zig_index - 1].toType();986 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);
991 const param = llvm_func.getParam(llvm_arg_i);988 const param = llvm_func.getParam(llvm_arg_i);
992 const alignment = param_ty.abiAlignment(mod);989 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);
995 llvm_arg_i += 1;992 llvm_arg_i += 1;
996993
997 try args.ensureUnusedCapacity(1);994 try args.ensureUnusedCapacity(1);
...@@ -1006,11 +1003,11 @@ pub const Object = struct {...@@ -1006,11 +1003,11 @@ pub const Object = struct {
1006 },1003 },
1007 .byref_mut => {1004 .byref_mut => {
1008 const param_ty = fn_info.param_types[it.zig_index - 1].toType();1005 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);
1010 const param = llvm_func.getParam(llvm_arg_i);1007 const param = llvm_func.getParam(llvm_arg_i);
1011 const alignment = param_ty.abiAlignment(mod);1008 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");
1014 llvm_arg_i += 1;1011 llvm_arg_i += 1;
10151012
1016 try args.ensureUnusedCapacity(1);1013 try args.ensureUnusedCapacity(1);
...@@ -1029,14 +1026,14 @@ pub const Object = struct {...@@ -1029,14 +1026,14 @@ pub const Object = struct {
1029 const param = llvm_func.getParam(llvm_arg_i);1026 const param = llvm_func.getParam(llvm_arg_i);
1030 llvm_arg_i += 1;1027 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);
1033 const abi_size = @intCast(c_uint, param_ty.abiSize(mod));1030 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);
1035 const alignment = @max(1032 const alignment = @max(
1036 param_ty.abiAlignment(mod),1033 param_ty.abiAlignment(mod),
1037 dg.object.target_data.abiAlignmentOfType(int_llvm_ty),1034 o.target_data.abiAlignmentOfType(int_llvm_ty),
1038 );1035 );
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);
1040 const store_inst = builder.buildStore(param, arg_ptr);1037 const store_inst = builder.buildStore(param, arg_ptr);
1041 store_inst.setAlignment(alignment);1038 store_inst.setAlignment(alignment);
10421039
...@@ -1057,24 +1054,24 @@ pub const Object = struct {...@@ -1057,24 +1054,24 @@ pub const Object = struct {
10571054
1058 if (math.cast(u5, it.zig_index - 1)) |i| {1055 if (math.cast(u5, it.zig_index - 1)) |i| {
1059 if (@truncate(u1, fn_info.noalias_bits >> i) != 0) {1056 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");
1061 }1058 }
1062 }1059 }
1063 if (param_ty.zigTypeTag(mod) != .Optional) {1060 if (param_ty.zigTypeTag(mod) != .Optional) {
1064 dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull");1061 o.addArgAttr(llvm_func, llvm_arg_i, "nonnull");
1065 }1062 }
1066 if (ptr_info.flags.is_const) {1063 if (ptr_info.flags.is_const) {
1067 dg.addArgAttr(llvm_func, llvm_arg_i, "readonly");1064 o.addArgAttr(llvm_func, llvm_arg_i, "readonly");
1068 }1065 }
1069 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse1066 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse
1070 @max(ptr_info.child.toType().abiAlignment(mod), 1);1067 @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);
1072 const ptr_param = llvm_func.getParam(llvm_arg_i);1069 const ptr_param = llvm_func.getParam(llvm_arg_i);
1073 llvm_arg_i += 1;1070 llvm_arg_i += 1;
1074 const len_param = llvm_func.getParam(llvm_arg_i);1071 const len_param = llvm_func.getParam(llvm_arg_i);
1075 llvm_arg_i += 1;1072 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);
1078 const partial = builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr_param, 0, "");1075 const partial = builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr_param, 0, "");
1079 const aggregate = builder.buildInsertValue(partial, len_param, 1, "");1076 const aggregate = builder.buildInsertValue(partial, len_param, 1, "");
1080 try args.append(aggregate);1077 try args.append(aggregate);
...@@ -1083,10 +1080,10 @@ pub const Object = struct {...@@ -1083,10 +1080,10 @@ pub const Object = struct {
1083 assert(!it.byval_attr);1080 assert(!it.byval_attr);
1084 const field_types = it.llvm_types_buffer[0..it.llvm_types_len];1081 const field_types = it.llvm_types_buffer[0..it.llvm_types_len];
1085 const param_ty = fn_info.param_types[it.zig_index - 1].toType();1082 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);
1087 const param_alignment = param_ty.abiAlignment(mod);1084 const param_alignment = param_ty.abiAlignment(mod);
1088 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, param_alignment, target);1085 const arg_ptr = buildAllocaInner(o.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);1086 const llvm_ty = o.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
1090 for (field_types, 0..) |_, field_i_usize| {1087 for (field_types, 0..) |_, field_i_usize| {
1091 const field_i = @intCast(c_uint, field_i_usize);1088 const field_i = @intCast(c_uint, field_i_usize);
1092 const param = llvm_func.getParam(llvm_arg_i);1089 const param = llvm_func.getParam(llvm_arg_i);
...@@ -1108,18 +1105,18 @@ pub const Object = struct {...@@ -1108,18 +1105,18 @@ pub const Object = struct {
1108 assert(!it.byval_attr);1105 assert(!it.byval_attr);
1109 const param = llvm_func.getParam(llvm_arg_i);1106 const param = llvm_func.getParam(llvm_arg_i);
1110 llvm_arg_i += 1;1107 llvm_arg_i += 1;
1111 const casted = builder.buildBitCast(param, dg.context.halfType(), "");1108 const casted = builder.buildBitCast(param, o.context.halfType(), "");
1112 try args.ensureUnusedCapacity(1);1109 try args.ensureUnusedCapacity(1);
1113 args.appendAssumeCapacity(casted);1110 args.appendAssumeCapacity(casted);
1114 },1111 },
1115 .float_array => {1112 .float_array => {
1116 const param_ty = fn_info.param_types[it.zig_index - 1].toType();1113 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);
1118 const param = llvm_func.getParam(llvm_arg_i);1115 const param = llvm_func.getParam(llvm_arg_i);
1119 llvm_arg_i += 1;1116 llvm_arg_i += 1;
11201117
1121 const alignment = param_ty.abiAlignment(mod);1118 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);
1123 _ = builder.buildStore(param, arg_ptr);1120 _ = builder.buildStore(param, arg_ptr);
11241121
1125 if (isByRef(param_ty, mod)) {1122 if (isByRef(param_ty, mod)) {
...@@ -1132,12 +1129,12 @@ pub const Object = struct {...@@ -1132,12 +1129,12 @@ pub const Object = struct {
1132 },1129 },
1133 .i32_array, .i64_array => {1130 .i32_array, .i64_array => {
1134 const param_ty = fn_info.param_types[it.zig_index - 1].toType();1131 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);
1136 const param = llvm_func.getParam(llvm_arg_i);1133 const param = llvm_func.getParam(llvm_arg_i);
1137 llvm_arg_i += 1;1134 llvm_arg_i += 1;
11381135
1139 const alignment = param_ty.abiAlignment(mod);1136 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);
1141 _ = builder.buildStore(param, arg_ptr);1138 _ = builder.buildStore(param, arg_ptr);
11421139
1143 if (isByRef(param_ty, mod)) {1140 if (isByRef(param_ty, mod)) {
...@@ -1154,8 +1151,8 @@ pub const Object = struct {...@@ -1154,8 +1151,8 @@ pub const Object = struct {
1154 var di_file: ?*llvm.DIFile = null;1151 var di_file: ?*llvm.DIFile = null;
1155 var di_scope: ?*llvm.DIScope = null;1152 var di_scope: ?*llvm.DIScope = null;
11561153
1157 if (dg.object.di_builder) |dib| {1154 if (o.di_builder) |dib| {
1158 di_file = try dg.object.getDIFile(gpa, mod.namespacePtr(decl.src_namespace).file_scope);1155 di_file = try o.getDIFile(gpa, mod.namespacePtr(decl.src_namespace).file_scope);
11591156
1160 const line_number = decl.src_line + 1;1157 const line_number = decl.src_line + 1;
1161 const is_internal_linkage = decl.val.getExternFunc(mod) == null and1158 const is_internal_linkage = decl.val.getExternFunc(mod) == null and
...@@ -1179,7 +1176,7 @@ pub const Object = struct {...@@ -1179,7 +1176,7 @@ pub const Object = struct {
1179 mod.comp.bin_file.options.optimize_mode != .Debug,1176 mod.comp.bin_file.options.optimize_mode != .Debug,
1180 null, // decl_subprogram1177 null, // decl_subprogram
1181 );1178 );
1182 try dg.object.di_map.put(gpa, decl, subprogram.toNode());1179 try o.di_map.put(gpa, decl, subprogram.toNode());
11831180
1184 llvm_func.fnSetSubprogram(subprogram);1181 llvm_func.fnSetSubprogram(subprogram);
11851182
...@@ -1190,7 +1187,7 @@ pub const Object = struct {...@@ -1190,7 +1187,7 @@ pub const Object = struct {
1190 .gpa = gpa,1187 .gpa = gpa,
1191 .air = air,1188 .air = air,
1192 .liveness = liveness,1189 .liveness = liveness,
1193 .context = dg.context,1190 .context = o.context,
1194 .dg = &dg,1191 .dg = &dg,
1195 .builder = builder,1192 .builder = builder,
1196 .ret_ptr = ret_ptr,1193 .ret_ptr = ret_ptr,
...@@ -1225,13 +1222,10 @@ pub const Object = struct {...@@ -1225,13 +1222,10 @@ pub const Object = struct {
1225 pub fn updateDecl(self: *Object, module: *Module, decl_index: Module.Decl.Index) !void {1222 pub fn updateDecl(self: *Object, module: *Module, decl_index: Module.Decl.Index) !void {
1226 const decl = module.declPtr(decl_index);1223 const decl = module.declPtr(decl_index);
1227 var dg: DeclGen = .{1224 var dg: DeclGen = .{
1228 .context = self.context,
1229 .object = self,1225 .object = self,
1230 .module = module,
1231 .decl = decl,1226 .decl = decl,
1232 .decl_index = decl_index,1227 .decl_index = decl_index,
1233 .err_msg = null,1228 .err_msg = null,
1234 .gpa = module.gpa,
1235 };1229 };
1236 dg.genDecl() catch |err| switch (err) {1230 dg.genDecl() catch |err| switch (err) {
1237 error.CodegenFail => {1231 error.CodegenFail => {
...@@ -2421,117 +2415,16 @@ pub const Object = struct {...@@ -2421,117 +2415,16 @@ pub const Object = struct {
2421 try ty.print(buffer.writer(), o.module);2415 try ty.print(buffer.writer(), o.module);
2422 return buffer.toOwnedSliceSentinel(0);2416 return buffer.toOwnedSliceSentinel(0);
2423 }2417 }
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
2527 /// If the llvm function does not exist, create it.2419 /// If the llvm function does not exist, create it.
2528 /// Note that this can be called before the function's semantic analysis has2420 /// Note that this can be called before the function's semantic analysis has
2529 /// completed, so if any attributes rely on that, they must be done in updateFunc, not here.2421 /// 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 {2422 fn resolveLlvmFunction(o: *Object, decl_index: Module.Decl.Index) !*llvm.Value {
2531 const mod = dg.module;2423 const mod = o.module;
2424 const gpa = o.gpa;
2532 const decl = mod.declPtr(decl_index);2425 const decl = mod.declPtr(decl_index);
2533 const zig_fn_type = decl.ty;2426 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);
2535 if (gop.found_existing) return gop.value_ptr.*;2428 if (gop.found_existing) return gop.value_ptr.*;
25362429
2537 assert(decl.has_tv);2430 assert(decl.has_tv);
...@@ -2539,12 +2432,12 @@ pub const DeclGen = struct {...@@ -2539,12 +2432,12 @@ pub const DeclGen = struct {
2539 const target = mod.getTarget();2432 const target = mod.getTarget();
2540 const sret = firstParamSRet(fn_info, mod);2433 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
2544 const fqn = try decl.getFullyQualifiedName(mod);2437 const fqn = try decl.getFullyQualifiedName(mod);
25452438
2546 const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);2439 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);
2548 gop.value_ptr.* = llvm_fn;2441 gop.value_ptr.* = llvm_fn;
25492442
2550 const is_extern = decl.isExtern(mod);2443 const is_extern = decl.isExtern(mod);
...@@ -2553,20 +2446,20 @@ pub const DeclGen = struct {...@@ -2553,20 +2446,20 @@ pub const DeclGen = struct {
2553 llvm_fn.setUnnamedAddr(.True);2446 llvm_fn.setUnnamedAddr(.True);
2554 } else {2447 } else {
2555 if (target.isWasm()) {2448 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));
2557 if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {2450 if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {
2558 if (!std.mem.eql(u8, lib_name, "c")) {2451 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);
2560 }2453 }
2561 }2454 }
2562 }2455 }
2563 }2456 }
25642457
2565 if (sret) {2458 if (sret) {
2566 dg.addArgAttr(llvm_fn, 0, "nonnull"); // Sret pointers must not be address 02459 o.addArgAttr(llvm_fn, 0, "nonnull"); // Sret pointers must not be address 0
2567 dg.addArgAttr(llvm_fn, 0, "noalias");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());
2570 llvm_fn.addSretAttr(raw_llvm_ret_ty);2463 llvm_fn.addSretAttr(raw_llvm_ret_ty);
2571 }2464 }
25722465
...@@ -2574,7 +2467,7 @@ pub const DeclGen = struct {...@@ -2574,7 +2467,7 @@ pub const DeclGen = struct {
2574 mod.comp.bin_file.options.error_return_tracing;2467 mod.comp.bin_file.options.error_return_tracing;
25752468
2576 if (err_return_tracing) {2469 if (err_return_tracing) {
2577 dg.addArgAttr(llvm_fn, @intFromBool(sret), "nonnull");2470 o.addArgAttr(llvm_fn, @intFromBool(sret), "nonnull");
2578 }2471 }
25792472
2580 switch (fn_info.cc) {2473 switch (fn_info.cc) {
...@@ -2582,7 +2475,7 @@ pub const DeclGen = struct {...@@ -2582,7 +2475,7 @@ pub const DeclGen = struct {
2582 llvm_fn.setFunctionCallConv(.Fast);2475 llvm_fn.setFunctionCallConv(.Fast);
2583 },2476 },
2584 .Naked => {2477 .Naked => {
2585 dg.addFnAttr(llvm_fn, "naked");2478 o.addFnAttr(llvm_fn, "naked");
2586 },2479 },
2587 .Async => {2480 .Async => {
2588 llvm_fn.setFunctionCallConv(.Fast);2481 llvm_fn.setFunctionCallConv(.Fast);
...@@ -2598,16 +2491,16 @@ pub const DeclGen = struct {...@@ -2598,16 +2491,16 @@ pub const DeclGen = struct {
2598 }2491 }
25992492
2600 // Function attributes that are independent of analysis results of the function body.2493 // Function attributes that are independent of analysis results of the function body.
2601 dg.addCommonFnAttributes(llvm_fn);2494 o.addCommonFnAttributes(llvm_fn);
26022495
2603 if (fn_info.return_type == .noreturn_type) {2496 if (fn_info.return_type == .noreturn_type) {
2604 dg.addFnAttr(llvm_fn, "noreturn");2497 o.addFnAttr(llvm_fn, "noreturn");
2605 }2498 }
26062499
2607 // Add parameter attributes. We handle only the case of extern functions (no body)2500 // Add parameter attributes. We handle only the case of extern functions (no body)
2608 // because functions with bodies are handled in `updateFunc`.2501 // because functions with bodies are handled in `updateFunc`.
2609 if (is_extern) {2502 if (is_extern) {
2610 var it = iterateParamTypes(dg, fn_info);2503 var it = iterateParamTypes(o, fn_info);
2611 it.llvm_index += @intFromBool(sret);2504 it.llvm_index += @intFromBool(sret);
2612 it.llvm_index += @intFromBool(err_return_tracing);2505 it.llvm_index += @intFromBool(err_return_tracing);
2613 while (it.next()) |lowering| switch (lowering) {2506 while (it.next()) |lowering| switch (lowering) {
...@@ -2615,17 +2508,17 @@ pub const DeclGen = struct {...@@ -2615,17 +2508,17 @@ pub const DeclGen = struct {
2615 const param_index = it.zig_index - 1;2508 const param_index = it.zig_index - 1;
2616 const param_ty = fn_info.param_types[param_index].toType();2509 const param_ty = fn_info.param_types[param_index].toType();
2617 if (!isByRef(param_ty, mod)) {2510 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);
2619 }2512 }
2620 },2513 },
2621 .byref => {2514 .byref => {
2622 const param_ty = fn_info.param_types[it.zig_index - 1];2515 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());
2624 const alignment = param_ty.toType().abiAlignment(mod);2517 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);
2626 },2519 },
2627 .byref_mut => {2520 .byref_mut => {
2628 dg.addArgAttr(llvm_fn, it.llvm_index - 1, "noundef");2521 o.addArgAttr(llvm_fn, it.llvm_index - 1, "noundef");
2629 },2522 },
2630 // No attributes needed for these.2523 // No attributes needed for these.
2631 .no_bits,2524 .no_bits,
...@@ -2645,20 +2538,20 @@ pub const DeclGen = struct {...@@ -2645,20 +2538,20 @@ pub const DeclGen = struct {
2645 return llvm_fn;2538 return llvm_fn;
2646 }2539 }
26472540
2648 fn addCommonFnAttributes(dg: *DeclGen, llvm_fn: *llvm.Value) void {2541 fn addCommonFnAttributes(o: *Object, llvm_fn: *llvm.Value) void {
2649 const comp = dg.module.comp;2542 const comp = o.module.comp;
26502543
2651 if (!comp.bin_file.options.red_zone) {2544 if (!comp.bin_file.options.red_zone) {
2652 dg.addFnAttr(llvm_fn, "noredzone");2545 o.addFnAttr(llvm_fn, "noredzone");
2653 }2546 }
2654 if (comp.bin_file.options.omit_frame_pointer) {2547 if (comp.bin_file.options.omit_frame_pointer) {
2655 dg.addFnAttrString(llvm_fn, "frame-pointer", "none");2548 o.addFnAttrString(llvm_fn, "frame-pointer", "none");
2656 } else {2549 } else {
2657 dg.addFnAttrString(llvm_fn, "frame-pointer", "all");2550 o.addFnAttrString(llvm_fn, "frame-pointer", "all");
2658 }2551 }
2659 dg.addFnAttr(llvm_fn, "nounwind");2552 o.addFnAttr(llvm_fn, "nounwind");
2660 if (comp.unwind_tables) {2553 if (comp.unwind_tables) {
2661 dg.addFnAttrInt(llvm_fn, "uwtable", 2);2554 o.addFnAttrInt(llvm_fn, "uwtable", 2);
2662 }2555 }
2663 if (comp.bin_file.options.skip_linker_dependencies or2556 if (comp.bin_file.options.skip_linker_dependencies or
2664 comp.bin_file.options.no_builtin)2557 comp.bin_file.options.no_builtin)
...@@ -2668,14 +2561,14 @@ pub const DeclGen = struct {...@@ -2668,14 +2561,14 @@ pub const DeclGen = struct {
2668 // and llvm detects that the body is equivalent to memcpy, it may replace the2561 // and llvm detects that the body is equivalent to memcpy, it may replace the
2669 // body of memcpy with a call to memcpy, which would then cause a stack2562 // body of memcpy with a call to memcpy, which would then cause a stack
2670 // overflow instead of performing memcpy.2563 // overflow instead of performing memcpy.
2671 dg.addFnAttr(llvm_fn, "nobuiltin");2564 o.addFnAttr(llvm_fn, "nobuiltin");
2672 }2565 }
2673 if (comp.bin_file.options.optimize_mode == .ReleaseSmall) {2566 if (comp.bin_file.options.optimize_mode == .ReleaseSmall) {
2674 dg.addFnAttr(llvm_fn, "minsize");2567 o.addFnAttr(llvm_fn, "minsize");
2675 dg.addFnAttr(llvm_fn, "optsize");2568 o.addFnAttr(llvm_fn, "optsize");
2676 }2569 }
2677 if (comp.bin_file.options.tsan) {2570 if (comp.bin_file.options.tsan) {
2678 dg.addFnAttr(llvm_fn, "sanitize_thread");2571 o.addFnAttr(llvm_fn, "sanitize_thread");
2679 }2572 }
2680 if (comp.getTarget().cpu.model.llvm_name) |s| {2573 if (comp.getTarget().cpu.model.llvm_name) |s| {
2681 llvm_fn.addFunctionAttr("target-cpu", s);2574 llvm_fn.addFunctionAttr("target-cpu", s);
...@@ -2688,21 +2581,21 @@ pub const DeclGen = struct {...@@ -2688,21 +2581,21 @@ pub const DeclGen = struct {
2688 }2581 }
2689 }2582 }
26902583
2691 fn resolveGlobalDecl(dg: *DeclGen, decl_index: Module.Decl.Index) Error!*llvm.Value {2584 fn resolveGlobalDecl(o: *Object, decl_index: Module.Decl.Index) Error!*llvm.Value {
2692 const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl_index);2585 const gop = try o.decl_map.getOrPut(o.gpa, decl_index);
2693 if (gop.found_existing) return gop.value_ptr.*;2586 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;
2697 const decl = mod.declPtr(decl_index);2590 const decl = mod.declPtr(decl_index);
2698 const fqn = try decl.getFullyQualifiedName(mod);2591 const fqn = try decl.getFullyQualifiedName(mod);
26992592
2700 const target = mod.getTarget();2593 const target = mod.getTarget();
27012594
2702 const llvm_type = try dg.lowerType(decl.ty);2595 const llvm_type = try o.lowerType(decl.ty);
2703 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);2596 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(
2706 llvm_type,2599 llvm_type,
2707 mod.intern_pool.stringToSlice(fqn),2600 mod.intern_pool.stringToSlice(fqn),
2708 llvm_actual_addrspace,2601 llvm_actual_addrspace,
...@@ -2731,128 +2624,128 @@ pub const DeclGen = struct {...@@ -2731,128 +2624,128 @@ pub const DeclGen = struct {
2731 return llvm_global;2624 return llvm_global;
2732 }2625 }
27332626
2734 fn isUnnamedType(dg: *DeclGen, ty: Type, val: *llvm.Value) bool {2627 fn isUnnamedType(o: *Object, ty: Type, val: *llvm.Value) bool {
2735 // Once `lowerType` succeeds, successive calls to it with the same Zig type2628 // Once `lowerType` succeeds, successive calls to it with the same Zig type
2736 // are guaranteed to succeed. So if a call to `lowerType` fails here it means2629 // are guaranteed to succeed. So if a call to `lowerType` fails here it means
2737 // it is the first time lowering the type, which means the value can't possible2630 // it is the first time lowering the type, which means the value can't possible
2738 // have that type.2631 // have that type.
2739 const llvm_ty = dg.lowerType(ty) catch return true;2632 const llvm_ty = o.lowerType(ty) catch return true;
2740 return val.typeOf() != llvm_ty;2633 return val.typeOf() != llvm_ty;
2741 }2634 }
27422635
2743 fn lowerType(dg: *DeclGen, t: Type) Allocator.Error!*llvm.Type {2636 fn lowerType(o: *Object, t: Type) Allocator.Error!*llvm.Type {
2744 const llvm_ty = try lowerTypeInner(dg, t);2637 const llvm_ty = try lowerTypeInner(o, t);
2745 const mod = dg.module;2638 const mod = o.module;
2746 if (std.debug.runtime_safety and false) check: {2639 if (std.debug.runtime_safety and false) check: {
2747 if (t.zigTypeTag(mod) == .Opaque) break :check;2640 if (t.zigTypeTag(mod) == .Opaque) break :check;
2748 if (!t.hasRuntimeBits(mod)) break :check;2641 if (!t.hasRuntimeBits(mod)) break :check;
2749 if (!llvm_ty.isSized().toBool()) break :check;2642 if (!llvm_ty.isSized().toBool()) break :check;
27502643
2751 const zig_size = t.abiSize(mod);2644 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);
2753 if (llvm_size != zig_size) {2646 if (llvm_size != zig_size) {
2754 log.err("when lowering {}, Zig ABI size = {d} but LLVM ABI size = {d}", .{2647 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,
2756 });2649 });
2757 }2650 }
2758 }2651 }
2759 return llvm_ty;2652 return llvm_ty;
2760 }2653 }
27612654
2762 fn lowerTypeInner(dg: *DeclGen, t: Type) Allocator.Error!*llvm.Type {2655 fn lowerTypeInner(o: *Object, t: Type) Allocator.Error!*llvm.Type {
2763 const gpa = dg.gpa;2656 const gpa = o.gpa;
2764 const mod = dg.module;2657 const mod = o.module;
2765 const target = mod.getTarget();2658 const target = mod.getTarget();
2766 switch (t.zigTypeTag(mod)) {2659 switch (t.zigTypeTag(mod)) {
2767 .Void, .NoReturn => return dg.context.voidType(),2660 .Void, .NoReturn => return o.context.voidType(),
2768 .Int => {2661 .Int => {
2769 const info = t.intInfo(mod);2662 const info = t.intInfo(mod);
2770 assert(info.bits != 0);2663 assert(info.bits != 0);
2771 return dg.context.intType(info.bits);2664 return o.context.intType(info.bits);
2772 },2665 },
2773 .Enum => {2666 .Enum => {
2774 const int_ty = t.intTagType(mod);2667 const int_ty = t.intTagType(mod);
2775 const bit_count = int_ty.intInfo(mod).bits;2668 const bit_count = int_ty.intInfo(mod).bits;
2776 assert(bit_count != 0);2669 assert(bit_count != 0);
2777 return dg.context.intType(bit_count);2670 return o.context.intType(bit_count);
2778 },2671 },
2779 .Float => switch (t.floatBits(target)) {2672 .Float => switch (t.floatBits(target)) {
2780 16 => return if (backendSupportsF16(target)) dg.context.halfType() else dg.context.intType(16),2673 16 => return if (backendSupportsF16(target)) o.context.halfType() else o.context.intType(16),
2781 32 => return dg.context.floatType(),2674 32 => return o.context.floatType(),
2782 64 => return dg.context.doubleType(),2675 64 => return o.context.doubleType(),
2783 80 => return if (backendSupportsF80(target)) dg.context.x86FP80Type() else dg.context.intType(80),2676 80 => return if (backendSupportsF80(target)) o.context.x86FP80Type() else o.context.intType(80),
2784 128 => return dg.context.fp128Type(),2677 128 => return o.context.fp128Type(),
2785 else => unreachable,2678 else => unreachable,
2786 },2679 },
2787 .Bool => return dg.context.intType(1),2680 .Bool => return o.context.intType(1),
2788 .Pointer => {2681 .Pointer => {
2789 if (t.isSlice(mod)) {2682 if (t.isSlice(mod)) {
2790 const ptr_type = t.slicePtrFieldType(mod);2683 const ptr_type = t.slicePtrFieldType(mod);
27912684
2792 const fields: [2]*llvm.Type = .{2685 const fields: [2]*llvm.Type = .{
2793 try dg.lowerType(ptr_type),2686 try o.lowerType(ptr_type),
2794 try dg.lowerType(Type.usize),2687 try o.lowerType(Type.usize),
2795 };2688 };
2796 return dg.context.structType(&fields, fields.len, .False);2689 return o.context.structType(&fields, fields.len, .False);
2797 }2690 }
2798 const ptr_info = t.ptrInfo(mod);2691 const ptr_info = t.ptrInfo(mod);
2799 const llvm_addrspace = toLlvmAddressSpace(ptr_info.flags.address_space, target);2692 const llvm_addrspace = toLlvmAddressSpace(ptr_info.flags.address_space, target);
2800 return dg.context.pointerType(llvm_addrspace);2693 return o.context.pointerType(llvm_addrspace);
2801 },2694 },
2802 .Opaque => {2695 .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());
2806 if (gop.found_existing) return gop.value_ptr.*;2699 if (gop.found_existing) return gop.value_ptr.*;
28072700
2808 const opaque_type = mod.intern_pool.indexToKey(t.toIntern()).opaque_type;2701 const opaque_type = mod.intern_pool.indexToKey(t.toIntern()).opaque_type;
2809 const name = mod.intern_pool.stringToSlice(try mod.opaqueFullyQualifiedName(opaque_type));2702 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);
2812 gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls2705 gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
2813 return llvm_struct_ty;2706 return llvm_struct_ty;
2814 },2707 },
2815 .Array => {2708 .Array => {
2816 const elem_ty = t.childType(mod);2709 const elem_ty = t.childType(mod);
2817 if (std.debug.runtime_safety) assert((try elem_ty.onePossibleValue(mod)) == null);2710 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);
2819 const total_len = t.arrayLen(mod) + @intFromBool(t.sentinel(mod) != null);2712 const total_len = t.arrayLen(mod) + @intFromBool(t.sentinel(mod) != null);
2820 return elem_llvm_ty.arrayType(@intCast(c_uint, total_len));2713 return elem_llvm_ty.arrayType(@intCast(c_uint, total_len));
2821 },2714 },
2822 .Vector => {2715 .Vector => {
2823 const elem_type = try dg.lowerType(t.childType(mod));2716 const elem_type = try o.lowerType(t.childType(mod));
2824 return elem_type.vectorType(t.vectorLen(mod));2717 return elem_type.vectorType(t.vectorLen(mod));
2825 },2718 },
2826 .Optional => {2719 .Optional => {
2827 const child_ty = t.optionalChild(mod);2720 const child_ty = t.optionalChild(mod);
2828 if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) {2721 if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2829 return dg.context.intType(8);2722 return o.context.intType(8);
2830 }2723 }
2831 const payload_llvm_ty = try dg.lowerType(child_ty);2724 const payload_llvm_ty = try o.lowerType(child_ty);
2832 if (t.optionalReprIsPayload(mod)) {2725 if (t.optionalReprIsPayload(mod)) {
2833 return payload_llvm_ty;2726 return payload_llvm_ty;
2834 }2727 }
28352728
2836 comptime assert(optional_layout_version == 3);2729 comptime assert(optional_layout_version == 3);
2837 var fields_buf: [3]*llvm.Type = .{2730 var fields_buf: [3]*llvm.Type = .{
2838 payload_llvm_ty, dg.context.intType(8), undefined,2731 payload_llvm_ty, o.context.intType(8), undefined,
2839 };2732 };
2840 const offset = child_ty.abiSize(mod) + 1;2733 const offset = child_ty.abiSize(mod) + 1;
2841 const abi_size = t.abiSize(mod);2734 const abi_size = t.abiSize(mod);
2842 const padding = @intCast(c_uint, abi_size - offset);2735 const padding = @intCast(c_uint, abi_size - offset);
2843 if (padding == 0) {2736 if (padding == 0) {
2844 return dg.context.structType(&fields_buf, 2, .False);2737 return o.context.structType(&fields_buf, 2, .False);
2845 }2738 }
2846 fields_buf[2] = dg.context.intType(8).arrayType(padding);2739 fields_buf[2] = o.context.intType(8).arrayType(padding);
2847 return dg.context.structType(&fields_buf, 3, .False);2740 return o.context.structType(&fields_buf, 3, .False);
2848 },2741 },
2849 .ErrorUnion => {2742 .ErrorUnion => {
2850 const payload_ty = t.errorUnionPayload(mod);2743 const payload_ty = t.errorUnionPayload(mod);
2851 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {2744 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2852 return try dg.lowerType(Type.anyerror);2745 return try o.lowerType(Type.anyerror);
2853 }2746 }
2854 const llvm_error_type = try dg.lowerType(Type.anyerror);2747 const llvm_error_type = try o.lowerType(Type.anyerror);
2855 const llvm_payload_type = try dg.lowerType(payload_ty);2748 const llvm_payload_type = try o.lowerType(payload_ty);
28562749
2857 const payload_align = payload_ty.abiAlignment(mod);2750 const payload_align = payload_ty.abiAlignment(mod);
2858 const error_align = Type.anyerror.abiAlignment(mod);2751 const error_align = Type.anyerror.abiAlignment(mod);
...@@ -2870,10 +2763,10 @@ pub const DeclGen = struct {...@@ -2870,10 +2763,10 @@ pub const DeclGen = struct {
2870 const abi_size = std.mem.alignForward(u64, payload_end, error_align);2763 const abi_size = std.mem.alignForward(u64, payload_end, error_align);
2871 const padding = @intCast(c_uint, abi_size - payload_end);2764 const padding = @intCast(c_uint, abi_size - payload_end);
2872 if (padding == 0) {2765 if (padding == 0) {
2873 return dg.context.structType(&fields_buf, 2, .False);2766 return o.context.structType(&fields_buf, 2, .False);
2874 }2767 }
2875 fields_buf[2] = dg.context.intType(8).arrayType(padding);2768 fields_buf[2] = o.context.intType(8).arrayType(padding);
2876 return dg.context.structType(&fields_buf, 3, .False);2769 return o.context.structType(&fields_buf, 3, .False);
2877 } else {2770 } else {
2878 fields_buf[0] = llvm_payload_type;2771 fields_buf[0] = llvm_payload_type;
2879 fields_buf[1] = llvm_error_type;2772 fields_buf[1] = llvm_error_type;
...@@ -2883,20 +2776,20 @@ pub const DeclGen = struct {...@@ -2883,20 +2776,20 @@ pub const DeclGen = struct {
2883 const abi_size = std.mem.alignForward(u64, error_end, payload_align);2776 const abi_size = std.mem.alignForward(u64, error_end, payload_align);
2884 const padding = @intCast(c_uint, abi_size - error_end);2777 const padding = @intCast(c_uint, abi_size - error_end);
2885 if (padding == 0) {2778 if (padding == 0) {
2886 return dg.context.structType(&fields_buf, 2, .False);2779 return o.context.structType(&fields_buf, 2, .False);
2887 }2780 }
2888 fields_buf[2] = dg.context.intType(8).arrayType(padding);2781 fields_buf[2] = o.context.intType(8).arrayType(padding);
2889 return dg.context.structType(&fields_buf, 3, .False);2782 return o.context.structType(&fields_buf, 3, .False);
2890 }2783 }
2891 },2784 },
2892 .ErrorSet => return dg.context.intType(16),2785 .ErrorSet => return o.context.intType(16),
2893 .Struct => {2786 .Struct => {
2894 const gop = try dg.object.type_map.getOrPut(gpa, t.toIntern());2787 const gop = try o.type_map.getOrPut(gpa, t.toIntern());
2895 if (gop.found_existing) return gop.value_ptr.*;2788 if (gop.found_existing) return gop.value_ptr.*;
28962789
2897 const struct_type = switch (mod.intern_pool.indexToKey(t.toIntern())) {2790 const struct_type = switch (mod.intern_pool.indexToKey(t.toIntern())) {
2898 .anon_struct_type => |tuple| {2791 .anon_struct_type => |tuple| {
2899 const llvm_struct_ty = dg.context.structCreateNamed("");2792 const llvm_struct_ty = o.context.structCreateNamed("");
2900 gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls2793 gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
29012794
2902 var llvm_field_types: std.ArrayListUnmanaged(*llvm.Type) = .{};2795 var llvm_field_types: std.ArrayListUnmanaged(*llvm.Type) = .{};
...@@ -2918,10 +2811,10 @@ pub const DeclGen = struct {...@@ -2918,10 +2811,10 @@ pub const DeclGen = struct {
29182811
2919 const padding_len = offset - prev_offset;2812 const padding_len = offset - prev_offset;
2920 if (padding_len > 0) {2813 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));
2922 try llvm_field_types.append(gpa, llvm_array_ty);2815 try llvm_field_types.append(gpa, llvm_array_ty);
2923 }2816 }
2924 const field_llvm_ty = try dg.lowerType(field_ty.toType());2817 const field_llvm_ty = try o.lowerType(field_ty.toType());
2925 try llvm_field_types.append(gpa, field_llvm_ty);2818 try llvm_field_types.append(gpa, field_llvm_ty);
29262819
2927 offset += field_ty.toType().abiSize(mod);2820 offset += field_ty.toType().abiSize(mod);
...@@ -2931,7 +2824,7 @@ pub const DeclGen = struct {...@@ -2931,7 +2824,7 @@ pub const DeclGen = struct {
2931 offset = std.mem.alignForward(u64, offset, big_align);2824 offset = std.mem.alignForward(u64, offset, big_align);
2932 const padding_len = offset - prev_offset;2825 const padding_len = offset - prev_offset;
2933 if (padding_len > 0) {2826 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));
2935 try llvm_field_types.append(gpa, llvm_array_ty);2828 try llvm_field_types.append(gpa, llvm_array_ty);
2936 }2829 }
2937 }2830 }
...@@ -2952,14 +2845,14 @@ pub const DeclGen = struct {...@@ -2952,14 +2845,14 @@ pub const DeclGen = struct {
29522845
2953 if (struct_obj.layout == .Packed) {2846 if (struct_obj.layout == .Packed) {
2954 assert(struct_obj.haveLayout());2847 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);
2956 gop.value_ptr.* = int_llvm_ty;2849 gop.value_ptr.* = int_llvm_ty;
2957 return int_llvm_ty;2850 return int_llvm_ty;
2958 }2851 }
29592852
2960 const name = mod.intern_pool.stringToSlice(try struct_obj.getFullyQualifiedName(mod));2853 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);
2963 gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls2856 gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
29642857
2965 assert(struct_obj.haveFieldTypes());2858 assert(struct_obj.haveFieldTypes());
...@@ -2987,10 +2880,10 @@ pub const DeclGen = struct {...@@ -2987,10 +2880,10 @@ pub const DeclGen = struct {
29872880
2988 const padding_len = offset - prev_offset;2881 const padding_len = offset - prev_offset;
2989 if (padding_len > 0) {2882 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));
2991 try llvm_field_types.append(gpa, llvm_array_ty);2884 try llvm_field_types.append(gpa, llvm_array_ty);
2992 }2885 }
2993 const field_llvm_ty = try dg.lowerType(field.ty);2886 const field_llvm_ty = try o.lowerType(field.ty);
2994 try llvm_field_types.append(gpa, field_llvm_ty);2887 try llvm_field_types.append(gpa, field_llvm_ty);
29952888
2996 offset += field.ty.abiSize(mod);2889 offset += field.ty.abiSize(mod);
...@@ -3000,7 +2893,7 @@ pub const DeclGen = struct {...@@ -3000,7 +2893,7 @@ pub const DeclGen = struct {
3000 offset = std.mem.alignForward(u64, offset, big_align);2893 offset = std.mem.alignForward(u64, offset, big_align);
3001 const padding_len = offset - prev_offset;2894 const padding_len = offset - prev_offset;
3002 if (padding_len > 0) {2895 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));
3004 try llvm_field_types.append(gpa, llvm_array_ty);2897 try llvm_field_types.append(gpa, llvm_array_ty);
3005 }2898 }
3006 }2899 }
...@@ -3014,7 +2907,7 @@ pub const DeclGen = struct {...@@ -3014,7 +2907,7 @@ pub const DeclGen = struct {
3014 return llvm_struct_ty;2907 return llvm_struct_ty;
3015 },2908 },
3016 .Union => {2909 .Union => {
3017 const gop = try dg.object.type_map.getOrPut(gpa, t.toIntern());2910 const gop = try o.type_map.getOrPut(gpa, t.toIntern());
3018 if (gop.found_existing) return gop.value_ptr.*;2911 if (gop.found_existing) return gop.value_ptr.*;
30192912
3020 const layout = t.unionGetLayout(mod);2913 const layout = t.unionGetLayout(mod);
...@@ -3022,24 +2915,24 @@ pub const DeclGen = struct {...@@ -3022,24 +2915,24 @@ pub const DeclGen = struct {
30222915
3023 if (union_obj.layout == .Packed) {2916 if (union_obj.layout == .Packed) {
3024 const bitsize = @intCast(c_uint, t.bitSize(mod));2917 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);
3026 gop.value_ptr.* = int_llvm_ty;2919 gop.value_ptr.* = int_llvm_ty;
3027 return int_llvm_ty;2920 return int_llvm_ty;
3028 }2921 }
30292922
3030 if (layout.payload_size == 0) {2923 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);
3032 gop.value_ptr.* = enum_tag_llvm_ty;2925 gop.value_ptr.* = enum_tag_llvm_ty;
3033 return enum_tag_llvm_ty;2926 return enum_tag_llvm_ty;
3034 }2927 }
30352928
3036 const name = mod.intern_pool.stringToSlice(try union_obj.getFullyQualifiedName(mod));2929 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);
3039 gop.value_ptr.* = llvm_union_ty; // must be done before any recursive calls2932 gop.value_ptr.* = llvm_union_ty; // must be done before any recursive calls
30402933
3041 const aligned_field = union_obj.fields.values()[layout.most_aligned_field];2934 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
3044 const llvm_payload_ty = t: {2937 const llvm_payload_ty = t: {
3045 if (layout.most_aligned_field_size == layout.payload_size) {2938 if (layout.most_aligned_field_size == layout.payload_size) {
...@@ -3051,9 +2944,9 @@ pub const DeclGen = struct {...@@ -3051,9 +2944,9 @@ pub const DeclGen = struct {
3051 @intCast(c_uint, layout.payload_size - layout.most_aligned_field_size);2944 @intCast(c_uint, layout.payload_size - layout.most_aligned_field_size);
3052 const fields: [2]*llvm.Type = .{2945 const fields: [2]*llvm.Type = .{
3053 llvm_aligned_field_ty,2946 llvm_aligned_field_ty,
3054 dg.context.intType(8).arrayType(padding_len),2947 o.context.intType(8).arrayType(padding_len),
3055 };2948 };
3056 break :t dg.context.structType(&fields, fields.len, .True);2949 break :t o.context.structType(&fields, fields.len, .True);
3057 };2950 };
30582951
3059 if (layout.tag_size == 0) {2952 if (layout.tag_size == 0) {
...@@ -3061,7 +2954,7 @@ pub const DeclGen = struct {...@@ -3061,7 +2954,7 @@ pub const DeclGen = struct {
3061 llvm_union_ty.structSetBody(&llvm_fields, llvm_fields.len, .False);2954 llvm_union_ty.structSetBody(&llvm_fields, llvm_fields.len, .False);
3062 return llvm_union_ty;2955 return llvm_union_ty;
3063 }2956 }
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
3066 // Put the tag before or after the payload depending on which one's2959 // Put the tag before or after the payload depending on which one's
3067 // alignment is greater.2960 // alignment is greater.
...@@ -3076,14 +2969,14 @@ pub const DeclGen = struct {...@@ -3076,14 +2969,14 @@ pub const DeclGen = struct {
30762969
3077 // Insert padding to make the LLVM struct ABI size match the Zig union ABI size.2970 // Insert padding to make the LLVM struct ABI size match the Zig union ABI size.
3078 if (layout.padding != 0) {2971 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);
3080 llvm_fields_len = 3;2973 llvm_fields_len = 3;
3081 }2974 }
30822975
3083 llvm_union_ty.structSetBody(&llvm_fields, llvm_fields_len, .False);2976 llvm_union_ty.structSetBody(&llvm_fields, llvm_fields_len, .False);
3084 return llvm_union_ty;2977 return llvm_union_ty;
3085 },2978 },
3086 .Fn => return lowerTypeFn(dg, t),2979 .Fn => return lowerTypeFn(o, t),
3087 .ComptimeInt => unreachable,2980 .ComptimeInt => unreachable,
3088 .ComptimeFloat => unreachable,2981 .ComptimeFloat => unreachable,
3089 .Type => unreachable,2982 .Type => unreachable,
...@@ -3096,39 +2989,39 @@ pub const DeclGen = struct {...@@ -3096,39 +2989,39 @@ pub const DeclGen = struct {
3096 }2989 }
3097 }2990 }
30982991
3099 fn lowerTypeFn(dg: *DeclGen, fn_ty: Type) Allocator.Error!*llvm.Type {2992 fn lowerTypeFn(o: *Object, fn_ty: Type) Allocator.Error!*llvm.Type {
3100 const mod = dg.module;2993 const mod = o.module;
3101 const fn_info = mod.typeToFunc(fn_ty).?;2994 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);
3105 defer llvm_params.deinit();2998 defer llvm_params.deinit();
31062999
3107 if (firstParamSRet(fn_info, mod)) {3000 if (firstParamSRet(fn_info, mod)) {
3108 try llvm_params.append(dg.context.pointerType(0));3001 try llvm_params.append(o.context.pointerType(0));
3109 }3002 }
31103003
3111 if (fn_info.return_type.toType().isError(mod) and3004 if (fn_info.return_type.toType().isError(mod) and
3112 mod.comp.bin_file.options.error_return_tracing)3005 mod.comp.bin_file.options.error_return_tracing)
3113 {3006 {
3114 const ptr_ty = try mod.singleMutPtrType(try dg.object.getStackTraceType());3007 const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType());
3115 try llvm_params.append(try dg.lowerType(ptr_ty));3008 try llvm_params.append(try o.lowerType(ptr_ty));
3116 }3009 }
31173010
3118 var it = iterateParamTypes(dg, fn_info);3011 var it = iterateParamTypes(o, fn_info);
3119 while (it.next()) |lowering| switch (lowering) {3012 while (it.next()) |lowering| switch (lowering) {
3120 .no_bits => continue,3013 .no_bits => continue,
3121 .byval => {3014 .byval => {
3122 const param_ty = fn_info.param_types[it.zig_index - 1].toType();3015 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));
3124 },3017 },
3125 .byref, .byref_mut => {3018 .byref, .byref_mut => {
3126 try llvm_params.append(dg.context.pointerType(0));3019 try llvm_params.append(o.context.pointerType(0));
3127 },3020 },
3128 .abi_sized_int => {3021 .abi_sized_int => {
3129 const param_ty = fn_info.param_types[it.zig_index - 1].toType();3022 const param_ty = fn_info.param_types[it.zig_index - 1].toType();
3130 const abi_size = @intCast(c_uint, param_ty.abiSize(mod));3023 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));
3132 },3025 },
3133 .slice => {3026 .slice => {
3134 const param_ty = fn_info.param_types[it.zig_index - 1].toType();3027 const param_ty = fn_info.param_types[it.zig_index - 1].toType();
...@@ -3136,8 +3029,8 @@ pub const DeclGen = struct {...@@ -3136,8 +3029,8 @@ pub const DeclGen = struct {
3136 param_ty.optionalChild(mod).slicePtrFieldType(mod)3029 param_ty.optionalChild(mod).slicePtrFieldType(mod)
3137 else3030 else
3138 param_ty.slicePtrFieldType(mod);3031 param_ty.slicePtrFieldType(mod);
3139 const ptr_llvm_ty = try dg.lowerType(ptr_ty);3032 const ptr_llvm_ty = try o.lowerType(ptr_ty);
3140 const len_llvm_ty = try dg.lowerType(Type.usize);3033 const len_llvm_ty = try o.lowerType(Type.usize);
31413034
3142 try llvm_params.ensureUnusedCapacity(2);3035 try llvm_params.ensureUnusedCapacity(2);
3143 llvm_params.appendAssumeCapacity(ptr_llvm_ty);3036 llvm_params.appendAssumeCapacity(ptr_llvm_ty);
...@@ -3147,18 +3040,18 @@ pub const DeclGen = struct {...@@ -3147,18 +3040,18 @@ pub const DeclGen = struct {
3147 try llvm_params.appendSlice(it.llvm_types_buffer[0..it.llvm_types_len]);3040 try llvm_params.appendSlice(it.llvm_types_buffer[0..it.llvm_types_len]);
3148 },3041 },
3149 .as_u16 => {3042 .as_u16 => {
3150 try llvm_params.append(dg.context.intType(16));3043 try llvm_params.append(o.context.intType(16));
3151 },3044 },
3152 .float_array => |count| {3045 .float_array => |count| {
3153 const param_ty = fn_info.param_types[it.zig_index - 1].toType();3046 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).?);
3155 const field_count = @intCast(c_uint, count);3048 const field_count = @intCast(c_uint, count);
3156 const arr_ty = float_ty.arrayType(field_count);3049 const arr_ty = float_ty.arrayType(field_count);
3157 try llvm_params.append(arr_ty);3050 try llvm_params.append(arr_ty);
3158 },3051 },
3159 .i32_array, .i64_array => |arr_len| {3052 .i32_array, .i64_array => |arr_len| {
3160 const elem_size: u8 = if (lowering == .i32_array) 32 else 64;3053 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);
3162 try llvm_params.append(arr_ty);3055 try llvm_params.append(arr_ty);
3163 },3056 },
3164 };3057 };
...@@ -3174,8 +3067,8 @@ pub const DeclGen = struct {...@@ -3174,8 +3067,8 @@ pub const DeclGen = struct {
3174 /// Use this instead of lowerType when you want to handle correctly the case of elem_ty3067 /// Use this instead of lowerType when you want to handle correctly the case of elem_ty
3175 /// being a zero bit type, but it should still be lowered as an i8 in such case.3068 /// being a zero bit type, but it should still be lowered as an i8 in such case.
3176 /// There are other similar cases handled here as well.3069 /// There are other similar cases handled here as well.
3177 fn lowerPtrElemTy(dg: *DeclGen, elem_ty: Type) Allocator.Error!*llvm.Type {3070 fn lowerPtrElemTy(o: *Object, elem_ty: Type) Allocator.Error!*llvm.Type {
3178 const mod = dg.module;3071 const mod = o.module;
3179 const lower_elem_ty = switch (elem_ty.zigTypeTag(mod)) {3072 const lower_elem_ty = switch (elem_ty.zigTypeTag(mod)) {
3180 .Opaque => true,3073 .Opaque => true,
3181 .Fn => !mod.typeToFunc(elem_ty).?.is_generic,3074 .Fn => !mod.typeToFunc(elem_ty).?.is_generic,
...@@ -3183,15 +3076,16 @@ pub const DeclGen = struct {...@@ -3183,15 +3076,16 @@ pub const DeclGen = struct {
3183 else => elem_ty.hasRuntimeBitsIgnoreComptime(mod),3076 else => elem_ty.hasRuntimeBitsIgnoreComptime(mod),
3184 };3077 };
3185 const llvm_elem_ty = if (lower_elem_ty)3078 const llvm_elem_ty = if (lower_elem_ty)
3186 try dg.lowerType(elem_ty)3079 try o.lowerType(elem_ty)
3187 else3080 else
3188 dg.context.intType(8);3081 o.context.intType(8);
31893082
3190 return llvm_elem_ty;3083 return llvm_elem_ty;
3191 }3084 }
31923085
3193 fn lowerValue(dg: *DeclGen, arg_tv: TypedValue) Error!*llvm.Value {3086 fn lowerValue(o: *Object, arg_tv: TypedValue) Error!*llvm.Value {
3194 const mod = dg.module;3087 const mod = o.module;
3088 const gpa = o.gpa;
3195 const target = mod.getTarget();3089 const target = mod.getTarget();
3196 var tv = arg_tv;3090 var tv = arg_tv;
3197 switch (mod.intern_pool.indexToKey(tv.val.toIntern())) {3091 switch (mod.intern_pool.indexToKey(tv.val.toIntern())) {
...@@ -3199,7 +3093,7 @@ pub const DeclGen = struct {...@@ -3199,7 +3093,7 @@ pub const DeclGen = struct {
3199 else => {},3093 else => {},
3200 }3094 }
3201 if (tv.val.isUndefDeep(mod)) {3095 if (tv.val.isUndefDeep(mod)) {
3202 const llvm_type = try dg.lowerType(tv.ty);3096 const llvm_type = try o.lowerType(tv.ty);
3203 return llvm_type.getUndef();3097 return llvm_type.getUndef();
3204 }3098 }
32053099
...@@ -3233,7 +3127,7 @@ pub const DeclGen = struct {...@@ -3233,7 +3127,7 @@ pub const DeclGen = struct {
3233 .generic_poison,3127 .generic_poison,
3234 => unreachable, // non-runtime values3128 => unreachable, // non-runtime values
3235 .false, .true => {3129 .false, .true => {
3236 const llvm_type = try dg.lowerType(tv.ty);3130 const llvm_type = try o.lowerType(tv.ty);
3237 return if (tv.val.toBool()) llvm_type.constAllOnes() else llvm_type.constNull();3131 return if (tv.val.toBool()) llvm_type.constAllOnes() else llvm_type.constNull();
3238 },3132 },
3239 },3133 },
...@@ -3247,17 +3141,17 @@ pub const DeclGen = struct {...@@ -3247,17 +3141,17 @@ pub const DeclGen = struct {
3247 .func => |func| mod.funcPtr(func.index).owner_decl,3141 .func => |func| mod.funcPtr(func.index).owner_decl,
3248 else => unreachable,3142 else => unreachable,
3249 };3143 };
3250 const fn_decl = dg.module.declPtr(fn_decl_index);3144 const fn_decl = o.module.declPtr(fn_decl_index);
3251 try dg.module.markDeclAlive(fn_decl);3145 try o.module.markDeclAlive(fn_decl);
3252 return dg.resolveLlvmFunction(fn_decl_index);3146 return o.resolveLlvmFunction(fn_decl_index);
3253 },3147 },
3254 .int => {3148 .int => {
3255 var bigint_space: Value.BigIntSpace = undefined;3149 var bigint_space: Value.BigIntSpace = undefined;
3256 const bigint = tv.val.toBigInt(&bigint_space, mod);3150 const bigint = tv.val.toBigInt(&bigint_space, mod);
3257 return lowerBigInt(dg, tv.ty, bigint);3151 return lowerBigInt(o, tv.ty, bigint);
3258 },3152 },
3259 .err => |err| {3153 .err => |err| {
3260 const llvm_ty = try dg.lowerType(Type.anyerror);3154 const llvm_ty = try o.lowerType(Type.anyerror);
3261 const int = try mod.getErrorValue(err.name);3155 const int = try mod.getErrorValue(err.name);
3262 return llvm_ty.constInt(int, .False);3156 return llvm_ty.constInt(int, .False);
3263 },3157 },
...@@ -3278,13 +3172,13 @@ pub const DeclGen = struct {...@@ -3278,13 +3172,13 @@ pub const DeclGen = struct {
3278 const payload_type = tv.ty.errorUnionPayload(mod);3172 const payload_type = tv.ty.errorUnionPayload(mod);
3279 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {3173 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
3280 // We use the error type directly as the type.3174 // We use the error type directly as the type.
3281 return dg.lowerValue(err_tv);3175 return o.lowerValue(err_tv);
3282 }3176 }
32833177
3284 const payload_align = payload_type.abiAlignment(mod);3178 const payload_align = payload_type.abiAlignment(mod);
3285 const error_align = err_tv.ty.abiAlignment(mod);3179 const error_align = err_tv.ty.abiAlignment(mod);
3286 const llvm_error_value = try dg.lowerValue(err_tv);3180 const llvm_error_value = try o.lowerValue(err_tv);
3287 const llvm_payload_value = try dg.lowerValue(.{3181 const llvm_payload_value = try o.lowerValue(.{
3288 .ty = payload_type,3182 .ty = payload_type,
3289 .val = switch (error_union.val) {3183 .val = switch (error_union.val) {
3290 .err_name => try mod.intern(.{ .undef = payload_type.toIntern() }),3184 .err_name => try mod.intern(.{ .undef = payload_type.toIntern() }),
...@@ -3293,7 +3187,7 @@ pub const DeclGen = struct {...@@ -3293,7 +3187,7 @@ pub const DeclGen = struct {
3293 });3187 });
3294 var fields_buf: [3]*llvm.Value = undefined;3188 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);
3297 const llvm_field_count = llvm_ty.countStructElementTypes();3191 const llvm_field_count = llvm_ty.countStructElementTypes();
3298 if (llvm_field_count > 2) {3192 if (llvm_field_count > 2) {
3299 assert(llvm_field_count == 3);3193 assert(llvm_field_count == 3);
...@@ -3303,11 +3197,11 @@ pub const DeclGen = struct {...@@ -3303,11 +3197,11 @@ pub const DeclGen = struct {
3303 if (error_align > payload_align) {3197 if (error_align > payload_align) {
3304 fields_buf[0] = llvm_error_value;3198 fields_buf[0] = llvm_error_value;
3305 fields_buf[1] = llvm_payload_value;3199 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);
3307 } else {3201 } else {
3308 fields_buf[0] = llvm_payload_value;3202 fields_buf[0] = llvm_payload_value;
3309 fields_buf[1] = llvm_error_value;3203 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);
3311 }3205 }
3312 },3206 },
3313 .enum_tag => {3207 .enum_tag => {
...@@ -3317,7 +3211,7 @@ pub const DeclGen = struct {...@@ -3317,7 +3211,7 @@ pub const DeclGen = struct {
3317 const bigint = int_val.toBigInt(&bigint_space, mod);3211 const bigint = int_val.toBigInt(&bigint_space, mod);
33183212
3319 const int_info = tv.ty.intInfo(mod);3213 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
3322 const unsigned_val = v: {3216 const unsigned_val = v: {
3323 if (bigint.limbs.len == 1) {3217 if (bigint.limbs.len == 1) {
...@@ -3337,30 +3231,30 @@ pub const DeclGen = struct {...@@ -3337,30 +3231,30 @@ pub const DeclGen = struct {
3337 return unsigned_val;3231 return unsigned_val;
3338 },3232 },
3339 .float => {3233 .float => {
3340 const llvm_ty = try dg.lowerType(tv.ty);3234 const llvm_ty = try o.lowerType(tv.ty);
3341 switch (tv.ty.floatBits(target)) {3235 switch (tv.ty.floatBits(target)) {
3342 16 => {3236 16 => {
3343 const repr = @bitCast(u16, tv.val.toFloat(f16, mod));3237 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);
3345 const int = llvm_i16.constInt(repr, .False);3239 const int = llvm_i16.constInt(repr, .False);
3346 return int.constBitCast(llvm_ty);3240 return int.constBitCast(llvm_ty);
3347 },3241 },
3348 32 => {3242 32 => {
3349 const repr = @bitCast(u32, tv.val.toFloat(f32, mod));3243 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);
3351 const int = llvm_i32.constInt(repr, .False);3245 const int = llvm_i32.constInt(repr, .False);
3352 return int.constBitCast(llvm_ty);3246 return int.constBitCast(llvm_ty);
3353 },3247 },
3354 64 => {3248 64 => {
3355 const repr = @bitCast(u64, tv.val.toFloat(f64, mod));3249 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);
3357 const int = llvm_i64.constInt(repr, .False);3251 const int = llvm_i64.constInt(repr, .False);
3358 return int.constBitCast(llvm_ty);3252 return int.constBitCast(llvm_ty);
3359 },3253 },
3360 80 => {3254 80 => {
3361 const float = tv.val.toFloat(f80, mod);3255 const float = tv.val.toFloat(f80, mod);
3362 const repr = std.math.break_f80(float);3256 const repr = std.math.break_f80(float);
3363 const llvm_i80 = dg.context.intType(80);3257 const llvm_i80 = o.context.intType(80);
3364 var x = llvm_i80.constInt(repr.exp, .False);3258 var x = llvm_i80.constInt(repr.exp, .False);
3365 x = x.constShl(llvm_i80.constInt(64, .False));3259 x = x.constShl(llvm_i80.constInt(64, .False));
3366 x = x.constOr(llvm_i80.constInt(repr.fraction, .False));3260 x = x.constOr(llvm_i80.constInt(repr.fraction, .False));
...@@ -3377,7 +3271,7 @@ pub const DeclGen = struct {...@@ -3377,7 +3271,7 @@ pub const DeclGen = struct {
3377 if (native_endian == .Big) {3271 if (native_endian == .Big) {
3378 std.mem.swap(u64, &buf[0], &buf[1]);3272 std.mem.swap(u64, &buf[0], &buf[1]);
3379 }3273 }
3380 const int = dg.context.intType(128).constIntOfArbitraryPrecision(buf.len, &buf);3274 const int = o.context.intType(128).constIntOfArbitraryPrecision(buf.len, &buf);
3381 return int.constBitCast(llvm_ty);3275 return int.constBitCast(llvm_ty);
3382 },3276 },
3383 else => unreachable,3277 else => unreachable,
...@@ -3389,14 +3283,14 @@ pub const DeclGen = struct {...@@ -3389,14 +3283,14 @@ pub const DeclGen = struct {
3389 else => .{ .ty = tv.ty.slicePtrFieldType(mod), .val = tv.val.slicePtr(mod) },3283 else => .{ .ty = tv.ty.slicePtrFieldType(mod), .val = tv.val.slicePtr(mod) },
3390 };3284 };
3391 const llvm_ptr_val = switch (ptr.addr) {3285 const llvm_ptr_val = switch (ptr.addr) {
3392 .decl => |decl| try dg.lowerDeclRefValue(ptr_tv, decl),3286 .decl => |decl| try o.lowerDeclRefValue(ptr_tv, decl),
3393 .mut_decl => |mut_decl| try dg.lowerDeclRefValue(ptr_tv, mut_decl.decl),3287 .mut_decl => |mut_decl| try o.lowerDeclRefValue(ptr_tv, mut_decl.decl),
3394 .int => |int| try dg.lowerIntAsPtr(int.toValue()),3288 .int => |int| try o.lowerIntAsPtr(int.toValue()),
3395 .eu_payload,3289 .eu_payload,
3396 .opt_payload,3290 .opt_payload,
3397 .elem,3291 .elem,
3398 .field,3292 .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),
3400 .comptime_field => unreachable,3294 .comptime_field => unreachable,
3401 };3295 };
3402 switch (ptr.len) {3296 switch (ptr.len) {
...@@ -3404,9 +3298,9 @@ pub const DeclGen = struct {...@@ -3404,9 +3298,9 @@ pub const DeclGen = struct {
3404 else => {3298 else => {
3405 const fields: [2]*llvm.Value = .{3299 const fields: [2]*llvm.Value = .{
3406 llvm_ptr_val,3300 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() }),
3408 };3302 };
3409 return dg.context.constStruct(&fields, fields.len, .False);3303 return o.context.constStruct(&fields, fields.len, .False);
3410 },3304 },
3411 }3305 }
3412 },3306 },
...@@ -3414,7 +3308,7 @@ pub const DeclGen = struct {...@@ -3414,7 +3308,7 @@ pub const DeclGen = struct {
3414 comptime assert(optional_layout_version == 3);3308 comptime assert(optional_layout_version == 3);
3415 const payload_ty = tv.ty.optionalChild(mod);3309 const payload_ty = tv.ty.optionalChild(mod);
34163310
3417 const llvm_i8 = dg.context.intType(8);3311 const llvm_i8 = o.context.intType(8);
3418 const non_null_bit = switch (opt.val) {3312 const non_null_bit = switch (opt.val) {
3419 .none => llvm_i8.constNull(),3313 .none => llvm_i8.constNull(),
3420 else => llvm_i8.constInt(1, .False),3314 else => llvm_i8.constInt(1, .False),
...@@ -3422,16 +3316,16 @@ pub const DeclGen = struct {...@@ -3422,16 +3316,16 @@ pub const DeclGen = struct {
3422 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {3316 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3423 return non_null_bit;3317 return non_null_bit;
3424 }3318 }
3425 const llvm_ty = try dg.lowerType(tv.ty);3319 const llvm_ty = try o.lowerType(tv.ty);
3426 if (tv.ty.optionalReprIsPayload(mod)) return switch (opt.val) {3320 if (tv.ty.optionalReprIsPayload(mod)) return switch (opt.val) {
3427 .none => llvm_ty.constNull(),3321 .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() }),
3429 };3323 };
3430 assert(payload_ty.zigTypeTag(mod) != .Fn);3324 assert(payload_ty.zigTypeTag(mod) != .Fn);
34313325
3432 const llvm_field_count = llvm_ty.countStructElementTypes();3326 const llvm_field_count = llvm_ty.countStructElementTypes();
3433 var fields_buf: [3]*llvm.Value = undefined;3327 var fields_buf: [3]*llvm.Value = undefined;
3434 fields_buf[0] = try dg.lowerValue(.{3328 fields_buf[0] = try o.lowerValue(.{
3435 .ty = payload_ty,3329 .ty = payload_ty,
3436 .val = switch (opt.val) {3330 .val = switch (opt.val) {
3437 .none => try mod.intern(.{ .undef = payload_ty.toIntern() }),3331 .none => try mod.intern(.{ .undef = payload_ty.toIntern() }),
...@@ -3443,33 +3337,32 @@ pub const DeclGen = struct {...@@ -3443,33 +3337,32 @@ pub const DeclGen = struct {
3443 assert(llvm_field_count == 3);3337 assert(llvm_field_count == 3);
3444 fields_buf[2] = llvm_ty.structGetTypeAtIndex(2).getUndef();3338 fields_buf[2] = llvm_ty.structGetTypeAtIndex(2).getUndef();
3445 }3339 }
3446 return dg.context.constStruct(&fields_buf, llvm_field_count, .False);3340 return o.context.constStruct(&fields_buf, llvm_field_count, .False);
3447 },3341 },
3448 .aggregate => |aggregate| switch (mod.intern_pool.indexToKey(tv.ty.toIntern())) {3342 .aggregate => |aggregate| switch (mod.intern_pool.indexToKey(tv.ty.toIntern())) {
3449 .array_type => switch (aggregate.storage) {3343 .array_type => switch (aggregate.storage) {
3450 .bytes => |bytes| return dg.context.constString(3344 .bytes => |bytes| return o.context.constString(
3451 bytes.ptr,3345 bytes.ptr,
3452 @intCast(c_uint, tv.ty.arrayLenIncludingSentinel(mod)),3346 @intCast(c_uint, tv.ty.arrayLenIncludingSentinel(mod)),
3453 .True, // Don't null terminate. Bytes has the sentinel, if any.3347 .True, // Don't null terminate. Bytes has the sentinel, if any.
3454 ),3348 ),
3455 .elems => |elem_vals| {3349 .elems => |elem_vals| {
3456 const elem_ty = tv.ty.childType(mod);3350 const elem_ty = tv.ty.childType(mod);
3457 const gpa = dg.gpa;
3458 const llvm_elems = try gpa.alloc(*llvm.Value, elem_vals.len);3351 const llvm_elems = try gpa.alloc(*llvm.Value, elem_vals.len);
3459 defer gpa.free(llvm_elems);3352 defer gpa.free(llvm_elems);
3460 var need_unnamed = false;3353 var need_unnamed = false;
3461 for (elem_vals, 0..) |elem_val, i| {3354 for (elem_vals, 0..) |elem_val, i| {
3462 llvm_elems[i] = try dg.lowerValue(.{ .ty = elem_ty, .val = elem_val.toValue() });3355 llvm_elems[i] = try o.lowerValue(.{ .ty = elem_ty, .val = elem_val.toValue() });
3463 need_unnamed = need_unnamed or dg.isUnnamedType(elem_ty, llvm_elems[i]);3356 need_unnamed = need_unnamed or o.isUnnamedType(elem_ty, llvm_elems[i]);
3464 }3357 }
3465 if (need_unnamed) {3358 if (need_unnamed) {
3466 return dg.context.constStruct(3359 return o.context.constStruct(
3467 llvm_elems.ptr,3360 llvm_elems.ptr,
3468 @intCast(c_uint, llvm_elems.len),3361 @intCast(c_uint, llvm_elems.len),
3469 .True,3362 .True,
3470 );3363 );
3471 } else {3364 } else {
3472 const llvm_elem_ty = try dg.lowerType(elem_ty);3365 const llvm_elem_ty = try o.lowerType(elem_ty);
3473 return llvm_elem_ty.constArray(3366 return llvm_elem_ty.constArray(
3474 llvm_elems.ptr,3367 llvm_elems.ptr,
3475 @intCast(c_uint, llvm_elems.len),3368 @intCast(c_uint, llvm_elems.len),
...@@ -3481,31 +3374,30 @@ pub const DeclGen = struct {...@@ -3481,31 +3374,30 @@ pub const DeclGen = struct {
3481 const sentinel = tv.ty.sentinel(mod);3374 const sentinel = tv.ty.sentinel(mod);
3482 const len = @intCast(usize, tv.ty.arrayLen(mod));3375 const len = @intCast(usize, tv.ty.arrayLen(mod));
3483 const len_including_sent = len + @intFromBool(sentinel != null);3376 const len_including_sent = len + @intFromBool(sentinel != null);
3484 const gpa = dg.gpa;
3485 const llvm_elems = try gpa.alloc(*llvm.Value, len_including_sent);3377 const llvm_elems = try gpa.alloc(*llvm.Value, len_including_sent);
3486 defer gpa.free(llvm_elems);3378 defer gpa.free(llvm_elems);
34873379
3488 var need_unnamed = false;3380 var need_unnamed = false;
3489 if (len != 0) {3381 if (len != 0) {
3490 for (llvm_elems[0..len]) |*elem| {3382 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() });
3492 }3384 }
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]);
3494 }3386 }
34953387
3496 if (sentinel) |sent| {3388 if (sentinel) |sent| {
3497 llvm_elems[len] = try dg.lowerValue(.{ .ty = elem_ty, .val = sent });3389 llvm_elems[len] = try o.lowerValue(.{ .ty = elem_ty, .val = sent });
3498 need_unnamed = need_unnamed or dg.isUnnamedType(elem_ty, llvm_elems[len]);3390 need_unnamed = need_unnamed or o.isUnnamedType(elem_ty, llvm_elems[len]);
3499 }3391 }
35003392
3501 if (need_unnamed) {3393 if (need_unnamed) {
3502 return dg.context.constStruct(3394 return o.context.constStruct(
3503 llvm_elems.ptr,3395 llvm_elems.ptr,
3504 @intCast(c_uint, llvm_elems.len),3396 @intCast(c_uint, llvm_elems.len),
3505 .True,3397 .True,
3506 );3398 );
3507 } else {3399 } else {
3508 const llvm_elem_ty = try dg.lowerType(elem_ty);3400 const llvm_elem_ty = try o.lowerType(elem_ty);
3509 return llvm_elem_ty.constArray(3401 return llvm_elem_ty.constArray(
3510 llvm_elems.ptr,3402 llvm_elems.ptr,
3511 @intCast(c_uint, llvm_elems.len),3403 @intCast(c_uint, llvm_elems.len),
...@@ -3515,17 +3407,17 @@ pub const DeclGen = struct {...@@ -3515,17 +3407,17 @@ pub const DeclGen = struct {
3515 },3407 },
3516 .vector_type => |vector_type| {3408 .vector_type => |vector_type| {
3517 const elem_ty = vector_type.child.toType();3409 const elem_ty = vector_type.child.toType();
3518 const llvm_elems = try dg.gpa.alloc(*llvm.Value, vector_type.len);3410 const llvm_elems = try gpa.alloc(*llvm.Value, vector_type.len);
3519 defer dg.gpa.free(llvm_elems);3411 defer gpa.free(llvm_elems);
3520 const llvm_i8 = dg.context.intType(8);3412 const llvm_i8 = o.context.intType(8);
3521 for (llvm_elems, 0..) |*llvm_elem, i| {3413 for (llvm_elems, 0..) |*llvm_elem, i| {
3522 llvm_elem.* = switch (aggregate.storage) {3414 llvm_elem.* = switch (aggregate.storage) {
3523 .bytes => |bytes| llvm_i8.constInt(bytes[i], .False),3415 .bytes => |bytes| llvm_i8.constInt(bytes[i], .False),
3524 .elems => |elems| try dg.lowerValue(.{3416 .elems => |elems| try o.lowerValue(.{
3525 .ty = elem_ty,3417 .ty = elem_ty,
3526 .val = elems[i].toValue(),3418 .val = elems[i].toValue(),
3527 }),3419 }),
3528 .repeated_elem => |elem| try dg.lowerValue(.{3420 .repeated_elem => |elem| try o.lowerValue(.{
3529 .ty = elem_ty,3421 .ty = elem_ty,
3530 .val = elem.toValue(),3422 .val = elem.toValue(),
3531 }),3423 }),
...@@ -3537,8 +3429,6 @@ pub const DeclGen = struct {...@@ -3537,8 +3429,6 @@ pub const DeclGen = struct {
3537 );3429 );
3538 },3430 },
3539 .anon_struct_type => |tuple| {3431 .anon_struct_type => |tuple| {
3540 const gpa = dg.gpa;
3541
3542 var llvm_fields: std.ArrayListUnmanaged(*llvm.Value) = .{};3432 var llvm_fields: std.ArrayListUnmanaged(*llvm.Value) = .{};
3543 defer llvm_fields.deinit(gpa);3433 defer llvm_fields.deinit(gpa);
35443434
...@@ -3560,18 +3450,18 @@ pub const DeclGen = struct {...@@ -3560,18 +3450,18 @@ pub const DeclGen = struct {
35603450
3561 const padding_len = offset - prev_offset;3451 const padding_len = offset - prev_offset;
3562 if (padding_len > 0) {3452 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));
3564 // TODO make this and all other padding elsewhere in debug3454 // TODO make this and all other padding elsewhere in debug
3565 // builds be 0xaa not undef.3455 // builds be 0xaa not undef.
3566 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());3456 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
3567 }3457 }
35683458
3569 const field_llvm_val = try dg.lowerValue(.{3459 const field_llvm_val = try o.lowerValue(.{
3570 .ty = field_ty.toType(),3460 .ty = field_ty.toType(),
3571 .val = try tv.val.fieldValue(mod, i),3461 .val = try tv.val.fieldValue(mod, i),
3572 });3462 });
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
3576 llvm_fields.appendAssumeCapacity(field_llvm_val);3466 llvm_fields.appendAssumeCapacity(field_llvm_val);
35773467
...@@ -3582,19 +3472,19 @@ pub const DeclGen = struct {...@@ -3582,19 +3472,19 @@ pub const DeclGen = struct {
3582 offset = std.mem.alignForward(u64, offset, big_align);3472 offset = std.mem.alignForward(u64, offset, big_align);
3583 const padding_len = offset - prev_offset;3473 const padding_len = offset - prev_offset;
3584 if (padding_len > 0) {3474 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));
3586 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());3476 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
3587 }3477 }
3588 }3478 }
35893479
3590 if (need_unnamed) {3480 if (need_unnamed) {
3591 return dg.context.constStruct(3481 return o.context.constStruct(
3592 llvm_fields.items.ptr,3482 llvm_fields.items.ptr,
3593 @intCast(c_uint, llvm_fields.items.len),3483 @intCast(c_uint, llvm_fields.items.len),
3594 .False,3484 .False,
3595 );3485 );
3596 } else {3486 } else {
3597 const llvm_struct_ty = try dg.lowerType(tv.ty);3487 const llvm_struct_ty = try o.lowerType(tv.ty);
3598 return llvm_struct_ty.constNamedStruct(3488 return llvm_struct_ty.constNamedStruct(
3599 llvm_fields.items.ptr,3489 llvm_fields.items.ptr,
3600 @intCast(c_uint, llvm_fields.items.len),3490 @intCast(c_uint, llvm_fields.items.len),
...@@ -3603,13 +3493,12 @@ pub const DeclGen = struct {...@@ -3603,13 +3493,12 @@ pub const DeclGen = struct {
3603 },3493 },
3604 .struct_type => |struct_type| {3494 .struct_type => |struct_type| {
3605 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;3495 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
3606 const llvm_struct_ty = try dg.lowerType(tv.ty);3496 const llvm_struct_ty = try o.lowerType(tv.ty);
3607 const gpa = dg.gpa;
36083497
3609 if (struct_obj.layout == .Packed) {3498 if (struct_obj.layout == .Packed) {
3610 assert(struct_obj.haveLayout());3499 assert(struct_obj.haveLayout());
3611 const big_bits = struct_obj.backing_int_ty.bitSize(mod);3500 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));
3613 const fields = struct_obj.fields.values();3502 const fields = struct_obj.fields.values();
3614 comptime assert(Type.packed_struct_layout_version == 2);3503 comptime assert(Type.packed_struct_layout_version == 2);
3615 var running_int: *llvm.Value = int_llvm_ty.constNull();3504 var running_int: *llvm.Value = int_llvm_ty.constNull();
...@@ -3617,12 +3506,12 @@ pub const DeclGen = struct {...@@ -3617,12 +3506,12 @@ pub const DeclGen = struct {
3617 for (fields, 0..) |field, i| {3506 for (fields, 0..) |field, i| {
3618 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;3507 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
36193508
3620 const non_int_val = try dg.lowerValue(.{3509 const non_int_val = try o.lowerValue(.{
3621 .ty = field.ty,3510 .ty = field.ty,
3622 .val = try tv.val.fieldValue(mod, i),3511 .val = try tv.val.fieldValue(mod, i),
3623 });3512 });
3624 const ty_bit_size = @intCast(u16, field.ty.bitSize(mod));3513 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);
3626 const small_int_val = if (field.ty.isPtrAtRuntime(mod))3515 const small_int_val = if (field.ty.isPtrAtRuntime(mod))
3627 non_int_val.constPtrToInt(small_int_ty)3516 non_int_val.constPtrToInt(small_int_ty)
3628 else3517 else
...@@ -3658,18 +3547,18 @@ pub const DeclGen = struct {...@@ -3658,18 +3547,18 @@ pub const DeclGen = struct {
36583547
3659 const padding_len = offset - prev_offset;3548 const padding_len = offset - prev_offset;
3660 if (padding_len > 0) {3549 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));
3662 // TODO make this and all other padding elsewhere in debug3551 // TODO make this and all other padding elsewhere in debug
3663 // builds be 0xaa not undef.3552 // builds be 0xaa not undef.
3664 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());3553 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
3665 }3554 }
36663555
3667 const field_llvm_val = try dg.lowerValue(.{3556 const field_llvm_val = try o.lowerValue(.{
3668 .ty = field.ty,3557 .ty = field.ty,
3669 .val = try tv.val.fieldValue(mod, field_and_index.index),3558 .val = try tv.val.fieldValue(mod, field_and_index.index),
3670 });3559 });
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
3674 llvm_fields.appendAssumeCapacity(field_llvm_val);3563 llvm_fields.appendAssumeCapacity(field_llvm_val);
36753564
...@@ -3680,13 +3569,13 @@ pub const DeclGen = struct {...@@ -3680,13 +3569,13 @@ pub const DeclGen = struct {
3680 offset = std.mem.alignForward(u64, offset, big_align);3569 offset = std.mem.alignForward(u64, offset, big_align);
3681 const padding_len = offset - prev_offset;3570 const padding_len = offset - prev_offset;
3682 if (padding_len > 0) {3571 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));
3684 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());3573 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
3685 }3574 }
3686 }3575 }
36873576
3688 if (need_unnamed) {3577 if (need_unnamed) {
3689 return dg.context.constStruct(3578 return o.context.constStruct(
3690 llvm_fields.items.ptr,3579 llvm_fields.items.ptr,
3691 @intCast(c_uint, llvm_fields.items.len),3580 @intCast(c_uint, llvm_fields.items.len),
3692 .False,3581 .False,
...@@ -3701,7 +3590,7 @@ pub const DeclGen = struct {...@@ -3701,7 +3590,7 @@ pub const DeclGen = struct {
3701 else => unreachable,3590 else => unreachable,
3702 },3591 },
3703 .un => {3592 .un => {
3704 const llvm_union_ty = try dg.lowerType(tv.ty);3593 const llvm_union_ty = try o.lowerType(tv.ty);
3705 const tag_and_val: Value.Payload.Union.Data = switch (tv.val.toIntern()) {3594 const tag_and_val: Value.Payload.Union.Data = switch (tv.val.toIntern()) {
3706 .none => tv.val.castTag(.@"union").?.data,3595 .none => tv.val.castTag(.@"union").?.data,
3707 else => switch (mod.intern_pool.indexToKey(tv.val.toIntern())) {3596 else => switch (mod.intern_pool.indexToKey(tv.val.toIntern())) {
...@@ -3713,22 +3602,22 @@ pub const DeclGen = struct {...@@ -3713,22 +3602,22 @@ pub const DeclGen = struct {
3713 const layout = tv.ty.unionGetLayout(mod);3602 const layout = tv.ty.unionGetLayout(mod);
37143603
3715 if (layout.payload_size == 0) {3604 if (layout.payload_size == 0) {
3716 return lowerValue(dg, .{3605 return lowerValue(o, .{
3717 .ty = tv.ty.unionTagTypeSafety(mod).?,3606 .ty = tv.ty.unionTagTypeSafety(mod).?,
3718 .val = tag_and_val.tag,3607 .val = tag_and_val.tag,
3719 });3608 });
3720 }3609 }
3721 const union_obj = mod.typeToUnion(tv.ty).?;3610 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).?;
3723 assert(union_obj.haveFieldTypes());3612 assert(union_obj.haveFieldTypes());
37243613
3725 const field_ty = union_obj.fields.values()[field_index].ty;3614 const field_ty = union_obj.fields.values()[field_index].ty;
3726 if (union_obj.layout == .Packed) {3615 if (union_obj.layout == .Packed) {
3727 if (!field_ty.hasRuntimeBits(mod))3616 if (!field_ty.hasRuntimeBits(mod))
3728 return llvm_union_ty.constNull();3617 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 });
3730 const ty_bit_size = @intCast(u16, field_ty.bitSize(mod));3619 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);
3732 const small_int_val = if (field_ty.isPtrAtRuntime(mod))3621 const small_int_val = if (field_ty.isPtrAtRuntime(mod))
3733 non_int_val.constPtrToInt(small_int_ty)3622 non_int_val.constPtrToInt(small_int_ty)
3734 else3623 else
...@@ -3744,30 +3633,30 @@ pub const DeclGen = struct {...@@ -3744,30 +3633,30 @@ pub const DeclGen = struct {
3744 const payload = p: {3633 const payload = p: {
3745 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {3634 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3746 const padding_len = @intCast(c_uint, layout.payload_size);3635 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();
3748 }3637 }
3749 const field = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val });3638 const field = try lowerValue(o, .{ .ty = field_ty, .val = tag_and_val.val });
3750 need_unnamed = need_unnamed or dg.isUnnamedType(field_ty, field);3639 need_unnamed = need_unnamed or o.isUnnamedType(field_ty, field);
3751 const field_size = field_ty.abiSize(mod);3640 const field_size = field_ty.abiSize(mod);
3752 if (field_size == layout.payload_size) {3641 if (field_size == layout.payload_size) {
3753 break :p field;3642 break :p field;
3754 }3643 }
3755 const padding_len = @intCast(c_uint, layout.payload_size - field_size);3644 const padding_len = @intCast(c_uint, layout.payload_size - field_size);
3756 const fields: [2]*llvm.Value = .{3645 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(),
3758 };3647 };
3759 break :p dg.context.constStruct(&fields, fields.len, .True);3648 break :p o.context.constStruct(&fields, fields.len, .True);
3760 };3649 };
37613650
3762 if (layout.tag_size == 0) {3651 if (layout.tag_size == 0) {
3763 const fields: [1]*llvm.Value = .{payload};3652 const fields: [1]*llvm.Value = .{payload};
3764 if (need_unnamed) {3653 if (need_unnamed) {
3765 return dg.context.constStruct(&fields, fields.len, .False);3654 return o.context.constStruct(&fields, fields.len, .False);
3766 } else {3655 } else {
3767 return llvm_union_ty.constNamedStruct(&fields, fields.len);3656 return llvm_union_ty.constNamedStruct(&fields, fields.len);
3768 }3657 }
3769 }3658 }
3770 const llvm_tag_value = try lowerValue(dg, .{3659 const llvm_tag_value = try lowerValue(o, .{
3771 .ty = tv.ty.unionTagTypeSafety(mod).?,3660 .ty = tv.ty.unionTagTypeSafety(mod).?,
3772 .val = tag_and_val.tag,3661 .val = tag_and_val.tag,
3773 });3662 });
...@@ -3779,11 +3668,11 @@ pub const DeclGen = struct {...@@ -3779,11 +3668,11 @@ pub const DeclGen = struct {
3779 fields = .{ payload, llvm_tag_value, undefined };3668 fields = .{ payload, llvm_tag_value, undefined };
3780 }3669 }
3781 if (layout.padding != 0) {3670 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();
3783 fields_len = 3;3672 fields_len = 3;
3784 }3673 }
3785 if (need_unnamed) {3674 if (need_unnamed) {
3786 return dg.context.constStruct(&fields, fields_len, .False);3675 return o.context.constStruct(&fields, fields_len, .False);
3787 } else {3676 } else {
3788 return llvm_union_ty.constNamedStruct(&fields, fields_len);3677 return llvm_union_ty.constNamedStruct(&fields, fields_len);
3789 }3678 }
...@@ -3792,24 +3681,24 @@ pub const DeclGen = struct {...@@ -3792,24 +3681,24 @@ pub const DeclGen = struct {
3792 }3681 }
3793 }3682 }
37943683
3795 fn lowerIntAsPtr(dg: *DeclGen, val: Value) Error!*llvm.Value {3684 fn lowerIntAsPtr(o: *Object, val: Value) Error!*llvm.Value {
3796 switch (dg.module.intern_pool.indexToKey(val.toIntern())) {3685 switch (o.module.intern_pool.indexToKey(val.toIntern())) {
3797 .undef => return dg.context.pointerType(0).getUndef(),3686 .undef => return o.context.pointerType(0).getUndef(),
3798 .int => {3687 .int => {
3799 var bigint_space: Value.BigIntSpace = undefined;3688 var bigint_space: Value.BigIntSpace = undefined;
3800 const bigint = val.toBigInt(&bigint_space, dg.module);3689 const bigint = val.toBigInt(&bigint_space, o.module);
3801 const llvm_int = lowerBigInt(dg, Type.usize, bigint);3690 const llvm_int = lowerBigInt(o, Type.usize, bigint);
3802 return llvm_int.constIntToPtr(dg.context.pointerType(0));3691 return llvm_int.constIntToPtr(o.context.pointerType(0));
3803 },3692 },
3804 else => unreachable,3693 else => unreachable,
3805 }3694 }
3806 }3695 }
38073696
3808 fn lowerBigInt(dg: *DeclGen, ty: Type, bigint: std.math.big.int.Const) *llvm.Value {3697 fn lowerBigInt(o: *Object, ty: Type, bigint: std.math.big.int.Const) *llvm.Value {
3809 const mod = dg.module;3698 const mod = o.module;
3810 const int_info = ty.intInfo(mod);3699 const int_info = ty.intInfo(mod);
3811 assert(int_info.bits != 0);3700 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
3814 const unsigned_val = v: {3703 const unsigned_val = v: {
3815 if (bigint.limbs.len == 1) {3704 if (bigint.limbs.len == 1) {
...@@ -3835,26 +3724,26 @@ pub const DeclGen = struct {...@@ -3835,26 +3724,26 @@ pub const DeclGen = struct {
3835 };3724 };
38363725
3837 fn lowerParentPtrDecl(3726 fn lowerParentPtrDecl(
3838 dg: *DeclGen,3727 o: *Object,
3839 ptr_val: Value,3728 ptr_val: Value,
3840 decl_index: Module.Decl.Index,3729 decl_index: Module.Decl.Index,
3841 ) Error!*llvm.Value {3730 ) Error!*llvm.Value {
3842 const mod = dg.module;3731 const mod = o.module;
3843 const decl = mod.declPtr(decl_index);3732 const decl = mod.declPtr(decl_index);
3844 try mod.markDeclAlive(decl);3733 try mod.markDeclAlive(decl);
3845 const ptr_ty = try mod.singleMutPtrType(decl.ty);3734 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);
3847 }3736 }
38483737
3849 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {3738 fn lowerParentPtr(o: *Object, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {
3850 const mod = dg.module;3739 const mod = o.module;
3851 const target = mod.getTarget();3740 const target = mod.getTarget();
3852 return switch (mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr) {3741 return switch (mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr) {
3853 .decl => |decl| dg.lowerParentPtrDecl(ptr_val, decl),3742 .decl => |decl| o.lowerParentPtrDecl(ptr_val, decl),
3854 .mut_decl => |mut_decl| dg.lowerParentPtrDecl(ptr_val, mut_decl.decl),3743 .mut_decl => |mut_decl| o.lowerParentPtrDecl(ptr_val, mut_decl.decl),
3855 .int => |int| dg.lowerIntAsPtr(int.toValue()),3744 .int => |int| o.lowerIntAsPtr(int.toValue()),
3856 .eu_payload => |eu_ptr| {3745 .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
3859 const eu_ty = mod.intern_pool.typeOf(eu_ptr).toType().childType(mod);3748 const eu_ty = mod.intern_pool.typeOf(eu_ptr).toType().childType(mod);
3860 const payload_ty = eu_ty.errorUnionPayload(mod);3749 const payload_ty = eu_ty.errorUnionPayload(mod);
...@@ -3865,16 +3754,16 @@ pub const DeclGen = struct {...@@ -3865,16 +3754,16 @@ pub const DeclGen = struct {
3865 }3754 }
38663755
3867 const payload_offset: u8 = if (payload_ty.abiAlignment(mod) > Type.anyerror.abiSize(mod)) 2 else 1;3756 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);
3869 const indices: [2]*llvm.Value = .{3758 const indices: [2]*llvm.Value = .{
3870 llvm_u32.constInt(0, .False),3759 llvm_u32.constInt(0, .False),
3871 llvm_u32.constInt(payload_offset, .False),3760 llvm_u32.constInt(payload_offset, .False),
3872 };3761 };
3873 const eu_llvm_ty = try dg.lowerType(eu_ty);3762 const eu_llvm_ty = try o.lowerType(eu_ty);
3874 return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);3763 return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3875 },3764 },
3876 .opt_payload => |opt_ptr| {3765 .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
3879 const opt_ty = mod.intern_pool.typeOf(opt_ptr).toType().childType(mod);3768 const opt_ty = mod.intern_pool.typeOf(opt_ptr).toType().childType(mod);
3880 const payload_ty = opt_ty.optionalChild(mod);3769 const payload_ty = opt_ty.optionalChild(mod);
...@@ -3886,32 +3775,32 @@ pub const DeclGen = struct {...@@ -3886,32 +3775,32 @@ pub const DeclGen = struct {
3886 return parent_llvm_ptr;3775 return parent_llvm_ptr;
3887 }3776 }
38883777
3889 const llvm_u32 = dg.context.intType(32);3778 const llvm_u32 = o.context.intType(32);
3890 const indices: [2]*llvm.Value = .{3779 const indices: [2]*llvm.Value = .{
3891 llvm_u32.constInt(0, .False),3780 llvm_u32.constInt(0, .False),
3892 llvm_u32.constInt(0, .False),3781 llvm_u32.constInt(0, .False),
3893 };3782 };
3894 const opt_llvm_ty = try dg.lowerType(opt_ty);3783 const opt_llvm_ty = try o.lowerType(opt_ty);
3895 return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);3784 return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3896 },3785 },
3897 .comptime_field => unreachable,3786 .comptime_field => unreachable,
3898 .elem => |elem_ptr| {3787 .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);
3902 const indices: [1]*llvm.Value = .{3791 const indices: [1]*llvm.Value = .{
3903 llvm_usize.constInt(elem_ptr.index, .False),3792 llvm_usize.constInt(elem_ptr.index, .False),
3904 };3793 };
3905 const elem_ty = mod.intern_pool.typeOf(elem_ptr.base).toType().elemType2(mod);3794 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);
3907 return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);3796 return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3908 },3797 },
3909 .field => |field_ptr| {3798 .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);
3911 const parent_ty = mod.intern_pool.typeOf(field_ptr.base).toType().childType(mod);3800 const parent_ty = mod.intern_pool.typeOf(field_ptr.base).toType().childType(mod);
39123801
3913 const field_index = @intCast(u32, field_ptr.index);3802 const field_index = @intCast(u32, field_ptr.index);
3914 const llvm_u32 = dg.context.intType(32);3803 const llvm_u32 = o.context.intType(32);
3915 switch (parent_ty.zigTypeTag(mod)) {3804 switch (parent_ty.zigTypeTag(mod)) {
3916 .Union => {3805 .Union => {
3917 if (parent_ty.containerLayout(mod) == .Packed) {3806 if (parent_ty.containerLayout(mod) == .Packed) {
...@@ -3932,13 +3821,13 @@ pub const DeclGen = struct {...@@ -3932,13 +3821,13 @@ pub const DeclGen = struct {
3932 llvm_u32.constInt(0, .False),3821 llvm_u32.constInt(0, .False),
3933 llvm_u32.constInt(llvm_pl_index, .False),3822 llvm_u32.constInt(llvm_pl_index, .False),
3934 };3823 };
3935 const parent_llvm_ty = try dg.lowerType(parent_ty);3824 const parent_llvm_ty = try o.lowerType(parent_ty);
3936 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);3825 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3937 },3826 },
3938 .Struct => {3827 .Struct => {
3939 if (parent_ty.containerLayout(mod) == .Packed) {3828 if (parent_ty.containerLayout(mod) == .Packed) {
3940 if (!byte_aligned) return parent_llvm_ptr;3829 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());
3942 const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);3831 const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);
3943 // count bits of fields before this one3832 // count bits of fields before this one
3944 const prev_bits = b: {3833 const prev_bits = b: {
...@@ -3951,11 +3840,11 @@ pub const DeclGen = struct {...@@ -3951,11 +3840,11 @@ pub const DeclGen = struct {
3951 };3840 };
3952 const byte_offset = llvm_usize.constInt(prev_bits / 8, .False);3841 const byte_offset = llvm_usize.constInt(prev_bits / 8, .False);
3953 const field_addr = base_addr.constAdd(byte_offset);3842 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);
3955 return field_addr.constIntToPtr(final_llvm_ty);3844 return field_addr.constIntToPtr(final_llvm_ty);
3956 }3845 }
39573846
3958 const parent_llvm_ty = try dg.lowerType(parent_ty);3847 const parent_llvm_ty = try o.lowerType(parent_ty);
3959 if (llvmField(parent_ty, field_index, mod)) |llvm_field| {3848 if (llvmField(parent_ty, field_index, mod)) |llvm_field| {
3960 const indices: [2]*llvm.Value = .{3849 const indices: [2]*llvm.Value = .{
3961 llvm_u32.constInt(0, .False),3850 llvm_u32.constInt(0, .False),
...@@ -3974,7 +3863,7 @@ pub const DeclGen = struct {...@@ -3974,7 +3863,7 @@ pub const DeclGen = struct {
3974 llvm_u32.constInt(0, .False),3863 llvm_u32.constInt(0, .False),
3975 llvm_u32.constInt(field_index, .False),3864 llvm_u32.constInt(field_index, .False),
3976 };3865 };
3977 const parent_llvm_ty = try dg.lowerType(parent_ty);3866 const parent_llvm_ty = try o.lowerType(parent_ty);
3978 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);3867 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3979 },3868 },
3980 else => unreachable,3869 else => unreachable,
...@@ -3984,11 +3873,11 @@ pub const DeclGen = struct {...@@ -3984,11 +3873,11 @@ pub const DeclGen = struct {
3984 }3873 }
39853874
3986 fn lowerDeclRefValue(3875 fn lowerDeclRefValue(
3987 self: *DeclGen,3876 o: *Object,
3988 tv: TypedValue,3877 tv: TypedValue,
3989 decl_index: Module.Decl.Index,3878 decl_index: Module.Decl.Index,
3990 ) Error!*llvm.Value {3879 ) Error!*llvm.Value {
3991 const mod = self.module;3880 const mod = o.module;
39923881
3993 // In the case of something like:3882 // In the case of something like:
3994 // fn foo() void {}3883 // fn foo() void {}
...@@ -3998,11 +3887,11 @@ pub const DeclGen = struct {...@@ -3998,11 +3887,11 @@ pub const DeclGen = struct {
3998 const decl = mod.declPtr(decl_index);3887 const decl = mod.declPtr(decl_index);
3999 if (decl.val.getFunction(mod)) |func| {3888 if (decl.val.getFunction(mod)) |func| {
4000 if (func.owner_decl != decl_index) {3889 if (func.owner_decl != decl_index) {
4001 return self.lowerDeclRefValue(tv, func.owner_decl);3890 return o.lowerDeclRefValue(tv, func.owner_decl);
4002 }3891 }
4003 } else if (decl.val.getExternFunc(mod)) |func| {3892 } else if (decl.val.getExternFunc(mod)) |func| {
4004 if (func.decl != decl_index) {3893 if (func.decl != decl_index) {
4005 return self.lowerDeclRefValue(tv, func.decl);3894 return o.lowerDeclRefValue(tv, func.decl);
4006 }3895 }
4007 }3896 }
40083897
...@@ -4010,25 +3899,25 @@ pub const DeclGen = struct {...@@ -4010,25 +3899,25 @@ pub const DeclGen = struct {
4010 if ((!is_fn_body and !decl.ty.hasRuntimeBits(mod)) or3899 if ((!is_fn_body and !decl.ty.hasRuntimeBits(mod)) or
4011 (is_fn_body and mod.typeToFunc(decl.ty).?.is_generic))3900 (is_fn_body and mod.typeToFunc(decl.ty).?.is_generic))
4012 {3901 {
4013 return self.lowerPtrToVoid(tv.ty);3902 return o.lowerPtrToVoid(tv.ty);
4014 }3903 }
40153904
4016 try mod.markDeclAlive(decl);3905 try mod.markDeclAlive(decl);
40173906
4018 const llvm_decl_val = if (is_fn_body)3907 const llvm_decl_val = if (is_fn_body)
4019 try self.resolveLlvmFunction(decl_index)3908 try o.resolveLlvmFunction(decl_index)
4020 else3909 else
4021 try self.resolveGlobalDecl(decl_index);3910 try o.resolveGlobalDecl(decl_index);
40223911
4023 const target = mod.getTarget();3912 const target = mod.getTarget();
4024 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);3913 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
4025 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);3914 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);
4026 const llvm_val = if (llvm_wanted_addrspace != llvm_actual_addrspace) blk: {3915 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);
4028 break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty);3917 break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty);
4029 } else llvm_decl_val;3918 } else llvm_decl_val;
40303919
4031 const llvm_type = try self.lowerType(tv.ty);3920 const llvm_type = try o.lowerType(tv.ty);
4032 if (tv.ty.zigTypeTag(mod) == .Int) {3921 if (tv.ty.zigTypeTag(mod) == .Int) {
4033 return llvm_val.constPtrToInt(llvm_type);3922 return llvm_val.constPtrToInt(llvm_type);
4034 } else {3923 } else {
...@@ -4036,15 +3925,15 @@ pub const DeclGen = struct {...@@ -4036,15 +3925,15 @@ pub const DeclGen = struct {
4036 }3925 }
4037 }3926 }
40383927
4039 fn lowerPtrToVoid(dg: *DeclGen, ptr_ty: Type) !*llvm.Value {3928 fn lowerPtrToVoid(o: *Object, ptr_ty: Type) !*llvm.Value {
4040 const mod = dg.module;3929 const mod = o.module;
4041 // Even though we are pointing at something which has zero bits (e.g. `void`),3930 // Even though we are pointing at something which has zero bits (e.g. `void`),
4042 // Pointers are defined to have bits. So we must return something here.3931 // Pointers are defined to have bits. So we must return something here.
4043 // The value cannot be undefined, because we use the `nonnull` annotation3932 // The value cannot be undefined, because we use the `nonnull` annotation
4044 // for non-optional pointers. We also need to respect the alignment, even though3933 // for non-optional pointers. We also need to respect the alignment, even though
4045 // the address will never be dereferenced.3934 // the address will never be dereferenced.
4046 const llvm_usize = try dg.lowerType(Type.usize);3935 const llvm_usize = try o.lowerType(Type.usize);
4047 const llvm_ptr_ty = try dg.lowerType(ptr_ty);3936 const llvm_ptr_ty = try o.lowerType(ptr_ty);
4048 if (ptr_ty.ptrInfo(mod).flags.alignment.toByteUnitsOptional()) |alignment| {3937 if (ptr_ty.ptrInfo(mod).flags.alignment.toByteUnitsOptional()) |alignment| {
4049 return llvm_usize.constInt(alignment, .False).constIntToPtr(llvm_ptr_ty);3938 return llvm_usize.constInt(alignment, .False).constIntToPtr(llvm_ptr_ty);
4050 }3939 }
...@@ -4053,7 +3942,7 @@ pub const DeclGen = struct {...@@ -4053,7 +3942,7 @@ pub const DeclGen = struct {
4053 // have an "undef_but_not_null" attribute. As an example, if this `alloc` AIR3942 // have an "undef_but_not_null" attribute. As an example, if this `alloc` AIR
4054 // instruction is followed by a `wrap_optional`, it will return this value3943 // instruction is followed by a `wrap_optional`, it will return this value
4055 // verbatim, and the result should test as non-null.3944 // verbatim, and the result should test as non-null.
4056 const target = dg.module.getTarget();3945 const target = mod.getTarget();
4057 const int = switch (target.ptrBitWidth()) {3946 const int = switch (target.ptrBitWidth()) {
4058 16 => llvm_usize.constInt(0xaaaa, .False),3947 16 => llvm_usize.constInt(0xaaaa, .False),
4059 32 => llvm_usize.constInt(0xaaaaaaaa, .False),3948 32 => llvm_usize.constInt(0xaaaaaaaa, .False),
...@@ -4063,16 +3952,16 @@ pub const DeclGen = struct {...@@ -4063,16 +3952,16 @@ pub const DeclGen = struct {
4063 return int.constIntToPtr(llvm_ptr_ty);3952 return int.constIntToPtr(llvm_ptr_ty);
4064 }3953 }
40653954
4066 fn addAttr(dg: DeclGen, val: *llvm.Value, index: llvm.AttributeIndex, name: []const u8) void {3955 fn addAttr(o: *Object, val: *llvm.Value, index: llvm.AttributeIndex, name: []const u8) void {
4067 return dg.addAttrInt(val, index, name, 0);3956 return o.addAttrInt(val, index, name, 0);
4068 }3957 }
40693958
4070 fn addArgAttr(dg: DeclGen, fn_val: *llvm.Value, param_index: u32, attr_name: []const u8) void {3959 fn addArgAttr(o: *Object, fn_val: *llvm.Value, param_index: u32, attr_name: []const u8) void {
4071 return dg.addAttr(fn_val, param_index + 1, attr_name);3960 return o.addAttr(fn_val, param_index + 1, attr_name);
4072 }3961 }
40733962
4074 fn addArgAttrInt(dg: DeclGen, fn_val: *llvm.Value, param_index: u32, attr_name: []const u8, int: u64) void {3963 fn addArgAttrInt(o: *Object, 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);3964 return o.addAttrInt(fn_val, param_index + 1, attr_name, int);
4076 }3965 }
40773966
4078 fn removeAttr(val: *llvm.Value, index: llvm.AttributeIndex, name: []const u8) void {3967 fn removeAttr(val: *llvm.Value, index: llvm.AttributeIndex, name: []const u8) void {
...@@ -4082,7 +3971,7 @@ pub const DeclGen = struct {...@@ -4082,7 +3971,7 @@ pub const DeclGen = struct {
4082 }3971 }
40833972
4084 fn addAttrInt(3973 fn addAttrInt(
4085 dg: DeclGen,3974 o: *Object,
4086 val: *llvm.Value,3975 val: *llvm.Value,
4087 index: llvm.AttributeIndex,3976 index: llvm.AttributeIndex,
4088 name: []const u8,3977 name: []const u8,
...@@ -4090,18 +3979,18 @@ pub const DeclGen = struct {...@@ -4090,18 +3979,18 @@ pub const DeclGen = struct {
4090 ) void {3979 ) void {
4091 const kind_id = llvm.getEnumAttributeKindForName(name.ptr, name.len);3980 const kind_id = llvm.getEnumAttributeKindForName(name.ptr, name.len);
4092 assert(kind_id != 0);3981 assert(kind_id != 0);
4093 const llvm_attr = dg.context.createEnumAttribute(kind_id, int);3982 const llvm_attr = o.context.createEnumAttribute(kind_id, int);
4094 val.addAttributeAtIndex(index, llvm_attr);3983 val.addAttributeAtIndex(index, llvm_attr);
4095 }3984 }
40963985
4097 fn addAttrString(3986 fn addAttrString(
4098 dg: *DeclGen,3987 o: *Object,
4099 val: *llvm.Value,3988 val: *llvm.Value,
4100 index: llvm.AttributeIndex,3989 index: llvm.AttributeIndex,
4101 name: []const u8,3990 name: []const u8,
4102 value: []const u8,3991 value: []const u8,
4103 ) void {3992 ) void {
4104 const llvm_attr = dg.context.createStringAttribute(3993 const llvm_attr = o.context.createStringAttribute(
4105 name.ptr,3994 name.ptr,
4106 @intCast(c_uint, name.len),3995 @intCast(c_uint, name.len),
4107 value.ptr,3996 value.ptr,
...@@ -4110,94 +3999,193 @@ pub const DeclGen = struct {...@@ -4110,94 +3999,193 @@ pub const DeclGen = struct {
4110 val.addAttributeAtIndex(index, llvm_attr);3999 val.addAttributeAtIndex(index, llvm_attr);
4111 }4000 }
41124001
4113 fn addFnAttr(dg: DeclGen, val: *llvm.Value, name: []const u8) void {4002 fn addFnAttr(o: *Object, val: *llvm.Value, name: []const u8) void {
4114 dg.addAttr(val, std.math.maxInt(llvm.AttributeIndex), name);4003 o.addAttr(val, std.math.maxInt(llvm.AttributeIndex), name);
4115 }4004 }
41164005
4117 fn addFnAttrString(dg: *DeclGen, val: *llvm.Value, name: []const u8, value: []const u8) void {4006 fn addFnAttrString(o: *Object, val: *llvm.Value, name: []const u8, value: []const u8) void {
4118 dg.addAttrString(val, std.math.maxInt(llvm.AttributeIndex), name, value);4007 o.addAttrString(val, std.math.maxInt(llvm.AttributeIndex), name, value);
4119 }4008 }
41204009
4121 fn removeFnAttr(fn_val: *llvm.Value, name: []const u8) void {4010 fn removeFnAttr(fn_val: *llvm.Value, name: []const u8) void {
4122 removeAttr(fn_val, std.math.maxInt(llvm.AttributeIndex), name);4011 removeAttr(fn_val, std.math.maxInt(llvm.AttributeIndex), name);
4123 }4012 }
41244013
4125 fn addFnAttrInt(dg: DeclGen, fn_val: *llvm.Value, name: []const u8, int: u64) void {4014 fn addFnAttrInt(o: *Object, fn_val: *llvm.Value, name: []const u8, int: u64) void {
4126 return dg.addAttrInt(fn_val, std.math.maxInt(llvm.AttributeIndex), name, int);4015 return o.addAttrInt(fn_val, std.math.maxInt(llvm.AttributeIndex), name, int);
4127 }4016 }
41284017
4129 /// If the operand type of an atomic operation is not byte sized we need to4018 /// If the operand type of an atomic operation is not byte sized we need to
4130 /// widen it before using it and then truncate the result.4019 /// widen it before using it and then truncate the result.
4131 /// RMW exchange of floating-point values is bitcasted to same-sized integer4020 /// RMW exchange of floating-point values is bitcasted to same-sized integer
4132 /// types to work around a LLVM deficiency when targeting ARM/AArch64.4021 /// types to work around a LLVM deficiency when targeting ARM/AArch64.
4133 fn getAtomicAbiType(dg: *DeclGen, ty: Type, is_rmw_xchg: bool) ?*llvm.Type {4022 fn getAtomicAbiType(o: *Object, ty: Type, is_rmw_xchg: bool) ?*llvm.Type {
4134 const mod = dg.module;4023 const mod = o.module;
4135 const int_ty = switch (ty.zigTypeTag(mod)) {4024 const int_ty = switch (ty.zigTypeTag(mod)) {
4136 .Int => ty,4025 .Int => ty,
4137 .Enum => ty.intTagType(mod),4026 .Enum => ty.intTagType(mod),
4138 .Float => {4027 .Float => {
4139 if (!is_rmw_xchg) return null;4028 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));
4141 },4030 },
4142 .Bool => return dg.context.intType(8),4031 .Bool => return o.context.intType(8),
4143 else => return null,4032 else => return null,
4144 };4033 };
4145 const bit_count = int_ty.intInfo(mod).bits;4034 const bit_count = int_ty.intInfo(mod).bits;
4146 if (!std.math.isPowerOfTwo(bit_count) or (bit_count % 8) != 0) {4035 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));
4148 } else {4037 } else {
4149 return null;4038 return null;
4150 }4039 }
4151 }4040 }
41524041
4153 fn addByValParamAttrs(4042 fn addByValParamAttrs(
4154 dg: DeclGen,4043 o: *Object,
4155 llvm_fn: *llvm.Value,4044 llvm_fn: *llvm.Value,
4156 param_ty: Type,4045 param_ty: Type,
4157 param_index: u32,4046 param_index: u32,
4158 fn_info: InternPool.Key.FuncType,4047 fn_info: InternPool.Key.FuncType,
4159 llvm_arg_i: u32,4048 llvm_arg_i: u32,
4160 ) void {4049 ) void {
4161 const mod = dg.module;4050 const mod = o.module;
4162 if (param_ty.isPtrAtRuntime(mod)) {4051 if (param_ty.isPtrAtRuntime(mod)) {
4163 const ptr_info = param_ty.ptrInfo(mod);4052 const ptr_info = param_ty.ptrInfo(mod);
4164 if (math.cast(u5, param_index)) |i| {4053 if (math.cast(u5, param_index)) |i| {
4165 if (@truncate(u1, fn_info.noalias_bits >> i) != 0) {4054 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");
4167 }4056 }
4168 }4057 }
4169 if (!param_ty.isPtrLikeOptional(mod) and !ptr_info.flags.is_allowzero) {4058 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");
4171 }4060 }
4172 if (ptr_info.flags.is_const) {4061 if (ptr_info.flags.is_const) {
4173 dg.addArgAttr(llvm_fn, llvm_arg_i, "readonly");4062 o.addArgAttr(llvm_fn, llvm_arg_i, "readonly");
4174 }4063 }
4175 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse4064 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse
4176 @max(ptr_info.child.toType().abiAlignment(mod), 1);4065 @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);
4178 } else if (ccAbiPromoteInt(fn_info.cc, mod, param_ty)) |s| switch (s) {4067 } else if (ccAbiPromoteInt(fn_info.cc, mod, param_ty)) |s| switch (s) {
4179 .signed => dg.addArgAttr(llvm_fn, llvm_arg_i, "signext"),4068 .signed => o.addArgAttr(llvm_fn, llvm_arg_i, "signext"),
4180 .unsigned => dg.addArgAttr(llvm_fn, llvm_arg_i, "zeroext"),4069 .unsigned => o.addArgAttr(llvm_fn, llvm_arg_i, "zeroext"),
4181 };4070 };
4182 }4071 }
41834072
4184 fn addByRefParamAttrs(4073 fn addByRefParamAttrs(
4185 dg: DeclGen,4074 o: *Object,
4186 llvm_fn: *llvm.Value,4075 llvm_fn: *llvm.Value,
4187 llvm_arg_i: u32,4076 llvm_arg_i: u32,
4188 alignment: u32,4077 alignment: u32,
4189 byval_attr: bool,4078 byval_attr: bool,
4190 param_llvm_ty: *llvm.Type,4079 param_llvm_ty: *llvm.Type,
4191 ) void {4080 ) void {
4192 dg.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");4081 o.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");
4193 dg.addArgAttr(llvm_fn, llvm_arg_i, "readonly");4082 o.addArgAttr(llvm_fn, llvm_arg_i, "readonly");
4194 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", alignment);4083 o.addArgAttrInt(llvm_fn, llvm_arg_i, "align", alignment);
4195 if (byval_attr) {4084 if (byval_attr) {
4196 llvm_fn.addByValAttr(llvm_arg_i, param_llvm_ty);4085 llvm_fn.addByValAttr(llvm_arg_i, param_llvm_ty);
4197 }4086 }
4198 }4087 }
4199};4088};
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
4201pub const FuncGen = struct {4189pub const FuncGen = struct {
4202 gpa: Allocator,4190 gpa: Allocator,
4203 dg: *DeclGen,4191 dg: *DeclGen,
...@@ -4268,15 +4256,13 @@ pub const FuncGen = struct {...@@ -4268,15 +4256,13 @@ pub const FuncGen = struct {
4268 return self.dg.todo(format, args);4256 return self.dg.todo(format, args);
4269 }4257 }
42704258
4271 fn llvmModule(self: *FuncGen) *llvm.Module {
4272 return self.dg.object.llvm_module;
4273 }
4274
4275 fn resolveInst(self: *FuncGen, inst: Air.Inst.Ref) !*llvm.Value {4259 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);
4277 if (gop.found_existing) return gop.value_ptr.*;4262 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;
4280 const llvm_val = try self.resolveValue(.{4266 const llvm_val = try self.resolveValue(.{
4281 .ty = self.typeOf(inst),4267 .ty = self.typeOf(inst),
4282 .val = (try self.air.value(inst, mod)).?,4268 .val = (try self.air.value(inst, mod)).?,
...@@ -4286,8 +4272,9 @@ pub const FuncGen = struct {...@@ -4286,8 +4272,9 @@ pub const FuncGen = struct {
4286 }4272 }
42874273
4288 fn resolveValue(self: *FuncGen, tv: TypedValue) !*llvm.Value {4274 fn resolveValue(self: *FuncGen, tv: TypedValue) !*llvm.Value {
4289 const mod = self.dg.module;4275 const o = self.dg.object;
4290 const llvm_val = try self.dg.lowerValue(tv);4276 const mod = o.module;
4277 const llvm_val = try o.lowerValue(tv);
4291 if (!isByRef(tv.ty, mod)) return llvm_val;4278 if (!isByRef(tv.ty, mod)) return llvm_val;
42924279
4293 // We have an LLVM value but we need to create a global constant and4280 // We have an LLVM value but we need to create a global constant and
...@@ -4295,7 +4282,7 @@ pub const FuncGen = struct {...@@ -4295,7 +4282,7 @@ pub const FuncGen = struct {
4295 const target = mod.getTarget();4282 const target = mod.getTarget();
4296 const llvm_wanted_addrspace = toLlvmAddressSpace(.generic, target);4283 const llvm_wanted_addrspace = toLlvmAddressSpace(.generic, target);
4297 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(.generic, target);4284 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);
4299 global.setInitializer(llvm_val);4286 global.setInitializer(llvm_val);
4300 global.setLinkage(.Private);4287 global.setLinkage(.Private);
4301 global.setGlobalConstant(.True);4288 global.setGlobalConstant(.True);
...@@ -4309,7 +4296,8 @@ pub const FuncGen = struct {...@@ -4309,7 +4296,8 @@ pub const FuncGen = struct {
4309 }4296 }
43104297
4311 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {4298 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;
4313 const ip = &mod.intern_pool;4301 const ip = &mod.intern_pool;
4314 const air_tags = self.air.instructions.items(.tag);4302 const air_tags = self.air.instructions.items(.tag);
4315 for (body, 0..) |inst, i| {4303 for (body, 0..) |inst, i| {
...@@ -4563,7 +4551,8 @@ pub const FuncGen = struct {...@@ -4563,7 +4551,8 @@ pub const FuncGen = struct {
4563 const pl_op = self.air.instructions.items(.data)[inst].pl_op;4551 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
4564 const extra = self.air.extraData(Air.Call, pl_op.payload);4552 const extra = self.air.extraData(Air.Call, pl_op.payload);
4565 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);4553 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;
4567 const callee_ty = self.typeOf(pl_op.operand);4556 const callee_ty = self.typeOf(pl_op.operand);
4568 const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) {4557 const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) {
4569 .Fn => callee_ty,4558 .Fn => callee_ty,
...@@ -4580,26 +4569,26 @@ pub const FuncGen = struct {...@@ -4580,26 +4569,26 @@ pub const FuncGen = struct {
4580 defer llvm_args.deinit();4569 defer llvm_args.deinit();
45814570
4582 const ret_ptr = if (!sret) null else blk: {4571 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);
4584 const ret_ptr = self.buildAlloca(llvm_ret_ty, return_type.abiAlignment(mod));4573 const ret_ptr = self.buildAlloca(llvm_ret_ty, return_type.abiAlignment(mod));
4585 try llvm_args.append(ret_ptr);4574 try llvm_args.append(ret_ptr);
4586 break :blk ret_ptr;4575 break :blk ret_ptr;
4587 };4576 };
45884577
4589 const err_return_tracing = return_type.isError(mod) and4578 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;
4591 if (err_return_tracing) {4580 if (err_return_tracing) {
4592 try llvm_args.append(self.err_ret_trace.?);4581 try llvm_args.append(self.err_ret_trace.?);
4593 }4582 }
45944583
4595 var it = iterateParamTypes(self.dg, fn_info);4584 var it = iterateParamTypes(o, fn_info);
4596 while (it.nextCall(self, args)) |lowering| switch (lowering) {4585 while (it.nextCall(self, args)) |lowering| switch (lowering) {
4597 .no_bits => continue,4586 .no_bits => continue,
4598 .byval => {4587 .byval => {
4599 const arg = args[it.zig_index - 1];4588 const arg = args[it.zig_index - 1];
4600 const param_ty = self.typeOf(arg);4589 const param_ty = self.typeOf(arg);
4601 const llvm_arg = try self.resolveInst(arg);4590 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);
4603 if (isByRef(param_ty, mod)) {4592 if (isByRef(param_ty, mod)) {
4604 const alignment = param_ty.abiAlignment(mod);4593 const alignment = param_ty.abiAlignment(mod);
4605 const load_inst = self.builder.buildLoad(llvm_param_ty, llvm_arg, "");4594 const load_inst = self.builder.buildLoad(llvm_param_ty, llvm_arg, "");
...@@ -4630,7 +4619,7 @@ pub const FuncGen = struct {...@@ -4630,7 +4619,7 @@ pub const FuncGen = struct {
4630 const llvm_arg = try self.resolveInst(arg);4619 const llvm_arg = try self.resolveInst(arg);
46314620
4632 const alignment = param_ty.abiAlignment(mod);4621 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);
4634 const arg_ptr = self.buildAlloca(param_llvm_ty, alignment);4623 const arg_ptr = self.buildAlloca(param_llvm_ty, alignment);
4635 if (isByRef(param_ty, mod)) {4624 if (isByRef(param_ty, mod)) {
4636 const load_inst = self.builder.buildLoad(param_llvm_ty, llvm_arg, "");4625 const load_inst = self.builder.buildLoad(param_llvm_ty, llvm_arg, "");
...@@ -4662,7 +4651,7 @@ pub const FuncGen = struct {...@@ -4662,7 +4651,7 @@ pub const FuncGen = struct {
4662 // a local, store as one type, and then load as another type.4651 // a local, store as one type, and then load as another type.
4663 const alignment = @max(4652 const alignment = @max(
4664 param_ty.abiAlignment(mod),4653 param_ty.abiAlignment(mod),
4665 self.dg.object.target_data.abiAlignmentOfType(int_llvm_ty),4654 o.target_data.abiAlignmentOfType(int_llvm_ty),
4666 );4655 );
4667 const int_ptr = self.buildAlloca(int_llvm_ty, alignment);4656 const int_ptr = self.buildAlloca(int_llvm_ty, alignment);
4668 const store_inst = self.builder.buildStore(llvm_arg, int_ptr);4657 const store_inst = self.builder.buildStore(llvm_arg, int_ptr);
...@@ -4721,7 +4710,7 @@ pub const FuncGen = struct {...@@ -4721,7 +4710,7 @@ pub const FuncGen = struct {
4721 llvm_arg = store_inst;4710 llvm_arg = store_inst;
4722 }4711 }
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).?);
4725 const array_llvm_ty = float_ty.arrayType(count);4714 const array_llvm_ty = float_ty.arrayType(count);
47264715
4727 const alignment = arg_ty.abiAlignment(mod);4716 const alignment = arg_ty.abiAlignment(mod);
...@@ -4750,7 +4739,7 @@ pub const FuncGen = struct {...@@ -4750,7 +4739,7 @@ pub const FuncGen = struct {
4750 };4739 };
47514740
4752 const call = self.builder.buildCall(4741 const call = self.builder.buildCall(
4753 try self.dg.lowerType(zig_fn_ty),4742 try o.lowerType(zig_fn_ty),
4754 llvm_fn,4743 llvm_fn,
4755 llvm_args.items.ptr,4744 llvm_args.items.ptr,
4756 @intCast(c_uint, llvm_args.items.len),4745 @intCast(c_uint, llvm_args.items.len),
...@@ -4761,7 +4750,7 @@ pub const FuncGen = struct {...@@ -4761,7 +4750,7 @@ pub const FuncGen = struct {
47614750
4762 if (callee_ty.zigTypeTag(mod) == .Pointer) {4751 if (callee_ty.zigTypeTag(mod) == .Pointer) {
4763 // Add argument attributes for function pointer calls.4752 // Add argument attributes for function pointer calls.
4764 it = iterateParamTypes(self.dg, fn_info);4753 it = iterateParamTypes(o, fn_info);
4765 it.llvm_index += @intFromBool(sret);4754 it.llvm_index += @intFromBool(sret);
4766 it.llvm_index += @intFromBool(err_return_tracing);4755 it.llvm_index += @intFromBool(err_return_tracing);
4767 while (it.next()) |lowering| switch (lowering) {4756 while (it.next()) |lowering| switch (lowering) {
...@@ -4769,18 +4758,18 @@ pub const FuncGen = struct {...@@ -4769,18 +4758,18 @@ pub const FuncGen = struct {
4769 const param_index = it.zig_index - 1;4758 const param_index = it.zig_index - 1;
4770 const param_ty = fn_info.param_types[param_index].toType();4759 const param_ty = fn_info.param_types[param_index].toType();
4771 if (!isByRef(param_ty, mod)) {4760 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);
4773 }4762 }
4774 },4763 },
4775 .byref => {4764 .byref => {
4776 const param_index = it.zig_index - 1;4765 const param_index = it.zig_index - 1;
4777 const param_ty = fn_info.param_types[param_index].toType();4766 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);
4779 const alignment = param_ty.abiAlignment(mod);4768 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);
4781 },4770 },
4782 .byref_mut => {4771 .byref_mut => {
4783 self.dg.addArgAttr(call, it.llvm_index - 1, "noundef");4772 o.addArgAttr(call, it.llvm_index - 1, "noundef");
4784 },4773 },
4785 // No attributes needed for these.4774 // No attributes needed for these.
4786 .no_bits,4775 .no_bits,
...@@ -4800,18 +4789,18 @@ pub const FuncGen = struct {...@@ -4800,18 +4789,18 @@ pub const FuncGen = struct {
48004789
4801 if (math.cast(u5, it.zig_index - 1)) |i| {4790 if (math.cast(u5, it.zig_index - 1)) |i| {
4802 if (@truncate(u1, fn_info.noalias_bits >> i) != 0) {4791 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");
4804 }4793 }
4805 }4794 }
4806 if (param_ty.zigTypeTag(mod) != .Optional) {4795 if (param_ty.zigTypeTag(mod) != .Optional) {
4807 self.dg.addArgAttr(call, llvm_arg_i, "nonnull");4796 o.addArgAttr(call, llvm_arg_i, "nonnull");
4808 }4797 }
4809 if (ptr_info.flags.is_const) {4798 if (ptr_info.flags.is_const) {
4810 self.dg.addArgAttr(call, llvm_arg_i, "readonly");4799 o.addArgAttr(call, llvm_arg_i, "readonly");
4811 }4800 }
4812 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse4801 const elem_align = ptr_info.flags.alignment.toByteUnitsOptional() orelse
4813 @max(ptr_info.child.toType().abiAlignment(mod), 1);4802 @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);
4815 },4804 },
4816 };4805 };
4817 }4806 }
...@@ -4824,7 +4813,7 @@ pub const FuncGen = struct {...@@ -4824,7 +4813,7 @@ pub const FuncGen = struct {
4824 return null;4813 return null;
4825 }4814 }
48264815
4827 const llvm_ret_ty = try self.dg.lowerType(return_type);4816 const llvm_ret_ty = try o.lowerType(return_type);
48284817
4829 if (ret_ptr) |rp| {4818 if (ret_ptr) |rp| {
4830 call.setCallSret(llvm_ret_ty);4819 call.setCallSret(llvm_ret_ty);
...@@ -4838,13 +4827,13 @@ pub const FuncGen = struct {...@@ -4838,13 +4827,13 @@ pub const FuncGen = struct {
4838 }4827 }
4839 }4828 }
48404829
4841 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);4830 const abi_ret_ty = try lowerFnRetTy(o, fn_info);
48424831
4843 if (abi_ret_ty != llvm_ret_ty) {4832 if (abi_ret_ty != llvm_ret_ty) {
4844 // In this case the function return type is honoring the calling convention by having4833 // In this case the function return type is honoring the calling convention by having
4845 // a different LLVM type than the usual one. We solve this here at the callsite4834 // a different LLVM type than the usual one. We solve this here at the callsite
4846 // by using our canonical type, then loading it if necessary.4835 // 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);
4848 const rp = self.buildAlloca(llvm_ret_ty, alignment);4837 const rp = self.buildAlloca(llvm_ret_ty, alignment);
4849 const store_inst = self.builder.buildStore(call, rp);4838 const store_inst = self.builder.buildStore(call, rp);
4850 store_inst.setAlignment(alignment);4839 store_inst.setAlignment(alignment);
...@@ -4871,7 +4860,8 @@ pub const FuncGen = struct {...@@ -4871,7 +4860,8 @@ pub const FuncGen = struct {
4871 }4860 }
48724861
4873 fn airRet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {4862 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;
4875 const un_op = self.air.instructions.items(.data)[inst].un_op;4865 const un_op = self.air.instructions.items(.data)[inst].un_op;
4876 const ret_ty = self.typeOf(un_op);4866 const ret_ty = self.typeOf(un_op);
4877 if (self.ret_ptr) |ret_ptr| {4867 if (self.ret_ptr) |ret_ptr| {
...@@ -4887,7 +4877,7 @@ pub const FuncGen = struct {...@@ -4887,7 +4877,7 @@ pub const FuncGen = struct {
4887 // Functions with an empty error set are emitted with an error code4877 // Functions with an empty error set are emitted with an error code
4888 // return type and return zero so they can be function pointers coerced4878 // return type and return zero so they can be function pointers coerced
4889 // to functions that return anyerror.4879 // to functions that return anyerror.
4890 const err_int = try self.dg.lowerType(Type.anyerror);4880 const err_int = try o.lowerType(Type.anyerror);
4891 _ = self.builder.buildRet(err_int.constInt(0, .False));4881 _ = self.builder.buildRet(err_int.constInt(0, .False));
4892 } else {4882 } else {
4893 _ = self.builder.buildRetVoid();4883 _ = self.builder.buildRetVoid();
...@@ -4895,7 +4885,7 @@ pub const FuncGen = struct {...@@ -4895,7 +4885,7 @@ pub const FuncGen = struct {
4895 return null;4885 return null;
4896 }4886 }
48974887
4898 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);4888 const abi_ret_ty = try lowerFnRetTy(o, fn_info);
4899 const operand = try self.resolveInst(un_op);4889 const operand = try self.resolveInst(un_op);
4900 const alignment = ret_ty.abiAlignment(mod);4890 const alignment = ret_ty.abiAlignment(mod);
49014891
...@@ -4924,7 +4914,8 @@ pub const FuncGen = struct {...@@ -4924,7 +4914,8 @@ pub const FuncGen = struct {
4924 }4914 }
49254915
4926 fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {4916 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;
4928 const un_op = self.air.instructions.items(.data)[inst].un_op;4919 const un_op = self.air.instructions.items(.data)[inst].un_op;
4929 const ptr_ty = self.typeOf(un_op);4920 const ptr_ty = self.typeOf(un_op);
4930 const ret_ty = ptr_ty.childType(mod);4921 const ret_ty = ptr_ty.childType(mod);
...@@ -4934,7 +4925,7 @@ pub const FuncGen = struct {...@@ -4934,7 +4925,7 @@ pub const FuncGen = struct {
4934 // Functions with an empty error set are emitted with an error code4925 // Functions with an empty error set are emitted with an error code
4935 // return type and return zero so they can be function pointers coerced4926 // return type and return zero so they can be function pointers coerced
4936 // to functions that return anyerror.4927 // to functions that return anyerror.
4937 const err_int = try self.dg.lowerType(Type.anyerror);4928 const err_int = try o.lowerType(Type.anyerror);
4938 _ = self.builder.buildRet(err_int.constInt(0, .False));4929 _ = self.builder.buildRet(err_int.constInt(0, .False));
4939 } else {4930 } else {
4940 _ = self.builder.buildRetVoid();4931 _ = self.builder.buildRetVoid();
...@@ -4946,7 +4937,7 @@ pub const FuncGen = struct {...@@ -4946,7 +4937,7 @@ pub const FuncGen = struct {
4946 return null;4937 return null;
4947 }4938 }
4948 const ptr = try self.resolveInst(un_op);4939 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);
4950 const loaded = self.builder.buildLoad(abi_ret_ty, ptr, "");4941 const loaded = self.builder.buildLoad(abi_ret_ty, ptr, "");
4951 loaded.setAlignment(ret_ty.abiAlignment(mod));4942 loaded.setAlignment(ret_ty.abiAlignment(mod));
4952 _ = self.builder.buildRet(loaded);4943 _ = self.builder.buildRet(loaded);
...@@ -4954,32 +4945,34 @@ pub const FuncGen = struct {...@@ -4954,32 +4945,34 @@ pub const FuncGen = struct {
4954 }4945 }
49554946
4956 fn airCVaArg(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {4947 fn airCVaArg(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
4948 const o = self.dg.object;
4957 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4949 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
4958 const list = try self.resolveInst(ty_op.operand);4950 const list = try self.resolveInst(ty_op.operand);
4959 const arg_ty = self.air.getRefType(ty_op.ty);4951 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
4962 return self.builder.buildVAArg(list, llvm_arg_ty, "");4954 return self.builder.buildVAArg(list, llvm_arg_ty, "");
4963 }4955 }
49644956
4965 fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {4957 fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
4958 const o = self.dg.object;
4966 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4959 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
4967 const src_list = try self.resolveInst(ty_op.operand);4960 const src_list = try self.resolveInst(ty_op.operand);
4968 const va_list_ty = self.air.getRefType(ty_op.ty);4961 const va_list_ty = self.air.getRefType(ty_op.ty);
4969 const llvm_va_list_ty = try self.dg.lowerType(va_list_ty);4962 const llvm_va_list_ty = try o.lowerType(va_list_ty);
4970 const mod = self.dg.module;4963 const mod = o.module;
49714964
4972 const result_alignment = va_list_ty.abiAlignment(mod);4965 const result_alignment = va_list_ty.abiAlignment(mod);
4973 const dest_list = self.buildAlloca(llvm_va_list_ty, result_alignment);4966 const dest_list = self.buildAlloca(llvm_va_list_ty, result_alignment);
49744967
4975 const llvm_fn_name = "llvm.va_copy";4968 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: {
4977 const param_types = [_]*llvm.Type{4970 const param_types = [_]*llvm.Type{
4978 self.context.pointerType(0),4971 self.context.pointerType(0),
4979 self.context.pointerType(0),4972 self.context.pointerType(0),
4980 };4973 };
4981 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);4974 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);
4983 };4976 };
49844977
4985 const args: [2]*llvm.Value = .{ dest_list, src_list };4978 const args: [2]*llvm.Value = .{ dest_list, src_list };
...@@ -4995,14 +4988,15 @@ pub const FuncGen = struct {...@@ -4995,14 +4988,15 @@ pub const FuncGen = struct {
4995 }4988 }
49964989
4997 fn airCVaEnd(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {4990 fn airCVaEnd(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
4991 const o = self.dg.object;
4998 const un_op = self.air.instructions.items(.data)[inst].un_op;4992 const un_op = self.air.instructions.items(.data)[inst].un_op;
4999 const list = try self.resolveInst(un_op);4993 const list = try self.resolveInst(un_op);
50004994
5001 const llvm_fn_name = "llvm.va_end";4995 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: {
5003 const param_types = [_]*llvm.Type{self.context.pointerType(0)};4997 const param_types = [_]*llvm.Type{self.context.pointerType(0)};
5004 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);4998 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);
5006 };5000 };
5007 const args: [1]*llvm.Value = .{list};5001 const args: [1]*llvm.Value = .{list};
5008 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");5002 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
...@@ -5010,18 +5004,19 @@ pub const FuncGen = struct {...@@ -5010,18 +5004,19 @@ pub const FuncGen = struct {
5010 }5004 }
50115005
5012 fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5006 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;
5014 const va_list_ty = self.typeOfIndex(inst);5009 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
5017 const result_alignment = va_list_ty.abiAlignment(mod);5012 const result_alignment = va_list_ty.abiAlignment(mod);
5018 const list = self.buildAlloca(llvm_va_list_ty, result_alignment);5013 const list = self.buildAlloca(llvm_va_list_ty, result_alignment);
50195014
5020 const llvm_fn_name = "llvm.va_start";5015 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: {
5022 const param_types = [_]*llvm.Type{self.context.pointerType(0)};5017 const param_types = [_]*llvm.Type{self.context.pointerType(0)};
5023 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);5018 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);
5025 };5020 };
5026 const args: [1]*llvm.Value = .{list};5021 const args: [1]*llvm.Value = .{list};
5027 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");5022 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
...@@ -5075,7 +5070,8 @@ pub const FuncGen = struct {...@@ -5075,7 +5070,8 @@ pub const FuncGen = struct {
5075 operand_ty: Type,5070 operand_ty: Type,
5076 op: math.CompareOperator,5071 op: math.CompareOperator,
5077 ) Allocator.Error!*llvm.Value {5072 ) Allocator.Error!*llvm.Value {
5078 const mod = self.dg.module;5073 const o = self.dg.object;
5074 const mod = o.module;
5079 const scalar_ty = operand_ty.scalarType(mod);5075 const scalar_ty = operand_ty.scalarType(mod);
5080 const int_ty = switch (scalar_ty.zigTypeTag(mod)) {5076 const int_ty = switch (scalar_ty.zigTypeTag(mod)) {
5081 .Enum => scalar_ty.intTagType(mod),5077 .Enum => scalar_ty.intTagType(mod),
...@@ -5090,7 +5086,7 @@ pub const FuncGen = struct {...@@ -5090,7 +5086,7 @@ pub const FuncGen = struct {
5090 // We need to emit instructions to check for equality/inequality5086 // We need to emit instructions to check for equality/inequality
5091 // of optionals that are not pointers.5087 // of optionals that are not pointers.
5092 const is_by_ref = isByRef(scalar_ty, mod);5088 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);
5094 const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref);5090 const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref);
5095 const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref);5091 const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref);
5096 const llvm_i2 = self.context.intType(2);5092 const llvm_i2 = self.context.intType(2);
...@@ -5169,7 +5165,8 @@ pub const FuncGen = struct {...@@ -5169,7 +5165,8 @@ pub const FuncGen = struct {
5169 }5165 }
51705166
5171 fn airBlock(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5167 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;
5173 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5170 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5174 const extra = self.air.extraData(Air.Block, ty_pl.payload);5171 const extra = self.air.extraData(Air.Block, ty_pl.payload);
5175 const body = self.air.extra[extra.end..][0..extra.data.body_len];5172 const body = self.air.extra[extra.end..][0..extra.data.body_len];
...@@ -5199,7 +5196,7 @@ pub const FuncGen = struct {...@@ -5199,7 +5196,7 @@ pub const FuncGen = struct {
5199 const is_body = inst_ty.zigTypeTag(mod) == .Fn;5196 const is_body = inst_ty.zigTypeTag(mod) == .Fn;
5200 if (!is_body and !inst_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;5197 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
5204 const llvm_ty = ty: {5201 const llvm_ty = ty: {
5205 // If the zig tag type is a function, this represents an actual function body; not5202 // If the zig tag type is a function, this represents an actual function body; not
...@@ -5222,12 +5219,13 @@ pub const FuncGen = struct {...@@ -5222,12 +5219,13 @@ pub const FuncGen = struct {
5222 }5219 }
52235220
5224 fn airBr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5221 fn airBr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5222 const o = self.dg.object;
5225 const branch = self.air.instructions.items(.data)[inst].br;5223 const branch = self.air.instructions.items(.data)[inst].br;
5226 const block = self.blocks.get(branch.block_inst).?;5224 const block = self.blocks.get(branch.block_inst).?;
52275225
5228 // Add the values to the lists only if the break provides a value.5226 // Add the values to the lists only if the break provides a value.
5229 const operand_ty = self.typeOf(branch.operand);5227 const operand_ty = self.typeOf(branch.operand);
5230 const mod = self.dg.module;5228 const mod = o.module;
5231 if (operand_ty.hasRuntimeBitsIgnoreComptime(mod) or operand_ty.zigTypeTag(mod) == .Fn) {5229 if (operand_ty.hasRuntimeBitsIgnoreComptime(mod) or operand_ty.zigTypeTag(mod) == .Fn) {
5232 const val = try self.resolveInst(branch.operand);5230 const val = try self.resolveInst(branch.operand);
52335231
...@@ -5264,7 +5262,8 @@ pub const FuncGen = struct {...@@ -5264,7 +5262,8 @@ pub const FuncGen = struct {
5264 }5262 }
52655263
5266 fn airTry(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {5264 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;
5268 const inst = body_tail[0];5267 const inst = body_tail[0];
5269 const pl_op = self.air.instructions.items(.data)[inst].pl_op;5268 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
5270 const err_union = try self.resolveInst(pl_op.operand);5269 const err_union = try self.resolveInst(pl_op.operand);
...@@ -5278,7 +5277,8 @@ pub const FuncGen = struct {...@@ -5278,7 +5277,8 @@ pub const FuncGen = struct {
5278 }5277 }
52795278
5280 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5279 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;
5282 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5282 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5283 const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);5283 const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);
5284 const err_union_ptr = try self.resolveInst(extra.data.ptr);5284 const err_union_ptr = try self.resolveInst(extra.data.ptr);
...@@ -5297,14 +5297,15 @@ pub const FuncGen = struct {...@@ -5297,14 +5297,15 @@ pub const FuncGen = struct {
5297 can_elide_load: bool,5297 can_elide_load: bool,
5298 is_unused: bool,5298 is_unused: bool,
5299 ) !?*llvm.Value {5299 ) !?*llvm.Value {
5300 const mod = fg.dg.module;5300 const o = fg.dg.object;
5301 const mod = o.module;
5301 const payload_ty = err_union_ty.errorUnionPayload(mod);5302 const payload_ty = err_union_ty.errorUnionPayload(mod);
5302 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);5303 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
5305 if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {5306 if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
5306 const is_err = err: {5307 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);
5308 const zero = err_set_ty.constNull();5309 const zero = err_set_ty.constNull();
5309 if (!payload_has_bits) {5310 if (!payload_has_bits) {
5310 // TODO add alignment to this load5311 // TODO add alignment to this load
...@@ -5359,7 +5360,8 @@ pub const FuncGen = struct {...@@ -5359,7 +5360,8 @@ pub const FuncGen = struct {
5359 }5360 }
53605361
5361 fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5362 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;
5363 const pl_op = self.air.instructions.items(.data)[inst].pl_op;5365 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
5364 const cond = try self.resolveInst(pl_op.operand);5366 const cond = try self.resolveInst(pl_op.operand);
5365 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);5367 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
...@@ -5409,7 +5411,8 @@ pub const FuncGen = struct {...@@ -5409,7 +5411,8 @@ pub const FuncGen = struct {
5409 }5411 }
54105412
5411 fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5413 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;
5413 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5416 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5414 const loop = self.air.extraData(Air.Block, ty_pl.payload);5417 const loop = self.air.extraData(Air.Block, ty_pl.payload);
5415 const body = self.air.extra[loop.end..][0..loop.data.body_len];5418 const body = self.air.extra[loop.end..][0..loop.data.body_len];
...@@ -5432,13 +5435,14 @@ pub const FuncGen = struct {...@@ -5432,13 +5435,14 @@ pub const FuncGen = struct {
5432 }5435 }
54335436
5434 fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5437 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;
5436 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5440 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
5437 const operand_ty = self.typeOf(ty_op.operand);5441 const operand_ty = self.typeOf(ty_op.operand);
5438 const array_ty = operand_ty.childType(mod);5442 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);
5440 const len = llvm_usize.constInt(array_ty.arrayLen(mod), .False);5444 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));
5442 const operand = try self.resolveInst(ty_op.operand);5446 const operand = try self.resolveInst(ty_op.operand);
5443 if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) {5447 if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5444 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), operand, 0, "");5448 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), operand, 0, "");
...@@ -5447,14 +5451,15 @@ pub const FuncGen = struct {...@@ -5447,14 +5451,15 @@ pub const FuncGen = struct {
5447 const indices: [2]*llvm.Value = .{5451 const indices: [2]*llvm.Value = .{
5448 llvm_usize.constNull(), llvm_usize.constNull(),5452 llvm_usize.constNull(), llvm_usize.constNull(),
5449 };5453 };
5450 const array_llvm_ty = try self.dg.lowerType(array_ty);5454 const array_llvm_ty = try o.lowerType(array_ty);
5451 const ptr = self.builder.buildInBoundsGEP(array_llvm_ty, operand, &indices, indices.len, "");5455 const ptr = self.builder.buildInBoundsGEP(array_llvm_ty, operand, &indices, indices.len, "");
5452 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, "");5456 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, "");
5453 return self.builder.buildInsertValue(partial, len, 1, "");5457 return self.builder.buildInsertValue(partial, len, 1, "");
5454 }5458 }
54555459
5456 fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5460 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;
5458 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5463 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
54595464
5460 const operand = try self.resolveInst(ty_op.operand);5465 const operand = try self.resolveInst(ty_op.operand);
...@@ -5463,7 +5468,7 @@ pub const FuncGen = struct {...@@ -5463,7 +5468,7 @@ pub const FuncGen = struct {
54635468
5464 const dest_ty = self.typeOfIndex(inst);5469 const dest_ty = self.typeOfIndex(inst);
5465 const dest_scalar_ty = dest_ty.scalarType(mod);5470 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);
5467 const target = mod.getTarget();5472 const target = mod.getTarget();
54685473
5469 if (intrinsicsAllowed(dest_scalar_ty, target)) {5474 if (intrinsicsAllowed(dest_scalar_ty, target)) {
...@@ -5513,7 +5518,8 @@ pub const FuncGen = struct {...@@ -5513,7 +5518,8 @@ pub const FuncGen = struct {
5513 fn airIntFromFloat(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {5518 fn airIntFromFloat(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
5514 self.builder.setFastMath(want_fast_math);5519 self.builder.setFastMath(want_fast_math);
55155520
5516 const mod = self.dg.module;5521 const o = self.dg.object;
5522 const mod = o.module;
5517 const target = mod.getTarget();5523 const target = mod.getTarget();
5518 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5524 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
55195525
...@@ -5523,7 +5529,7 @@ pub const FuncGen = struct {...@@ -5523,7 +5529,7 @@ pub const FuncGen = struct {
55235529
5524 const dest_ty = self.typeOfIndex(inst);5530 const dest_ty = self.typeOfIndex(inst);
5525 const dest_scalar_ty = dest_ty.scalarType(mod);5531 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
5528 if (intrinsicsAllowed(operand_scalar_ty, target)) {5534 if (intrinsicsAllowed(operand_scalar_ty, target)) {
5529 // TODO set fast math flag5535 // TODO set fast math flag
...@@ -5555,7 +5561,7 @@ pub const FuncGen = struct {...@@ -5555,7 +5561,7 @@ pub const FuncGen = struct {
5555 compiler_rt_dest_abbrev,5561 compiler_rt_dest_abbrev,
5556 }) catch unreachable;5562 }) catch unreachable;
55575563
5558 const operand_llvm_ty = try self.dg.lowerType(operand_ty);5564 const operand_llvm_ty = try o.lowerType(operand_ty);
5559 const param_types = [1]*llvm.Type{operand_llvm_ty};5565 const param_types = [1]*llvm.Type{operand_llvm_ty};
5560 const libc_fn = self.getLibcFunction(fn_name, &param_types, libc_ret_ty);5566 const libc_fn = self.getLibcFunction(fn_name, &param_types, libc_ret_ty);
5561 const params = [1]*llvm.Value{operand};5567 const params = [1]*llvm.Value{operand};
...@@ -5568,7 +5574,8 @@ pub const FuncGen = struct {...@@ -5568,7 +5574,8 @@ pub const FuncGen = struct {
5568 }5574 }
55695575
5570 fn sliceOrArrayPtr(fg: *FuncGen, ptr: *llvm.Value, ty: Type) *llvm.Value {5576 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;
5572 if (ty.isSlice(mod)) {5579 if (ty.isSlice(mod)) {
5573 return fg.builder.buildExtractValue(ptr, 0, "");5580 return fg.builder.buildExtractValue(ptr, 0, "");
5574 } else {5581 } else {
...@@ -5577,7 +5584,8 @@ pub const FuncGen = struct {...@@ -5577,7 +5584,8 @@ pub const FuncGen = struct {
5577 }5584 }
55785585
5579 fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: *llvm.Value, ty: Type) *llvm.Value {5586 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;
5581 const target = mod.getTarget();5589 const target = mod.getTarget();
5582 const llvm_usize_ty = fg.context.intType(target.ptrBitWidth());5590 const llvm_usize_ty = fg.context.intType(target.ptrBitWidth());
5583 switch (ty.ptrSize(mod)) {5591 switch (ty.ptrSize(mod)) {
...@@ -5606,24 +5614,26 @@ pub const FuncGen = struct {...@@ -5606,24 +5614,26 @@ pub const FuncGen = struct {
5606 }5614 }
56075615
5608 fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*llvm.Value {5616 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;
5610 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5619 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
5611 const slice_ptr = try self.resolveInst(ty_op.operand);5620 const slice_ptr = try self.resolveInst(ty_op.operand);
5612 const slice_ptr_ty = self.typeOf(ty_op.operand);5621 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
5615 return self.builder.buildStructGEP(slice_llvm_ty, slice_ptr, index, "");5624 return self.builder.buildStructGEP(slice_llvm_ty, slice_ptr, index, "");
5616 }5625 }
56175626
5618 fn airSliceElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {5627 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;
5620 const inst = body_tail[0];5630 const inst = body_tail[0];
5621 const bin_op = self.air.instructions.items(.data)[inst].bin_op;5631 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
5622 const slice_ty = self.typeOf(bin_op.lhs);5632 const slice_ty = self.typeOf(bin_op.lhs);
5623 const slice = try self.resolveInst(bin_op.lhs);5633 const slice = try self.resolveInst(bin_op.lhs);
5624 const index = try self.resolveInst(bin_op.rhs);5634 const index = try self.resolveInst(bin_op.rhs);
5625 const elem_ty = slice_ty.childType(mod);5635 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);
5627 const base_ptr = self.builder.buildExtractValue(slice, 0, "");5637 const base_ptr = self.builder.buildExtractValue(slice, 0, "");
5628 const indices: [1]*llvm.Value = .{index};5638 const indices: [1]*llvm.Value = .{index};
5629 const ptr = self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");5639 const ptr = self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
...@@ -5638,28 +5648,30 @@ pub const FuncGen = struct {...@@ -5638,28 +5648,30 @@ pub const FuncGen = struct {
5638 }5648 }
56395649
5640 fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5650 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;
5642 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5653 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5643 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;5654 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
5644 const slice_ty = self.typeOf(bin_op.lhs);5655 const slice_ty = self.typeOf(bin_op.lhs);
56455656
5646 const slice = try self.resolveInst(bin_op.lhs);5657 const slice = try self.resolveInst(bin_op.lhs);
5647 const index = try self.resolveInst(bin_op.rhs);5658 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));
5649 const base_ptr = self.builder.buildExtractValue(slice, 0, "");5660 const base_ptr = self.builder.buildExtractValue(slice, 0, "");
5650 const indices: [1]*llvm.Value = .{index};5661 const indices: [1]*llvm.Value = .{index};
5651 return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");5662 return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
5652 }5663 }
56535664
5654 fn airArrayElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {5665 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;
5656 const inst = body_tail[0];5668 const inst = body_tail[0];
56575669
5658 const bin_op = self.air.instructions.items(.data)[inst].bin_op;5670 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
5659 const array_ty = self.typeOf(bin_op.lhs);5671 const array_ty = self.typeOf(bin_op.lhs);
5660 const array_llvm_val = try self.resolveInst(bin_op.lhs);5672 const array_llvm_val = try self.resolveInst(bin_op.lhs);
5661 const rhs = try self.resolveInst(bin_op.rhs);5673 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);
5663 const elem_ty = array_ty.childType(mod);5675 const elem_ty = array_ty.childType(mod);
5664 if (isByRef(array_ty, mod)) {5676 if (isByRef(array_ty, mod)) {
5665 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };5677 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
...@@ -5671,7 +5683,7 @@ pub const FuncGen = struct {...@@ -5671,7 +5683,7 @@ pub const FuncGen = struct {
5671 return self.loadByRef(elem_ptr, elem_ty, elem_ty.abiAlignment(mod), false);5683 return self.loadByRef(elem_ptr, elem_ty, elem_ty.abiAlignment(mod), false);
5672 } else {5684 } else {
5673 const lhs_index = Air.refToIndex(bin_op.lhs).?;5685 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);
5675 if (self.air.instructions.items(.tag)[lhs_index] == .load) {5687 if (self.air.instructions.items(.tag)[lhs_index] == .load) {
5676 const load_data = self.air.instructions.items(.data)[lhs_index];5688 const load_data = self.air.instructions.items(.data)[lhs_index];
5677 const load_ptr = load_data.ty_op.operand;5689 const load_ptr = load_data.ty_op.operand;
...@@ -5695,12 +5707,13 @@ pub const FuncGen = struct {...@@ -5695,12 +5707,13 @@ pub const FuncGen = struct {
5695 }5707 }
56965708
5697 fn airPtrElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {5709 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;
5699 const inst = body_tail[0];5712 const inst = body_tail[0];
5700 const bin_op = self.air.instructions.items(.data)[inst].bin_op;5713 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
5701 const ptr_ty = self.typeOf(bin_op.lhs);5714 const ptr_ty = self.typeOf(bin_op.lhs);
5702 const elem_ty = ptr_ty.childType(mod);5715 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);
5704 const base_ptr = try self.resolveInst(bin_op.lhs);5717 const base_ptr = try self.resolveInst(bin_op.lhs);
5705 const rhs = try self.resolveInst(bin_op.rhs);5718 const rhs = try self.resolveInst(bin_op.rhs);
5706 // TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch5719 // TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch
...@@ -5723,12 +5736,13 @@ pub const FuncGen = struct {...@@ -5723,12 +5736,13 @@ pub const FuncGen = struct {
5723 }5736 }
57245737
5725 fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5738 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;
5727 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5741 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5728 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;5742 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
5729 const ptr_ty = self.typeOf(bin_op.lhs);5743 const ptr_ty = self.typeOf(bin_op.lhs);
5730 const elem_ty = ptr_ty.childType(mod);5744 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
5733 const base_ptr = try self.resolveInst(bin_op.lhs);5747 const base_ptr = try self.resolveInst(bin_op.lhs);
5734 const rhs = try self.resolveInst(bin_op.rhs);5748 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -5736,7 +5750,7 @@ pub const FuncGen = struct {...@@ -5736,7 +5750,7 @@ pub const FuncGen = struct {
5736 const elem_ptr = self.air.getRefType(ty_pl.ty);5750 const elem_ptr = self.air.getRefType(ty_pl.ty);
5737 if (elem_ptr.ptrInfo(mod).flags.vector_index != .none) return base_ptr;5751 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);
5740 if (ptr_ty.isSinglePointer(mod)) {5754 if (ptr_ty.isSinglePointer(mod)) {
5741 // If this is a single-item pointer to an array, we need another index in the GEP.5755 // If this is a single-item pointer to an array, we need another index in the GEP.
5742 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };5756 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
...@@ -5767,7 +5781,8 @@ pub const FuncGen = struct {...@@ -5767,7 +5781,8 @@ pub const FuncGen = struct {
5767 }5781 }
57685782
5769 fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {5783 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;
5771 const inst = body_tail[0];5786 const inst = body_tail[0];
5772 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5787 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5773 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;5788 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
...@@ -5789,7 +5804,7 @@ pub const FuncGen = struct {...@@ -5789,7 +5804,7 @@ pub const FuncGen = struct {
5789 const containing_int = struct_llvm_val;5804 const containing_int = struct_llvm_val;
5790 const shift_amt = containing_int.typeOf().constInt(bit_offset, .False);5805 const shift_amt = containing_int.typeOf().constInt(bit_offset, .False);
5791 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");5806 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);
5793 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {5808 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
5794 const elem_bits = @intCast(c_uint, field_ty.bitSize(mod));5809 const elem_bits = @intCast(c_uint, field_ty.bitSize(mod));
5795 const same_size_int = self.context.intType(elem_bits);5810 const same_size_int = self.context.intType(elem_bits);
...@@ -5811,7 +5826,7 @@ pub const FuncGen = struct {...@@ -5811,7 +5826,7 @@ pub const FuncGen = struct {
5811 .Union => {5826 .Union => {
5812 assert(struct_ty.containerLayout(mod) == .Packed);5827 assert(struct_ty.containerLayout(mod) == .Packed);
5813 const containing_int = struct_llvm_val;5828 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);
5815 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {5830 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
5816 const elem_bits = @intCast(c_uint, field_ty.bitSize(mod));5831 const elem_bits = @intCast(c_uint, field_ty.bitSize(mod));
5817 const same_size_int = self.context.intType(elem_bits);5832 const same_size_int = self.context.intType(elem_bits);
...@@ -5833,7 +5848,7 @@ pub const FuncGen = struct {...@@ -5833,7 +5848,7 @@ pub const FuncGen = struct {
5833 .Struct => {5848 .Struct => {
5834 assert(struct_ty.containerLayout(mod) != .Packed);5849 assert(struct_ty.containerLayout(mod) != .Packed);
5835 const llvm_field = llvmField(struct_ty, field_index, mod).?;5850 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);
5837 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field.index, "");5852 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field.index, "");
5838 const field_ptr_ty = try mod.ptrType(.{5853 const field_ptr_ty = try mod.ptrType(.{
5839 .child = llvm_field.ty.toIntern(),5854 .child = llvm_field.ty.toIntern(),
...@@ -5852,11 +5867,11 @@ pub const FuncGen = struct {...@@ -5852,11 +5867,11 @@ pub const FuncGen = struct {
5852 }5867 }
5853 },5868 },
5854 .Union => {5869 .Union => {
5855 const union_llvm_ty = try self.dg.lowerType(struct_ty);5870 const union_llvm_ty = try o.lowerType(struct_ty);
5856 const layout = struct_ty.unionGetLayout(mod);5871 const layout = struct_ty.unionGetLayout(mod);
5857 const payload_index = @intFromBool(layout.tag_align >= layout.payload_align);5872 const payload_index = @intFromBool(layout.tag_align >= layout.payload_align);
5858 const field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, "");5873 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);
5860 if (isByRef(field_ty, mod)) {5875 if (isByRef(field_ty, mod)) {
5861 if (canElideLoad(self, body_tail))5876 if (canElideLoad(self, body_tail))
5862 return field_ptr;5877 return field_ptr;
...@@ -5871,17 +5886,18 @@ pub const FuncGen = struct {...@@ -5871,17 +5886,18 @@ pub const FuncGen = struct {
5871 }5886 }
58725887
5873 fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5888 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;
5875 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5891 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5876 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;5892 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
58775893
5878 const field_ptr = try self.resolveInst(extra.field_ptr);5894 const field_ptr = try self.resolveInst(extra.field_ptr);
58795895
5880 const target = self.dg.module.getTarget();5896 const target = o.module.getTarget();
5881 const parent_ty = self.air.getRefType(ty_pl.ty).childType(mod);5897 const parent_ty = self.air.getRefType(ty_pl.ty).childType(mod);
5882 const field_offset = parent_ty.structFieldOffset(extra.field_index, mod);5898 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));
5885 if (field_offset == 0) {5901 if (field_offset == 0) {
5886 return field_ptr;5902 return field_ptr;
5887 }5903 }
...@@ -5919,14 +5935,15 @@ pub const FuncGen = struct {...@@ -5919,14 +5935,15 @@ pub const FuncGen = struct {
5919 }5935 }
59205936
5921 fn airDbgInlineBegin(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5937 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;
5923 const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;5940 const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;
59245941
5925 const mod = self.dg.module;5942 const mod = o.module;
5926 const func = mod.funcPtr(ty_fn.func);5943 const func = mod.funcPtr(ty_fn.func);
5927 const decl_index = func.owner_decl;5944 const decl_index = func.owner_decl;
5928 const decl = mod.declPtr(decl_index);5945 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);
5930 self.di_file = di_file;5947 self.di_file = di_file;
5931 const line_number = decl.src_line + 1;5948 const line_number = decl.src_line + 1;
5932 const cur_debug_location = self.builder.getCurrentDebugLocation2();5949 const cur_debug_location = self.builder.getCurrentDebugLocation2();
...@@ -5955,7 +5972,7 @@ pub const FuncGen = struct {...@@ -5955,7 +5972,7 @@ pub const FuncGen = struct {
5955 .section_is_generic = false,5972 .section_is_generic = false,
5956 .addrspace_is_generic = false,5973 .addrspace_is_generic = false,
5957 });5974 });
5958 const fn_di_ty = try self.dg.object.lowerDebugType(fn_ty, .full);5975 const fn_di_ty = try o.lowerDebugType(fn_ty, .full);
5959 const subprogram = dib.createFunction(5976 const subprogram = dib.createFunction(
5960 di_file.toScope(),5977 di_file.toScope(),
5961 mod.intern_pool.stringToSlice(decl.name),5978 mod.intern_pool.stringToSlice(decl.name),
...@@ -5978,13 +5995,14 @@ pub const FuncGen = struct {...@@ -5978,13 +5995,14 @@ pub const FuncGen = struct {
5978 }5995 }
59795996
5980 fn airDbgInlineEnd(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5997 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;
5982 const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;6000 const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;
59836001
5984 const mod = self.dg.module;6002 const mod = o.module;
5985 const func = mod.funcPtr(ty_fn.func);6003 const func = mod.funcPtr(ty_fn.func);
5986 const decl = mod.declPtr(func.owner_decl);6004 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);
5988 self.di_file = di_file;6006 self.di_file = di_file;
5989 const old = self.dbg_inlined.pop();6007 const old = self.dbg_inlined.pop();
5990 self.di_scope = old.scope;6008 self.di_scope = old.scope;
...@@ -5993,7 +6011,8 @@ pub const FuncGen = struct {...@@ -5993,7 +6011,8 @@ pub const FuncGen = struct {
5993 }6011 }
59946012
5995 fn airDbgBlockBegin(self: *FuncGen) !?*llvm.Value {6013 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;
5997 const old_scope = self.di_scope.?;6016 const old_scope = self.di_scope.?;
5998 try self.dbg_block_stack.append(self.gpa, old_scope);6017 try self.dbg_block_stack.append(self.gpa, old_scope);
5999 const lexical_block = dib.createLexicalBlock(old_scope, self.di_file.?, self.prev_dbg_line, self.prev_dbg_column);6018 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 {...@@ -6002,14 +6021,16 @@ pub const FuncGen = struct {
6002 }6021 }
60036022
6004 fn airDbgBlockEnd(self: *FuncGen) !?*llvm.Value {6023 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;
6006 self.di_scope = self.dbg_block_stack.pop();6026 self.di_scope = self.dbg_block_stack.pop();
6007 return null;6027 return null;
6008 }6028 }
60096029
6010 fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6030 fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6011 const mod = self.dg.module;6031 const o = self.dg.object;
6012 const dib = self.dg.object.di_builder orelse return null;6032 const mod = o.module;
6033 const dib = o.di_builder orelse return null;
6013 const pl_op = self.air.instructions.items(.data)[inst].pl_op;6034 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
6014 const operand = try self.resolveInst(pl_op.operand);6035 const operand = try self.resolveInst(pl_op.operand);
6015 const name = self.air.nullTerminatedString(pl_op.payload);6036 const name = self.air.nullTerminatedString(pl_op.payload);
...@@ -6020,7 +6041,7 @@ pub const FuncGen = struct {...@@ -6020,7 +6041,7 @@ pub const FuncGen = struct {
6020 name.ptr,6041 name.ptr,
6021 self.di_file.?,6042 self.di_file.?,
6022 self.prev_dbg_line,6043 self.prev_dbg_line,
6023 try self.dg.object.lowerDebugType(ptr_ty.childType(mod), .full),6044 try o.lowerDebugType(ptr_ty.childType(mod), .full),
6024 true, // always preserve6045 true, // always preserve
6025 0, // flags6046 0, // flags
6026 );6047 );
...@@ -6035,13 +6056,14 @@ pub const FuncGen = struct {...@@ -6035,13 +6056,14 @@ pub const FuncGen = struct {
6035 }6056 }
60366057
6037 fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6058 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;
6039 const pl_op = self.air.instructions.items(.data)[inst].pl_op;6061 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
6040 const operand = try self.resolveInst(pl_op.operand);6062 const operand = try self.resolveInst(pl_op.operand);
6041 const operand_ty = self.typeOf(pl_op.operand);6063 const operand_ty = self.typeOf(pl_op.operand);
6042 const name = self.air.nullTerminatedString(pl_op.payload);6064 const name = self.air.nullTerminatedString(pl_op.payload);
60436065
6044 if (needDbgVarWorkaround(self.dg)) {6066 if (needDbgVarWorkaround(o)) {
6045 return null;6067 return null;
6046 }6068 }
60476069
...@@ -6050,7 +6072,7 @@ pub const FuncGen = struct {...@@ -6050,7 +6072,7 @@ pub const FuncGen = struct {
6050 name.ptr,6072 name.ptr,
6051 self.di_file.?,6073 self.di_file.?,
6052 self.prev_dbg_line,6074 self.prev_dbg_line,
6053 try self.dg.object.lowerDebugType(operand_ty, .full),6075 try o.lowerDebugType(operand_ty, .full),
6054 true, // always preserve6076 true, // always preserve
6055 0, // flags6077 0, // flags
6056 );6078 );
...@@ -6060,10 +6082,10 @@ pub const FuncGen = struct {...@@ -6060,10 +6082,10 @@ pub const FuncGen = struct {
6060 null;6082 null;
6061 const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at);6083 const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at);
6062 const insert_block = self.builder.getInsertBlock();6084 const insert_block = self.builder.getInsertBlock();
6063 const mod = self.dg.module;6085 const mod = o.module;
6064 if (isByRef(operand_ty, mod)) {6086 if (isByRef(operand_ty, mod)) {
6065 _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block);6087 _ = 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) {
6067 const alignment = operand_ty.abiAlignment(mod);6089 const alignment = operand_ty.abiAlignment(mod);
6068 const alloca = self.buildAlloca(operand.typeOf(), alignment);6090 const alloca = self.buildAlloca(operand.typeOf(), alignment);
6069 const store_inst = self.builder.buildStore(operand, alloca);6091 const store_inst = self.builder.buildStore(operand, alloca);
...@@ -6082,6 +6104,7 @@ pub const FuncGen = struct {...@@ -6082,6 +6104,7 @@ pub const FuncGen = struct {
6082 // We don't have such an assembler implemented yet though. For now,6104 // We don't have such an assembler implemented yet though. For now,
6083 // this implementation feeds the inline assembly code directly to LLVM.6105 // this implementation feeds the inline assembly code directly to LLVM.
60846106
6107 const o = self.dg.object;
6085 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;6108 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
6086 const extra = self.air.extraData(Air.Asm, ty_pl.payload);6109 const extra = self.air.extraData(Air.Asm, ty_pl.payload);
6087 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;6110 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;
...@@ -6112,7 +6135,7 @@ pub const FuncGen = struct {...@@ -6112,7 +6135,7 @@ pub const FuncGen = struct {
6112 // This stores whether we need to add an elementtype attribute and6135 // This stores whether we need to add an elementtype attribute and
6113 // if so, the element type itself.6136 // if so, the element type itself.
6114 const llvm_param_attrs = try arena.alloc(?*llvm.Type, max_param_count);6137 const llvm_param_attrs = try arena.alloc(?*llvm.Type, max_param_count);
6115 const mod = self.dg.module;6138 const mod = o.module;
6116 const target = mod.getTarget();6139 const target = mod.getTarget();
61176140
6118 var llvm_ret_i: usize = 0;6141 var llvm_ret_i: usize = 0;
...@@ -6142,7 +6165,7 @@ pub const FuncGen = struct {...@@ -6142,7 +6165,7 @@ pub const FuncGen = struct {
6142 const output_inst = try self.resolveInst(output);6165 const output_inst = try self.resolveInst(output);
6143 const output_ty = self.typeOf(output);6166 const output_ty = self.typeOf(output);
6144 assert(output_ty.zigTypeTag(mod) == .Pointer);6167 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
6147 if (llvm_ret_indirect[i]) {6170 if (llvm_ret_indirect[i]) {
6148 // Pass the result by reference as an indirect output (e.g. "=*m")6171 // Pass the result by reference as an indirect output (e.g. "=*m")
...@@ -6159,7 +6182,7 @@ pub const FuncGen = struct {...@@ -6159,7 +6182,7 @@ pub const FuncGen = struct {
6159 }6182 }
6160 } else {6183 } else {
6161 const ret_ty = self.typeOfIndex(inst);6184 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);
6163 llvm_ret_i += 1;6186 llvm_ret_i += 1;
6164 }6187 }
61656188
...@@ -6196,13 +6219,13 @@ pub const FuncGen = struct {...@@ -6196,13 +6219,13 @@ pub const FuncGen = struct {
6196 const arg_ty = self.typeOf(input);6219 const arg_ty = self.typeOf(input);
6197 var llvm_elem_ty: ?*llvm.Type = null;6220 var llvm_elem_ty: ?*llvm.Type = null;
6198 if (isByRef(arg_ty, mod)) {6221 if (isByRef(arg_ty, mod)) {
6199 llvm_elem_ty = try self.dg.lowerPtrElemTy(arg_ty);6222 llvm_elem_ty = try o.lowerPtrElemTy(arg_ty);
6200 if (constraintAllowsMemory(constraint)) {6223 if (constraintAllowsMemory(constraint)) {
6201 llvm_param_values[llvm_param_i] = arg_llvm_value;6224 llvm_param_values[llvm_param_i] = arg_llvm_value;
6202 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();6225 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
6203 } else {6226 } else {
6204 const alignment = arg_ty.abiAlignment(mod);6227 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);
6206 const load_inst = self.builder.buildLoad(arg_llvm_ty, arg_llvm_value, "");6229 const load_inst = self.builder.buildLoad(arg_llvm_ty, arg_llvm_value, "");
6207 load_inst.setAlignment(alignment);6230 load_inst.setAlignment(alignment);
6208 llvm_param_values[llvm_param_i] = load_inst;6231 llvm_param_values[llvm_param_i] = load_inst;
...@@ -6243,7 +6266,7 @@ pub const FuncGen = struct {...@@ -6243,7 +6266,7 @@ pub const FuncGen = struct {
6243 // an elementtype(<ty>) attribute.6266 // an elementtype(<ty>) attribute.
6244 if (constraint[0] == '*') {6267 if (constraint[0] == '*') {
6245 llvm_param_attrs[llvm_param_i] = llvm_elem_ty orelse6268 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));
6247 } else {6270 } else {
6248 llvm_param_attrs[llvm_param_i] = null;6271 llvm_param_attrs[llvm_param_i] = null;
6249 }6272 }
...@@ -6434,12 +6457,13 @@ pub const FuncGen = struct {...@@ -6434,12 +6457,13 @@ pub const FuncGen = struct {
6434 operand_is_ptr: bool,6457 operand_is_ptr: bool,
6435 pred: llvm.IntPredicate,6458 pred: llvm.IntPredicate,
6436 ) !?*llvm.Value {6459 ) !?*llvm.Value {
6437 const mod = self.dg.module;6460 const o = self.dg.object;
6461 const mod = o.module;
6438 const un_op = self.air.instructions.items(.data)[inst].un_op;6462 const un_op = self.air.instructions.items(.data)[inst].un_op;
6439 const operand = try self.resolveInst(un_op);6463 const operand = try self.resolveInst(un_op);
6440 const operand_ty = self.typeOf(un_op);6464 const operand_ty = self.typeOf(un_op);
6441 const optional_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;6465 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);
6443 const payload_ty = optional_ty.optionalChild(mod);6467 const payload_ty = optional_ty.optionalChild(mod);
6444 if (optional_ty.optionalReprIsPayload(mod)) {6468 if (optional_ty.optionalReprIsPayload(mod)) {
6445 const loaded = if (operand_is_ptr)6469 const loaded = if (operand_is_ptr)
...@@ -6448,7 +6472,7 @@ pub const FuncGen = struct {...@@ -6448,7 +6472,7 @@ pub const FuncGen = struct {
6448 operand;6472 operand;
6449 if (payload_ty.isSlice(mod)) {6473 if (payload_ty.isSlice(mod)) {
6450 const slice_ptr = self.builder.buildExtractValue(loaded, 0, "");6474 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));
6452 return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), "");6476 return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), "");
6453 }6477 }
6454 return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), "");6478 return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), "");
...@@ -6480,13 +6504,14 @@ pub const FuncGen = struct {...@@ -6480,13 +6504,14 @@ pub const FuncGen = struct {
6480 op: llvm.IntPredicate,6504 op: llvm.IntPredicate,
6481 operand_is_ptr: bool,6505 operand_is_ptr: bool,
6482 ) !?*llvm.Value {6506 ) !?*llvm.Value {
6483 const mod = self.dg.module;6507 const o = self.dg.object;
6508 const mod = o.module;
6484 const un_op = self.air.instructions.items(.data)[inst].un_op;6509 const un_op = self.air.instructions.items(.data)[inst].un_op;
6485 const operand = try self.resolveInst(un_op);6510 const operand = try self.resolveInst(un_op);
6486 const operand_ty = self.typeOf(un_op);6511 const operand_ty = self.typeOf(un_op);
6487 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;6512 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
6488 const payload_ty = err_union_ty.errorUnionPayload(mod);6513 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);
6490 const zero = err_set_ty.constNull();6515 const zero = err_set_ty.constNull();
64916516
6492 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {6517 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
...@@ -6500,7 +6525,7 @@ pub const FuncGen = struct {...@@ -6500,7 +6525,7 @@ pub const FuncGen = struct {
65006525
6501 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {6526 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6502 const loaded = if (operand_is_ptr)6527 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, "")
6504 else6529 else
6505 operand;6530 operand;
6506 return self.builder.buildICmp(op, loaded, zero, "");6531 return self.builder.buildICmp(op, loaded, zero, "");
...@@ -6509,7 +6534,7 @@ pub const FuncGen = struct {...@@ -6509,7 +6534,7 @@ pub const FuncGen = struct {
6509 const err_field_index = errUnionErrorOffset(payload_ty, mod);6534 const err_field_index = errUnionErrorOffset(payload_ty, mod);
65106535
6511 if (operand_is_ptr or isByRef(err_union_ty, mod)) {6536 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);
6513 const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, err_field_index, "");6538 const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, err_field_index, "");
6514 const loaded = self.builder.buildLoad(err_set_ty, err_field_ptr, "");6539 const loaded = self.builder.buildLoad(err_set_ty, err_field_ptr, "");
6515 return self.builder.buildICmp(op, loaded, zero, "");6540 return self.builder.buildICmp(op, loaded, zero, "");
...@@ -6520,7 +6545,8 @@ pub const FuncGen = struct {...@@ -6520,7 +6545,8 @@ pub const FuncGen = struct {
6520 }6545 }
65216546
6522 fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6547 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;
6524 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6550 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6525 const operand = try self.resolveInst(ty_op.operand);6551 const operand = try self.resolveInst(ty_op.operand);
6526 const optional_ty = self.typeOf(ty_op.operand).childType(mod);6552 const optional_ty = self.typeOf(ty_op.operand).childType(mod);
...@@ -6534,14 +6560,15 @@ pub const FuncGen = struct {...@@ -6534,14 +6560,15 @@ pub const FuncGen = struct {
6534 // The payload and the optional are the same value.6560 // The payload and the optional are the same value.
6535 return operand;6561 return operand;
6536 }6562 }
6537 const optional_llvm_ty = try self.dg.lowerType(optional_ty);6563 const optional_llvm_ty = try o.lowerType(optional_ty);
6538 return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, "");6564 return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, "");
6539 }6565 }
65406566
6541 fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6567 fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6542 comptime assert(optional_layout_version == 3);6568 comptime assert(optional_layout_version == 3);
65436569
6544 const mod = self.dg.module;6570 const o = self.dg.object;
6571 const mod = o.module;
6545 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6572 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6546 const operand = try self.resolveInst(ty_op.operand);6573 const operand = try self.resolveInst(ty_op.operand);
6547 const optional_ty = self.typeOf(ty_op.operand).childType(mod);6574 const optional_ty = self.typeOf(ty_op.operand).childType(mod);
...@@ -6559,7 +6586,7 @@ pub const FuncGen = struct {...@@ -6559,7 +6586,7 @@ pub const FuncGen = struct {
6559 }6586 }
65606587
6561 // First set the non-null bit.6588 // 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);
6563 const non_null_ptr = self.builder.buildStructGEP(optional_llvm_ty, operand, 1, "");6590 const non_null_ptr = self.builder.buildStructGEP(optional_llvm_ty, operand, 1, "");
6564 // TODO set alignment on this store6591 // TODO set alignment on this store
6565 _ = self.builder.buildStore(non_null_bit, non_null_ptr);6592 _ = self.builder.buildStore(non_null_bit, non_null_ptr);
...@@ -6572,7 +6599,8 @@ pub const FuncGen = struct {...@@ -6572,7 +6599,8 @@ pub const FuncGen = struct {
6572 }6599 }
65736600
6574 fn airOptionalPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {6601 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;
6576 const inst = body_tail[0];6604 const inst = body_tail[0];
6577 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6605 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6578 const operand = try self.resolveInst(ty_op.operand);6606 const operand = try self.resolveInst(ty_op.operand);
...@@ -6585,7 +6613,7 @@ pub const FuncGen = struct {...@@ -6585,7 +6613,7 @@ pub const FuncGen = struct {
6585 return operand;6613 return operand;
6586 }6614 }
65876615
6588 const opt_llvm_ty = try self.dg.lowerType(optional_ty);6616 const opt_llvm_ty = try o.lowerType(optional_ty);
6589 const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false;6617 const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false;
6590 return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load);6618 return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load);
6591 }6619 }
...@@ -6595,7 +6623,8 @@ pub const FuncGen = struct {...@@ -6595,7 +6623,8 @@ pub const FuncGen = struct {
6595 body_tail: []const Air.Inst.Index,6623 body_tail: []const Air.Inst.Index,
6596 operand_is_ptr: bool,6624 operand_is_ptr: bool,
6597 ) !?*llvm.Value {6625 ) !?*llvm.Value {
6598 const mod = self.dg.module;6626 const o = self.dg.object;
6627 const mod = o.module;
6599 const inst = body_tail[0];6628 const inst = body_tail[0];
6600 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6629 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6601 const operand = try self.resolveInst(ty_op.operand);6630 const operand = try self.resolveInst(ty_op.operand);
...@@ -6608,7 +6637,7 @@ pub const FuncGen = struct {...@@ -6608,7 +6637,7 @@ pub const FuncGen = struct {
6608 return if (operand_is_ptr) operand else null;6637 return if (operand_is_ptr) operand else null;
6609 }6638 }
6610 const offset = errUnionPayloadOffset(payload_ty, mod);6639 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);
6612 if (operand_is_ptr) {6641 if (operand_is_ptr) {
6613 return self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");6642 return self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");
6614 } else if (isByRef(err_union_ty, mod)) {6643 } else if (isByRef(err_union_ty, mod)) {
...@@ -6631,13 +6660,14 @@ pub const FuncGen = struct {...@@ -6631,13 +6660,14 @@ pub const FuncGen = struct {
6631 inst: Air.Inst.Index,6660 inst: Air.Inst.Index,
6632 operand_is_ptr: bool,6661 operand_is_ptr: bool,
6633 ) !?*llvm.Value {6662 ) !?*llvm.Value {
6634 const mod = self.dg.module;6663 const o = self.dg.object;
6664 const mod = o.module;
6635 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6665 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6636 const operand = try self.resolveInst(ty_op.operand);6666 const operand = try self.resolveInst(ty_op.operand);
6637 const operand_ty = self.typeOf(ty_op.operand);6667 const operand_ty = self.typeOf(ty_op.operand);
6638 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;6668 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
6639 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {6669 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);
6641 if (operand_is_ptr) {6671 if (operand_is_ptr) {
6642 return operand;6672 return operand;
6643 } else {6673 } else {
...@@ -6645,7 +6675,7 @@ pub const FuncGen = struct {...@@ -6645,7 +6675,7 @@ pub const FuncGen = struct {
6645 }6675 }
6646 }6676 }
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
6650 const payload_ty = err_union_ty.errorUnionPayload(mod);6680 const payload_ty = err_union_ty.errorUnionPayload(mod);
6651 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {6681 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -6656,7 +6686,7 @@ pub const FuncGen = struct {...@@ -6656,7 +6686,7 @@ pub const FuncGen = struct {
6656 const offset = errUnionErrorOffset(payload_ty, mod);6686 const offset = errUnionErrorOffset(payload_ty, mod);
66576687
6658 if (operand_is_ptr or isByRef(err_union_ty, mod)) {6688 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);
6660 const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");6690 const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");
6661 return self.builder.buildLoad(err_set_llvm_ty, err_field_ptr, "");6691 return self.builder.buildLoad(err_set_llvm_ty, err_field_ptr, "");
6662 }6692 }
...@@ -6665,18 +6695,19 @@ pub const FuncGen = struct {...@@ -6665,18 +6695,19 @@ pub const FuncGen = struct {
6665 }6695 }
66666696
6667 fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6697 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;
6669 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6700 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6670 const operand = try self.resolveInst(ty_op.operand);6701 const operand = try self.resolveInst(ty_op.operand);
6671 const err_union_ty = self.typeOf(ty_op.operand).childType(mod);6702 const err_union_ty = self.typeOf(ty_op.operand).childType(mod);
66726703
6673 const payload_ty = err_union_ty.errorUnionPayload(mod);6704 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) });
6675 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {6706 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6676 _ = self.builder.buildStore(non_error_val, operand);6707 _ = self.builder.buildStore(non_error_val, operand);
6677 return operand;6708 return operand;
6678 }6709 }
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);
6680 {6711 {
6681 const error_offset = errUnionErrorOffset(payload_ty, mod);6712 const error_offset = errUnionErrorOffset(payload_ty, mod);
6682 // First set the non-error value.6713 // First set the non-error value.
...@@ -6704,14 +6735,15 @@ pub const FuncGen = struct {...@@ -6704,14 +6735,15 @@ pub const FuncGen = struct {
6704 }6735 }
67056736
6706 fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6737 fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6738 const o = self.dg.object;
6707 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;6739 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
6708 //const struct_ty = try self.resolveInst(ty_pl.ty);6740 //const struct_ty = try self.resolveInst(ty_pl.ty);
6709 const struct_ty = self.air.getRefType(ty_pl.ty);6741 const struct_ty = self.air.getRefType(ty_pl.ty);
6710 const field_index = ty_pl.payload;6742 const field_index = ty_pl.payload;
67116743
6712 const mod = self.dg.module;6744 const mod = o.module;
6713 const llvm_field = llvmField(struct_ty, field_index, mod).?;6745 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);
6715 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field.index, "");6747 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field.index, "");
6716 const field_ptr_ty = try mod.ptrType(.{6748 const field_ptr_ty = try mod.ptrType(.{
6717 .child = llvm_field.ty.toIntern(),6749 .child = llvm_field.ty.toIntern(),
...@@ -6723,7 +6755,8 @@ pub const FuncGen = struct {...@@ -6723,7 +6755,8 @@ pub const FuncGen = struct {
6723 }6755 }
67246756
6725 fn airWrapOptional(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6757 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;
6727 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6760 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6728 const payload_ty = self.typeOf(ty_op.operand);6761 const payload_ty = self.typeOf(ty_op.operand);
6729 const non_null_bit = self.context.intType(8).constInt(1, .False);6762 const non_null_bit = self.context.intType(8).constInt(1, .False);
...@@ -6734,7 +6767,7 @@ pub const FuncGen = struct {...@@ -6734,7 +6767,7 @@ pub const FuncGen = struct {
6734 if (optional_ty.optionalReprIsPayload(mod)) {6767 if (optional_ty.optionalReprIsPayload(mod)) {
6735 return operand;6768 return operand;
6736 }6769 }
6737 const llvm_optional_ty = try self.dg.lowerType(optional_ty);6770 const llvm_optional_ty = try o.lowerType(optional_ty);
6738 if (isByRef(optional_ty, mod)) {6771 if (isByRef(optional_ty, mod)) {
6739 const optional_ptr = self.buildAlloca(llvm_optional_ty, optional_ty.abiAlignment(mod));6772 const optional_ptr = self.buildAlloca(llvm_optional_ty, optional_ty.abiAlignment(mod));
6740 const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, "");6773 const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, "");
...@@ -6749,7 +6782,8 @@ pub const FuncGen = struct {...@@ -6749,7 +6782,8 @@ pub const FuncGen = struct {
6749 }6782 }
67506783
6751 fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6784 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;
6753 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6787 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6754 const err_un_ty = self.typeOfIndex(inst);6788 const err_un_ty = self.typeOfIndex(inst);
6755 const operand = try self.resolveInst(ty_op.operand);6789 const operand = try self.resolveInst(ty_op.operand);
...@@ -6757,8 +6791,8 @@ pub const FuncGen = struct {...@@ -6757,8 +6791,8 @@ pub const FuncGen = struct {
6757 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {6791 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6758 return operand;6792 return operand;
6759 }6793 }
6760 const ok_err_code = (try self.dg.lowerType(Type.anyerror)).constNull();6794 const ok_err_code = (try o.lowerType(Type.anyerror)).constNull();
6761 const err_un_llvm_ty = try self.dg.lowerType(err_un_ty);6795 const err_un_llvm_ty = try o.lowerType(err_un_ty);
67626796
6763 const payload_offset = errUnionPayloadOffset(payload_ty, mod);6797 const payload_offset = errUnionPayloadOffset(payload_ty, mod);
6764 const error_offset = errUnionErrorOffset(payload_ty, mod);6798 const error_offset = errUnionErrorOffset(payload_ty, mod);
...@@ -6778,7 +6812,8 @@ pub const FuncGen = struct {...@@ -6778,7 +6812,8 @@ pub const FuncGen = struct {
6778 }6812 }
67796813
6780 fn airWrapErrUnionErr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6814 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;
6782 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6817 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6783 const err_un_ty = self.typeOfIndex(inst);6818 const err_un_ty = self.typeOfIndex(inst);
6784 const payload_ty = err_un_ty.errorUnionPayload(mod);6819 const payload_ty = err_un_ty.errorUnionPayload(mod);
...@@ -6786,7 +6821,7 @@ pub const FuncGen = struct {...@@ -6786,7 +6821,7 @@ pub const FuncGen = struct {
6786 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {6821 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6787 return operand;6822 return operand;
6788 }6823 }
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
6791 const payload_offset = errUnionPayloadOffset(payload_ty, mod);6826 const payload_offset = errUnionPayloadOffset(payload_ty, mod);
6792 const error_offset = errUnionErrorOffset(payload_ty, mod);6827 const error_offset = errUnionErrorOffset(payload_ty, mod);
...@@ -6831,7 +6866,8 @@ pub const FuncGen = struct {...@@ -6831,7 +6866,8 @@ pub const FuncGen = struct {
6831 }6866 }
68326867
6833 fn airVectorStoreElem(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6868 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;
6835 const data = self.air.instructions.items(.data)[inst].vector_store_elem;6871 const data = self.air.instructions.items(.data)[inst].vector_store_elem;
6836 const extra = self.air.extraData(Air.Bin, data.payload).data;6872 const extra = self.air.extraData(Air.Bin, data.payload).data;
68376873
...@@ -6841,7 +6877,7 @@ pub const FuncGen = struct {...@@ -6841,7 +6877,7 @@ pub const FuncGen = struct {
6841 const operand = try self.resolveInst(extra.rhs);6877 const operand = try self.resolveInst(extra.rhs);
68426878
6843 const loaded_vector = blk: {6879 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));
6845 const load_inst = self.builder.buildLoad(elem_llvm_ty, vector_ptr, "");6881 const load_inst = self.builder.buildLoad(elem_llvm_ty, vector_ptr, "");
6846 load_inst.setAlignment(vector_ptr_ty.ptrAlignment(mod));6882 load_inst.setAlignment(vector_ptr_ty.ptrAlignment(mod));
6847 load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr(mod)));6883 load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr(mod)));
...@@ -6853,7 +6889,8 @@ pub const FuncGen = struct {...@@ -6853,7 +6889,8 @@ pub const FuncGen = struct {
6853 }6889 }
68546890
6855 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6891 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;
6857 const bin_op = self.air.instructions.items(.data)[inst].bin_op;6894 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
6858 const lhs = try self.resolveInst(bin_op.lhs);6895 const lhs = try self.resolveInst(bin_op.lhs);
6859 const rhs = try self.resolveInst(bin_op.rhs);6896 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -6865,7 +6902,8 @@ pub const FuncGen = struct {...@@ -6865,7 +6902,8 @@ pub const FuncGen = struct {
6865 }6902 }
68666903
6867 fn airMax(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6904 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;
6869 const bin_op = self.air.instructions.items(.data)[inst].bin_op;6907 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
6870 const lhs = try self.resolveInst(bin_op.lhs);6908 const lhs = try self.resolveInst(bin_op.lhs);
6871 const rhs = try self.resolveInst(bin_op.rhs);6909 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -6877,12 +6915,13 @@ pub const FuncGen = struct {...@@ -6877,12 +6915,13 @@ pub const FuncGen = struct {
6877 }6915 }
68786916
6879 fn airSlice(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6917 fn airSlice(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6918 const o = self.dg.object;
6880 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;6919 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
6881 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;6920 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
6882 const ptr = try self.resolveInst(bin_op.lhs);6921 const ptr = try self.resolveInst(bin_op.lhs);
6883 const len = try self.resolveInst(bin_op.rhs);6922 const len = try self.resolveInst(bin_op.rhs);
6884 const inst_ty = self.typeOfIndex(inst);6923 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
6887 // In case of slicing a global, the result type looks something like `{ i8*, i64 }`6926 // In case of slicing a global, the result type looks something like `{ i8*, i64 }`
6888 // but `ptr` is pointing to the global directly.6927 // but `ptr` is pointing to the global directly.
...@@ -6893,7 +6932,8 @@ pub const FuncGen = struct {...@@ -6893,7 +6932,8 @@ pub const FuncGen = struct {
6893 fn airAdd(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {6932 fn airAdd(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
6894 self.builder.setFastMath(want_fast_math);6933 self.builder.setFastMath(want_fast_math);
68956934
6896 const mod = self.dg.module;6935 const o = self.dg.object;
6936 const mod = o.module;
6897 const bin_op = self.air.instructions.items(.data)[inst].bin_op;6937 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
6898 const lhs = try self.resolveInst(bin_op.lhs);6938 const lhs = try self.resolveInst(bin_op.lhs);
6899 const rhs = try self.resolveInst(bin_op.rhs);6939 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -6916,7 +6956,8 @@ pub const FuncGen = struct {...@@ -6916,7 +6956,8 @@ pub const FuncGen = struct {
6916 }6956 }
69176957
6918 fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6958 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;
6920 const bin_op = self.air.instructions.items(.data)[inst].bin_op;6961 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
6921 const lhs = try self.resolveInst(bin_op.lhs);6962 const lhs = try self.resolveInst(bin_op.lhs);
6922 const rhs = try self.resolveInst(bin_op.rhs);6963 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -6932,7 +6973,8 @@ pub const FuncGen = struct {...@@ -6932,7 +6973,8 @@ pub const FuncGen = struct {
6932 fn airSub(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {6973 fn airSub(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
6933 self.builder.setFastMath(want_fast_math);6974 self.builder.setFastMath(want_fast_math);
69346975
6935 const mod = self.dg.module;6976 const o = self.dg.object;
6977 const mod = o.module;
6936 const bin_op = self.air.instructions.items(.data)[inst].bin_op;6978 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
6937 const lhs = try self.resolveInst(bin_op.lhs);6979 const lhs = try self.resolveInst(bin_op.lhs);
6938 const rhs = try self.resolveInst(bin_op.rhs);6980 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -6955,7 +6997,8 @@ pub const FuncGen = struct {...@@ -6955,7 +6997,8 @@ pub const FuncGen = struct {
6955 }6997 }
69566998
6957 fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6999 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;
6959 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7002 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
6960 const lhs = try self.resolveInst(bin_op.lhs);7003 const lhs = try self.resolveInst(bin_op.lhs);
6961 const rhs = try self.resolveInst(bin_op.rhs);7004 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -6970,7 +7013,8 @@ pub const FuncGen = struct {...@@ -6970,7 +7013,8 @@ pub const FuncGen = struct {
6970 fn airMul(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {7013 fn airMul(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
6971 self.builder.setFastMath(want_fast_math);7014 self.builder.setFastMath(want_fast_math);
69727015
6973 const mod = self.dg.module;7016 const o = self.dg.object;
7017 const mod = o.module;
6974 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7018 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
6975 const lhs = try self.resolveInst(bin_op.lhs);7019 const lhs = try self.resolveInst(bin_op.lhs);
6976 const rhs = try self.resolveInst(bin_op.rhs);7020 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -6993,7 +7037,8 @@ pub const FuncGen = struct {...@@ -6993,7 +7037,8 @@ pub const FuncGen = struct {
6993 }7037 }
69947038
6995 fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7039 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;
6997 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7042 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
6998 const lhs = try self.resolveInst(bin_op.lhs);7043 const lhs = try self.resolveInst(bin_op.lhs);
6999 const rhs = try self.resolveInst(bin_op.rhs);7044 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7019,7 +7064,8 @@ pub const FuncGen = struct {...@@ -7019,7 +7064,8 @@ pub const FuncGen = struct {
7019 fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {7064 fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
7020 self.builder.setFastMath(want_fast_math);7065 self.builder.setFastMath(want_fast_math);
70217066
7022 const mod = self.dg.module;7067 const o = self.dg.object;
7068 const mod = o.module;
7023 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7069 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7024 const lhs = try self.resolveInst(bin_op.lhs);7070 const lhs = try self.resolveInst(bin_op.lhs);
7025 const rhs = try self.resolveInst(bin_op.rhs);7071 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7037,7 +7083,8 @@ pub const FuncGen = struct {...@@ -7037,7 +7083,8 @@ pub const FuncGen = struct {
7037 fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {7083 fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
7038 self.builder.setFastMath(want_fast_math);7084 self.builder.setFastMath(want_fast_math);
70397085
7040 const mod = self.dg.module;7086 const o = self.dg.object;
7087 const mod = o.module;
7041 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7088 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7042 const lhs = try self.resolveInst(bin_op.lhs);7089 const lhs = try self.resolveInst(bin_op.lhs);
7043 const rhs = try self.resolveInst(bin_op.rhs);7090 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7049,11 +7096,11 @@ pub const FuncGen = struct {...@@ -7049,11 +7096,11 @@ pub const FuncGen = struct {
7049 return self.buildFloatOp(.floor, inst_ty, 1, .{result});7096 return self.buildFloatOp(.floor, inst_ty, 1, .{result});
7050 }7097 }
7051 if (scalar_ty.isSignedInt(mod)) {7098 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);
7053 const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1;7100 const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1;
7054 const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: {7101 const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: {
7055 const vec_len = inst_ty.vectorLen(mod);7102 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
7058 const shifts = try self.gpa.alloc(*llvm.Value, vec_len);7105 const shifts = try self.gpa.alloc(*llvm.Value, vec_len);
7059 defer self.gpa.free(shifts);7106 defer self.gpa.free(shifts);
...@@ -7077,7 +7124,8 @@ pub const FuncGen = struct {...@@ -7077,7 +7124,8 @@ pub const FuncGen = struct {
7077 fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {7124 fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
7078 self.builder.setFastMath(want_fast_math);7125 self.builder.setFastMath(want_fast_math);
70797126
7080 const mod = self.dg.module;7127 const o = self.dg.object;
7128 const mod = o.module;
7081 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7129 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7082 const lhs = try self.resolveInst(bin_op.lhs);7130 const lhs = try self.resolveInst(bin_op.lhs);
7083 const rhs = try self.resolveInst(bin_op.rhs);7131 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7092,7 +7140,8 @@ pub const FuncGen = struct {...@@ -7092,7 +7140,8 @@ pub const FuncGen = struct {
7092 fn airRem(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {7140 fn airRem(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
7093 self.builder.setFastMath(want_fast_math);7141 self.builder.setFastMath(want_fast_math);
70947142
7095 const mod = self.dg.module;7143 const o = self.dg.object;
7144 const mod = o.module;
7096 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7145 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7097 const lhs = try self.resolveInst(bin_op.lhs);7146 const lhs = try self.resolveInst(bin_op.lhs);
7098 const rhs = try self.resolveInst(bin_op.rhs);7147 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7107,12 +7156,13 @@ pub const FuncGen = struct {...@@ -7107,12 +7156,13 @@ pub const FuncGen = struct {
7107 fn airMod(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {7156 fn airMod(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
7108 self.builder.setFastMath(want_fast_math);7157 self.builder.setFastMath(want_fast_math);
71097158
7110 const mod = self.dg.module;7159 const o = self.dg.object;
7160 const mod = o.module;
7111 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7161 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7112 const lhs = try self.resolveInst(bin_op.lhs);7162 const lhs = try self.resolveInst(bin_op.lhs);
7113 const rhs = try self.resolveInst(bin_op.rhs);7163 const rhs = try self.resolveInst(bin_op.rhs);
7114 const inst_ty = self.typeOfIndex(inst);7164 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);
7116 const scalar_ty = inst_ty.scalarType(mod);7166 const scalar_ty = inst_ty.scalarType(mod);
71177167
7118 if (scalar_ty.isRuntimeFloat()) {7168 if (scalar_ty.isRuntimeFloat()) {
...@@ -7127,7 +7177,7 @@ pub const FuncGen = struct {...@@ -7127,7 +7177,7 @@ pub const FuncGen = struct {
7127 const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1;7177 const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1;
7128 const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: {7178 const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: {
7129 const vec_len = inst_ty.vectorLen(mod);7179 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
7132 const shifts = try self.gpa.alloc(*llvm.Value, vec_len);7182 const shifts = try self.gpa.alloc(*llvm.Value, vec_len);
7133 defer self.gpa.free(shifts);7183 defer self.gpa.free(shifts);
...@@ -7149,13 +7199,14 @@ pub const FuncGen = struct {...@@ -7149,13 +7199,14 @@ pub const FuncGen = struct {
7149 }7199 }
71507200
7151 fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7201 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;
7153 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;7204 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
7154 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;7205 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
7155 const ptr = try self.resolveInst(bin_op.lhs);7206 const ptr = try self.resolveInst(bin_op.lhs);
7156 const offset = try self.resolveInst(bin_op.rhs);7207 const offset = try self.resolveInst(bin_op.rhs);
7157 const ptr_ty = self.typeOf(bin_op.lhs);7208 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));
7159 switch (ptr_ty.ptrSize(mod)) {7210 switch (ptr_ty.ptrSize(mod)) {
7160 .One => {7211 .One => {
7161 // It's a pointer to an array, so according to LLVM we need an extra GEP index.7212 // 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 {...@@ -7175,14 +7226,15 @@ pub const FuncGen = struct {
7175 }7226 }
71767227
7177 fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7228 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;
7179 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;7231 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
7180 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;7232 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
7181 const ptr = try self.resolveInst(bin_op.lhs);7233 const ptr = try self.resolveInst(bin_op.lhs);
7182 const offset = try self.resolveInst(bin_op.rhs);7234 const offset = try self.resolveInst(bin_op.rhs);
7183 const negative_offset = self.builder.buildNeg(offset, "");7235 const negative_offset = self.builder.buildNeg(offset, "");
7184 const ptr_ty = self.typeOf(bin_op.lhs);7236 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));
7186 switch (ptr_ty.ptrSize(mod)) {7238 switch (ptr_ty.ptrSize(mod)) {
7187 .One => {7239 .One => {
7188 // It's a pointer to an array, so according to LLVM we need an extra GEP index.7240 // 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 {...@@ -7209,7 +7261,8 @@ pub const FuncGen = struct {
7209 signed_intrinsic: []const u8,7261 signed_intrinsic: []const u8,
7210 unsigned_intrinsic: []const u8,7262 unsigned_intrinsic: []const u8,
7211 ) !?*llvm.Value {7263 ) !?*llvm.Value {
7212 const mod = self.dg.module;7264 const o = self.dg.object;
7265 const mod = o.module;
7213 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;7266 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
7214 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;7267 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
72157268
...@@ -7222,8 +7275,8 @@ pub const FuncGen = struct {...@@ -7222,8 +7275,8 @@ pub const FuncGen = struct {
72227275
7223 const intrinsic_name = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic;7276 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);7278 const llvm_lhs_ty = try o.lowerType(lhs_ty);
7226 const llvm_dest_ty = try self.dg.lowerType(dest_ty);7279 const llvm_dest_ty = try o.lowerType(dest_ty);
72277280
7228 const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty});7281 const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty});
7229 const result_struct = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &[_]*llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, "");7282 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 {...@@ -7287,13 +7340,14 @@ pub const FuncGen = struct {
7287 param_types: []const *llvm.Type,7340 param_types: []const *llvm.Type,
7288 return_type: *llvm.Type,7341 return_type: *llvm.Type,
7289 ) *llvm.Value {7342 ) *llvm.Value {
7290 return self.dg.object.llvm_module.getNamedFunction(fn_name.ptr) orelse b: {7343 const o = self.dg.object;
7291 const alias = self.dg.object.llvm_module.getNamedGlobalAlias(fn_name.ptr, fn_name.len);7344 return o.llvm_module.getNamedFunction(fn_name.ptr) orelse b: {
7345 const alias = o.llvm_module.getNamedGlobalAlias(fn_name.ptr, fn_name.len);
7292 break :b if (alias) |a| a.getAliasee() else null;7346 break :b if (alias) |a| a.getAliasee() else null;
7293 } orelse b: {7347 } orelse b: {
7294 const params_len = @intCast(c_uint, param_types.len);7348 const params_len = @intCast(c_uint, param_types.len);
7295 const fn_type = llvm.functionType(return_type, param_types.ptr, params_len, .False);7349 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);
7297 break :b f;7351 break :b f;
7298 };7352 };
7299 }7353 }
...@@ -7306,10 +7360,11 @@ pub const FuncGen = struct {...@@ -7306,10 +7360,11 @@ pub const FuncGen = struct {
7306 ty: Type,7360 ty: Type,
7307 params: [2]*llvm.Value,7361 params: [2]*llvm.Value,
7308 ) !*llvm.Value {7362 ) !*llvm.Value {
7309 const mod = self.dg.module;7363 const o = self.dg.object;
7310 const target = self.dg.module.getTarget();7364 const mod = o.module;
7365 const target = o.module.getTarget();
7311 const scalar_ty = ty.scalarType(mod);7366 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
7314 if (intrinsicsAllowed(scalar_ty, target)) {7369 if (intrinsicsAllowed(scalar_ty, target)) {
7315 const llvm_predicate: llvm.RealPredicate = switch (pred) {7370 const llvm_predicate: llvm.RealPredicate = switch (pred) {
...@@ -7408,11 +7463,12 @@ pub const FuncGen = struct {...@@ -7408,11 +7463,12 @@ pub const FuncGen = struct {
7408 comptime params_len: usize,7463 comptime params_len: usize,
7409 params: [params_len]*llvm.Value,7464 params: [params_len]*llvm.Value,
7410 ) !*llvm.Value {7465 ) !*llvm.Value {
7411 const mod = self.dg.module;7466 const o = self.dg.object;
7467 const mod = o.module;
7412 const target = mod.getTarget();7468 const target = mod.getTarget();
7413 const scalar_ty = ty.scalarType(mod);7469 const scalar_ty = ty.scalarType(mod);
7414 const llvm_ty = try self.dg.lowerType(ty);7470 const llvm_ty = try o.lowerType(ty);
7415 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);7471 const scalar_llvm_ty = try o.lowerType(scalar_ty);
74167472
7417 const intrinsics_allowed = op != .tan and intrinsicsAllowed(scalar_ty, target);7473 const intrinsics_allowed = op != .tan and intrinsicsAllowed(scalar_ty, target);
7418 var fn_name_buf: [64]u8 = undefined;7474 var fn_name_buf: [64]u8 = undefined;
...@@ -7508,7 +7564,8 @@ pub const FuncGen = struct {...@@ -7508,7 +7564,8 @@ pub const FuncGen = struct {
7508 }7564 }
75097565
7510 fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7566 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;
7512 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;7569 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
7513 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;7570 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
75147571
...@@ -7521,10 +7578,10 @@ pub const FuncGen = struct {...@@ -7521,10 +7578,10 @@ pub const FuncGen = struct {
7521 const rhs_scalar_ty = rhs_ty.scalarType(mod);7578 const rhs_scalar_ty = rhs_ty.scalarType(mod);
75227579
7523 const dest_ty = self.typeOfIndex(inst);7580 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
7526 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))7583 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), "")
7528 else7585 else
7529 rhs;7586 rhs;
75307587
...@@ -7582,7 +7639,8 @@ pub const FuncGen = struct {...@@ -7582,7 +7639,8 @@ pub const FuncGen = struct {
7582 }7639 }
75837640
7584 fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7641 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;
7586 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7644 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
75877645
7588 const lhs = try self.resolveInst(bin_op.lhs);7646 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7594,7 +7652,7 @@ pub const FuncGen = struct {...@@ -7594,7 +7652,7 @@ pub const FuncGen = struct {
7594 const rhs_scalar_ty = rhs_ty.scalarType(mod);7652 const rhs_scalar_ty = rhs_ty.scalarType(mod);
75957653
7596 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))7654 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), "")
7598 else7656 else
7599 rhs;7657 rhs;
7600 if (lhs_scalar_ty.isSignedInt(mod)) return self.builder.buildNSWShl(lhs, casted_rhs, "");7658 if (lhs_scalar_ty.isSignedInt(mod)) return self.builder.buildNSWShl(lhs, casted_rhs, "");
...@@ -7602,7 +7660,8 @@ pub const FuncGen = struct {...@@ -7602,7 +7660,8 @@ pub const FuncGen = struct {
7602 }7660 }
76037661
7604 fn airShl(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7662 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;
7606 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7665 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
76077666
7608 const lhs = try self.resolveInst(bin_op.lhs);7667 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7614,14 +7673,15 @@ pub const FuncGen = struct {...@@ -7614,14 +7673,15 @@ pub const FuncGen = struct {
7614 const rhs_scalar_ty = rhs_type.scalarType(mod);7673 const rhs_scalar_ty = rhs_type.scalarType(mod);
76157674
7616 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))7675 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), "")
7618 else7677 else
7619 rhs;7678 rhs;
7620 return self.builder.buildShl(lhs, casted_rhs, "");7679 return self.builder.buildShl(lhs, casted_rhs, "");
7621 }7680 }
76227681
7623 fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7682 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;
7625 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7685 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
76267686
7627 const lhs = try self.resolveInst(bin_op.lhs);7687 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7648,7 +7708,7 @@ pub const FuncGen = struct {...@@ -7648,7 +7708,7 @@ pub const FuncGen = struct {
7648 // poison value."7708 // poison value."
7649 // However Zig semantics says that saturating shift left can never produce7709 // However Zig semantics says that saturating shift left can never produce
7650 // undefined; instead it saturates.7710 // 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);
7652 const bits = lhs_scalar_llvm_ty.constInt(lhs_bits, .False);7712 const bits = lhs_scalar_llvm_ty.constInt(lhs_bits, .False);
7653 const lhs_max = lhs_scalar_llvm_ty.constAllOnes();7713 const lhs_max = lhs_scalar_llvm_ty.constAllOnes();
7654 if (rhs_ty.zigTypeTag(mod) == .Vector) {7714 if (rhs_ty.zigTypeTag(mod) == .Vector) {
...@@ -7664,7 +7724,8 @@ pub const FuncGen = struct {...@@ -7664,7 +7724,8 @@ pub const FuncGen = struct {
7664 }7724 }
76657725
7666 fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !?*llvm.Value {7726 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;
7668 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7729 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
76697730
7670 const lhs = try self.resolveInst(bin_op.lhs);7731 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7676,7 +7737,7 @@ pub const FuncGen = struct {...@@ -7676,7 +7737,7 @@ pub const FuncGen = struct {
7676 const rhs_scalar_ty = rhs_ty.scalarType(mod);7737 const rhs_scalar_ty = rhs_ty.scalarType(mod);
76777738
7678 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))7739 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), "")
7680 else7741 else
7681 rhs;7742 rhs;
7682 const is_signed_int = lhs_scalar_ty.isSignedInt(mod);7743 const is_signed_int = lhs_scalar_ty.isSignedInt(mod);
...@@ -7697,11 +7758,12 @@ pub const FuncGen = struct {...@@ -7697,11 +7758,12 @@ pub const FuncGen = struct {
7697 }7758 }
76987759
7699 fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7760 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;
7701 const ty_op = self.air.instructions.items(.data)[inst].ty_op;7763 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
7702 const dest_ty = self.typeOfIndex(inst);7764 const dest_ty = self.typeOfIndex(inst);
7703 const dest_info = dest_ty.intInfo(mod);7765 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);
7705 const operand = try self.resolveInst(ty_op.operand);7767 const operand = try self.resolveInst(ty_op.operand);
7706 const operand_ty = self.typeOf(ty_op.operand);7768 const operand_ty = self.typeOf(ty_op.operand);
7707 const operand_info = operand_ty.intInfo(mod);7769 const operand_info = operand_ty.intInfo(mod);
...@@ -7719,14 +7781,16 @@ pub const FuncGen = struct {...@@ -7719,14 +7781,16 @@ pub const FuncGen = struct {
7719 }7781 }
77207782
7721 fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7783 fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7784 const o = self.dg.object;
7722 const ty_op = self.air.instructions.items(.data)[inst].ty_op;7785 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
7723 const operand = try self.resolveInst(ty_op.operand);7786 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));
7725 return self.builder.buildTrunc(operand, dest_llvm_ty, "");7788 return self.builder.buildTrunc(operand, dest_llvm_ty, "");
7726 }7789 }
77277790
7728 fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7791 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;
7730 const ty_op = self.air.instructions.items(.data)[inst].ty_op;7794 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
7731 const operand = try self.resolveInst(ty_op.operand);7795 const operand = try self.resolveInst(ty_op.operand);
7732 const operand_ty = self.typeOf(ty_op.operand);7796 const operand_ty = self.typeOf(ty_op.operand);
...@@ -7736,11 +7800,11 @@ pub const FuncGen = struct {...@@ -7736,11 +7800,11 @@ pub const FuncGen = struct {
7736 const src_bits = operand_ty.floatBits(target);7800 const src_bits = operand_ty.floatBits(target);
77377801
7738 if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) {7802 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);
7740 return self.builder.buildFPTrunc(operand, dest_llvm_ty, "");7804 return self.builder.buildFPTrunc(operand, dest_llvm_ty, "");
7741 } else {7805 } else {
7742 const operand_llvm_ty = try self.dg.lowerType(operand_ty);7806 const operand_llvm_ty = try o.lowerType(operand_ty);
7743 const dest_llvm_ty = try self.dg.lowerType(dest_ty);7807 const dest_llvm_ty = try o.lowerType(dest_ty);
77447808
7745 var fn_name_buf: [64]u8 = undefined;7809 var fn_name_buf: [64]u8 = undefined;
7746 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__trunc{s}f{s}f2", .{7810 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__trunc{s}f{s}f2", .{
...@@ -7756,7 +7820,8 @@ pub const FuncGen = struct {...@@ -7756,7 +7820,8 @@ pub const FuncGen = struct {
7756 }7820 }
77577821
7758 fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7822 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;
7760 const ty_op = self.air.instructions.items(.data)[inst].ty_op;7825 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
7761 const operand = try self.resolveInst(ty_op.operand);7826 const operand = try self.resolveInst(ty_op.operand);
7762 const operand_ty = self.typeOf(ty_op.operand);7827 const operand_ty = self.typeOf(ty_op.operand);
...@@ -7766,11 +7831,11 @@ pub const FuncGen = struct {...@@ -7766,11 +7831,11 @@ pub const FuncGen = struct {
7766 const src_bits = operand_ty.floatBits(target);7831 const src_bits = operand_ty.floatBits(target);
77677832
7768 if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) {7833 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);
7770 return self.builder.buildFPExt(operand, dest_llvm_ty, "");7835 return self.builder.buildFPExt(operand, dest_llvm_ty, "");
7771 } else {7836 } else {
7772 const operand_llvm_ty = try self.dg.lowerType(operand_ty);7837 const operand_llvm_ty = try o.lowerType(operand_ty);
7773 const dest_llvm_ty = try self.dg.lowerType(dest_ty);7838 const dest_llvm_ty = try o.lowerType(dest_ty);
77747839
7775 var fn_name_buf: [64]u8 = undefined;7840 var fn_name_buf: [64]u8 = undefined;
7776 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__extend{s}f{s}f2", .{7841 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__extend{s}f{s}f2", .{
...@@ -7786,11 +7851,12 @@ pub const FuncGen = struct {...@@ -7786,11 +7851,12 @@ pub const FuncGen = struct {
7786 }7851 }
77877852
7788 fn airIntFromPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7853 fn airIntFromPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7854 const o = self.dg.object;
7789 const un_op = self.air.instructions.items(.data)[inst].un_op;7855 const un_op = self.air.instructions.items(.data)[inst].un_op;
7790 const operand = try self.resolveInst(un_op);7856 const operand = try self.resolveInst(un_op);
7791 const ptr_ty = self.typeOf(un_op);7857 const ptr_ty = self.typeOf(un_op);
7792 const operand_ptr = self.sliceOrArrayPtr(operand, ptr_ty);7858 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));
7794 return self.builder.buildPtrToInt(operand_ptr, dest_llvm_ty, "");7860 return self.builder.buildPtrToInt(operand_ptr, dest_llvm_ty, "");
7795 }7861 }
77967862
...@@ -7803,10 +7869,11 @@ pub const FuncGen = struct {...@@ -7803,10 +7869,11 @@ pub const FuncGen = struct {
7803 }7869 }
78047870
7805 fn bitCast(self: *FuncGen, operand: *llvm.Value, operand_ty: Type, inst_ty: Type) !*llvm.Value {7871 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;
7807 const operand_is_ref = isByRef(operand_ty, mod);7874 const operand_is_ref = isByRef(operand_ty, mod);
7808 const result_is_ref = isByRef(inst_ty, mod);7875 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
7811 if (operand_is_ref and result_is_ref) {7878 if (operand_is_ref and result_is_ref) {
7812 // They are both pointers, so just return the same opaque pointer :)7879 // They are both pointers, so just return the same opaque pointer :)
...@@ -7836,7 +7903,7 @@ pub const FuncGen = struct {...@@ -7836,7 +7903,7 @@ pub const FuncGen = struct {
7836 } else {7903 } else {
7837 // If the ABI size of the element type is not evenly divisible by size in bits;7904 // If the ABI size of the element type is not evenly divisible by size in bits;
7838 // a simple bitcast will not work, and we fall back to extractelement.7905 // 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);
7840 const llvm_u32 = self.context.intType(32);7907 const llvm_u32 = self.context.intType(32);
7841 const zero = llvm_usize.constNull();7908 const zero = llvm_usize.constNull();
7842 const vector_len = operand_ty.arrayLen(mod);7909 const vector_len = operand_ty.arrayLen(mod);
...@@ -7853,7 +7920,7 @@ pub const FuncGen = struct {...@@ -7853,7 +7920,7 @@ pub const FuncGen = struct {
7853 return array_ptr;7920 return array_ptr;
7854 } else if (operand_ty.zigTypeTag(mod) == .Array and inst_ty.zigTypeTag(mod) == .Vector) {7921 } else if (operand_ty.zigTypeTag(mod) == .Array and inst_ty.zigTypeTag(mod) == .Vector) {
7855 const elem_ty = operand_ty.childType(mod);7922 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);
7857 if (!operand_is_ref) {7924 if (!operand_is_ref) {
7858 return self.dg.todo("implement bitcast non-ref array to vector", .{});7925 return self.dg.todo("implement bitcast non-ref array to vector", .{});
7859 }7926 }
...@@ -7868,9 +7935,9 @@ pub const FuncGen = struct {...@@ -7868,9 +7935,9 @@ pub const FuncGen = struct {
7868 } else {7935 } else {
7869 // If the ABI size of the element type is not evenly divisible by size in bits;7936 // If the ABI size of the element type is not evenly divisible by size in bits;
7870 // a simple bitcast will not work, and we fall back to extractelement.7937 // a simple bitcast will not work, and we fall back to extractelement.
7871 const array_llvm_ty = try self.dg.lowerType(operand_ty);7938 const array_llvm_ty = try o.lowerType(operand_ty);
7872 const elem_llvm_ty = try self.dg.lowerType(elem_ty);7939 const elem_llvm_ty = try o.lowerType(elem_ty);
7873 const llvm_usize = try self.dg.lowerType(Type.usize);7940 const llvm_usize = try o.lowerType(Type.usize);
7874 const llvm_u32 = self.context.intType(32);7941 const llvm_u32 = self.context.intType(32);
7875 const zero = llvm_usize.constNull();7942 const zero = llvm_usize.constNull();
7876 const vector_len = operand_ty.arrayLen(mod);7943 const vector_len = operand_ty.arrayLen(mod);
...@@ -7926,13 +7993,14 @@ pub const FuncGen = struct {...@@ -7926,13 +7993,14 @@ pub const FuncGen = struct {
7926 }7993 }
79277994
7928 fn airArg(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7995 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;
7930 const arg_val = self.args[self.arg_index];7998 const arg_val = self.args[self.arg_index];
7931 self.arg_index += 1;7999 self.arg_index += 1;
79328000
7933 const inst_ty = self.typeOfIndex(inst);8001 const inst_ty = self.typeOfIndex(inst);
7934 if (self.dg.object.di_builder) |dib| {8002 if (o.di_builder) |dib| {
7935 if (needDbgVarWorkaround(self.dg)) {8003 if (needDbgVarWorkaround(o)) {
7936 return arg_val;8004 return arg_val;
7937 }8005 }
79388006
...@@ -7945,7 +8013,7 @@ pub const FuncGen = struct {...@@ -7945,7 +8013,7 @@ pub const FuncGen = struct {
7945 func.getParamName(mod, src_index).ptr, // TODO test 0 bit args8013 func.getParamName(mod, src_index).ptr, // TODO test 0 bit args
7946 self.di_file.?,8014 self.di_file.?,
7947 lbrace_line,8015 lbrace_line,
7948 try self.dg.object.lowerDebugType(inst_ty, .full),8016 try o.lowerDebugType(inst_ty, .full),
7949 true, // always preserve8017 true, // always preserve
7950 0, // flags8018 0, // flags
7951 self.arg_index, // includes +1 because 0 is return type8019 self.arg_index, // includes +1 because 0 is return type
...@@ -7955,7 +8023,7 @@ pub const FuncGen = struct {...@@ -7955,7 +8023,7 @@ pub const FuncGen = struct {
7955 const insert_block = self.builder.getInsertBlock();8023 const insert_block = self.builder.getInsertBlock();
7956 if (isByRef(inst_ty, mod)) {8024 if (isByRef(inst_ty, mod)) {
7957 _ = dib.insertDeclareAtEnd(arg_val, di_local_var, debug_loc, insert_block);8025 _ = 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) {
7959 const alignment = inst_ty.abiAlignment(mod);8027 const alignment = inst_ty.abiAlignment(mod);
7960 const alloca = self.buildAlloca(arg_val.typeOf(), alignment);8028 const alloca = self.buildAlloca(arg_val.typeOf(), alignment);
7961 const store_inst = self.builder.buildStore(arg_val, alloca);8029 const store_inst = self.builder.buildStore(arg_val, alloca);
...@@ -7970,34 +8038,41 @@ pub const FuncGen = struct {...@@ -7970,34 +8038,41 @@ pub const FuncGen = struct {
7970 }8038 }
79718039
7972 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8040 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;
7974 const ptr_ty = self.typeOfIndex(inst);8043 const ptr_ty = self.typeOfIndex(inst);
7975 const pointee_type = ptr_ty.childType(mod);8044 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);
7979 const alignment = ptr_ty.ptrAlignment(mod);8049 const alignment = ptr_ty.ptrAlignment(mod);
7980 return self.buildAlloca(pointee_llvm_ty, alignment);8050 return self.buildAlloca(pointee_llvm_ty, alignment);
7981 }8051 }
79828052
7983 fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8053 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;
7985 const ptr_ty = self.typeOfIndex(inst);8056 const ptr_ty = self.typeOfIndex(inst);
7986 const ret_ty = ptr_ty.childType(mod);8057 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);
7988 if (self.ret_ptr) |ret_ptr| return ret_ptr;8059 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);
7990 return self.buildAlloca(ret_llvm_ty, ptr_ty.ptrAlignment(mod));8061 return self.buildAlloca(ret_llvm_ty, ptr_ty.ptrAlignment(mod));
7991 }8062 }
79928063
7993 /// Use this instead of builder.buildAlloca, because this function makes sure to8064 /// Use this instead of builder.buildAlloca, because this function makes sure to
7994 /// put the alloca instruction at the top of the function!8065 /// put the alloca instruction at the top of the function!
7995 fn buildAlloca(self: *FuncGen, llvm_ty: *llvm.Type, alignment: ?c_uint) *llvm.Value {8066 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);
7997 }8071 }
79988072
7999 fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !?*llvm.Value {8073 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;
8001 const bin_op = self.air.instructions.items(.data)[inst].bin_op;8076 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
8002 const dest_ptr = try self.resolveInst(bin_op.lhs);8077 const dest_ptr = try self.resolveInst(bin_op.lhs);
8003 const ptr_ty = self.typeOf(bin_op.lhs);8078 const ptr_ty = self.typeOf(bin_op.lhs);
...@@ -8014,7 +8089,7 @@ pub const FuncGen = struct {...@@ -8014,7 +8089,7 @@ pub const FuncGen = struct {
8014 else8089 else
8015 u8_llvm_ty.getUndef();8090 u8_llvm_ty.getUndef();
8016 const operand_size = operand_ty.abiSize(mod);8091 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);
8018 const len = usize_llvm_ty.constInt(operand_size, .False);8093 const len = usize_llvm_ty.constInt(operand_size, .False);
8019 const dest_ptr_align = ptr_ty.ptrAlignment(mod);8094 const dest_ptr_align = ptr_ty.ptrAlignment(mod);
8020 _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr(mod));8095 _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr(mod));
...@@ -8036,7 +8111,8 @@ pub const FuncGen = struct {...@@ -8036,7 +8111,8 @@ pub const FuncGen = struct {
8036 ///8111 ///
8037 /// The first instruction of `body_tail` is the one whose copy we want to elide.8112 /// The first instruction of `body_tail` is the one whose copy we want to elide.
8038 fn canElideLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) bool {8113 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;
8040 const ip = &mod.intern_pool;8116 const ip = &mod.intern_pool;
8041 for (body_tail[1..]) |body_inst| {8117 for (body_tail[1..]) |body_inst| {
8042 switch (fg.liveness.categorizeOperand(fg.air, body_inst, body_tail[0], ip)) {8118 switch (fg.liveness.categorizeOperand(fg.air, body_inst, body_tail[0], ip)) {
...@@ -8051,7 +8127,8 @@ pub const FuncGen = struct {...@@ -8051,7 +8127,8 @@ pub const FuncGen = struct {
8051 }8127 }
80528128
8053 fn airLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {8129 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;
8055 const inst = body_tail[0];8132 const inst = body_tail[0];
8056 const ty_op = fg.air.instructions.items(.data)[inst].ty_op;8133 const ty_op = fg.air.instructions.items(.data)[inst].ty_op;
8057 const ptr_ty = fg.typeOf(ty_op.operand);8134 const ptr_ty = fg.typeOf(ty_op.operand);
...@@ -8083,8 +8160,9 @@ pub const FuncGen = struct {...@@ -8083,8 +8160,9 @@ pub const FuncGen = struct {
80838160
8084 fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8161 fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8085 _ = inst;8162 _ = inst;
8086 const mod = self.dg.module;8163 const o = self.dg.object;
8087 const llvm_usize = try self.dg.lowerType(Type.usize);8164 const mod = o.module;
8165 const llvm_usize = try o.lowerType(Type.usize);
8088 const target = mod.getTarget();8166 const target = mod.getTarget();
8089 if (!target_util.supportsReturnAddress(target)) {8167 if (!target_util.supportsReturnAddress(target)) {
8090 // https://github.com/ziglang/zig/issues/119468168 // https://github.com/ziglang/zig/issues/11946
...@@ -8100,18 +8178,19 @@ pub const FuncGen = struct {...@@ -8100,18 +8178,19 @@ pub const FuncGen = struct {
81008178
8101 fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8179 fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8102 _ = inst;8180 _ = inst;
8181 const o = self.dg.object;
8103 const llvm_i32 = self.context.intType(32);8182 const llvm_i32 = self.context.intType(32);
8104 const llvm_fn_name = "llvm.frameaddress.p0";8183 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: {
8106 const llvm_p0i8 = self.context.pointerType(0);8185 const llvm_p0i8 = self.context.pointerType(0);
8107 const param_types = [_]*llvm.Type{llvm_i32};8186 const param_types = [_]*llvm.Type{llvm_i32};
8108 const fn_type = llvm.functionType(llvm_p0i8, &param_types, param_types.len, .False);8187 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);
8110 };8189 };
81118190
8112 const params = [_]*llvm.Value{llvm_i32.constNull()};8191 const params = [_]*llvm.Value{llvm_i32.constNull()};
8113 const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, "");8192 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);
8115 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");8194 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
8116 }8195 }
81178196
...@@ -8124,14 +8203,15 @@ pub const FuncGen = struct {...@@ -8124,14 +8203,15 @@ pub const FuncGen = struct {
8124 }8203 }
81258204
8126 fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*llvm.Value {8205 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;
8128 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;8208 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
8129 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;8209 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
8130 const ptr = try self.resolveInst(extra.ptr);8210 const ptr = try self.resolveInst(extra.ptr);
8131 var expected_value = try self.resolveInst(extra.expected_value);8211 var expected_value = try self.resolveInst(extra.expected_value);
8132 var new_value = try self.resolveInst(extra.new_value);8212 var new_value = try self.resolveInst(extra.new_value);
8133 const operand_ty = self.typeOf(extra.ptr).childType(mod);8213 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);
8135 if (opt_abi_ty) |abi_ty| {8215 if (opt_abi_ty) |abi_ty| {
8136 // operand needs widening and truncating8216 // operand needs widening and truncating
8137 if (operand_ty.isSignedInt(mod)) {8217 if (operand_ty.isSignedInt(mod)) {
...@@ -8156,7 +8236,7 @@ pub const FuncGen = struct {...@@ -8156,7 +8236,7 @@ pub const FuncGen = struct {
81568236
8157 var payload = self.builder.buildExtractValue(result, 0, "");8237 var payload = self.builder.buildExtractValue(result, 0, "");
8158 if (opt_abi_ty != null) {8238 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), "");
8160 }8240 }
8161 const success_bit = self.builder.buildExtractValue(result, 1, "");8241 const success_bit = self.builder.buildExtractValue(result, 1, "");
81628242
...@@ -8171,7 +8251,8 @@ pub const FuncGen = struct {...@@ -8171,7 +8251,8 @@ pub const FuncGen = struct {
8171 }8251 }
81728252
8173 fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8253 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;
8175 const pl_op = self.air.instructions.items(.data)[inst].pl_op;8256 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
8176 const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;8257 const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;
8177 const ptr = try self.resolveInst(pl_op.operand);8258 const ptr = try self.resolveInst(pl_op.operand);
...@@ -8183,7 +8264,7 @@ pub const FuncGen = struct {...@@ -8183,7 +8264,7 @@ pub const FuncGen = struct {
8183 const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float);8264 const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float);
8184 const ordering = toLlvmAtomicOrdering(extra.ordering());8265 const ordering = toLlvmAtomicOrdering(extra.ordering());
8185 const single_threaded = llvm.Bool.fromBool(self.single_threaded);8266 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);
8187 if (opt_abi_ty) |abi_ty| {8268 if (opt_abi_ty) |abi_ty| {
8188 // operand needs widening and truncating or bitcasting.8269 // operand needs widening and truncating or bitcasting.
8189 const casted_operand = if (is_float)8270 const casted_operand = if (is_float)
...@@ -8200,7 +8281,7 @@ pub const FuncGen = struct {...@@ -8200,7 +8281,7 @@ pub const FuncGen = struct {
8200 ordering,8281 ordering,
8201 single_threaded,8282 single_threaded,
8202 );8283 );
8203 const operand_llvm_ty = try self.dg.lowerType(operand_ty);8284 const operand_llvm_ty = try o.lowerType(operand_ty);
8204 if (is_float) {8285 if (is_float) {
8205 return self.builder.buildBitCast(uncasted_result, operand_llvm_ty, "");8286 return self.builder.buildBitCast(uncasted_result, operand_llvm_ty, "");
8206 } else {8287 } else {
...@@ -8213,7 +8294,7 @@ pub const FuncGen = struct {...@@ -8213,7 +8294,7 @@ pub const FuncGen = struct {
8213 }8294 }
82148295
8215 // It's a pointer but we need to treat it as an int.8296 // 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);
8217 const casted_operand = self.builder.buildPtrToInt(operand, usize_llvm_ty, "");8298 const casted_operand = self.builder.buildPtrToInt(operand, usize_llvm_ty, "");
8218 const uncasted_result = self.builder.buildAtomicRmw(8299 const uncasted_result = self.builder.buildAtomicRmw(
8219 op,8300 op,
...@@ -8222,12 +8303,13 @@ pub const FuncGen = struct {...@@ -8222,12 +8303,13 @@ pub const FuncGen = struct {
8222 ordering,8303 ordering,
8223 single_threaded,8304 single_threaded,
8224 );8305 );
8225 const operand_llvm_ty = try self.dg.lowerType(operand_ty);8306 const operand_llvm_ty = try o.lowerType(operand_ty);
8226 return self.builder.buildIntToPtr(uncasted_result, operand_llvm_ty, "");8307 return self.builder.buildIntToPtr(uncasted_result, operand_llvm_ty, "");
8227 }8308 }
82288309
8229 fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8310 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;
8231 const atomic_load = self.air.instructions.items(.data)[inst].atomic_load;8313 const atomic_load = self.air.instructions.items(.data)[inst].atomic_load;
8232 const ptr = try self.resolveInst(atomic_load.ptr);8314 const ptr = try self.resolveInst(atomic_load.ptr);
8233 const ptr_ty = self.typeOf(atomic_load.ptr);8315 const ptr_ty = self.typeOf(atomic_load.ptr);
...@@ -8236,11 +8318,11 @@ pub const FuncGen = struct {...@@ -8236,11 +8318,11 @@ pub const FuncGen = struct {
8236 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod))8318 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod))
8237 return null;8319 return null;
8238 const ordering = toLlvmAtomicOrdering(atomic_load.order);8320 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);
8240 const ptr_alignment = @intCast(u32, ptr_info.flags.alignment.toByteUnitsOptional() orelse8322 const ptr_alignment = @intCast(u32, ptr_info.flags.alignment.toByteUnitsOptional() orelse
8241 ptr_info.child.toType().abiAlignment(mod));8323 ptr_info.child.toType().abiAlignment(mod));
8242 const ptr_volatile = llvm.Bool.fromBool(ptr_info.flags.is_volatile);8324 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
8245 if (opt_abi_llvm_ty) |abi_llvm_ty| {8327 if (opt_abi_llvm_ty) |abi_llvm_ty| {
8246 // operand needs widening and truncating8328 // operand needs widening and truncating
...@@ -8262,14 +8344,15 @@ pub const FuncGen = struct {...@@ -8262,14 +8344,15 @@ pub const FuncGen = struct {
8262 inst: Air.Inst.Index,8344 inst: Air.Inst.Index,
8263 ordering: llvm.AtomicOrdering,8345 ordering: llvm.AtomicOrdering,
8264 ) !?*llvm.Value {8346 ) !?*llvm.Value {
8265 const mod = self.dg.module;8347 const o = self.dg.object;
8348 const mod = o.module;
8266 const bin_op = self.air.instructions.items(.data)[inst].bin_op;8349 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
8267 const ptr_ty = self.typeOf(bin_op.lhs);8350 const ptr_ty = self.typeOf(bin_op.lhs);
8268 const operand_ty = ptr_ty.childType(mod);8351 const operand_ty = ptr_ty.childType(mod);
8269 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return null;8352 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return null;
8270 const ptr = try self.resolveInst(bin_op.lhs);8353 const ptr = try self.resolveInst(bin_op.lhs);
8271 var element = try self.resolveInst(bin_op.rhs);8354 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
8274 if (opt_abi_ty) |abi_ty| {8357 if (opt_abi_ty) |abi_ty| {
8275 // operand needs widening8358 // operand needs widening
...@@ -8284,7 +8367,8 @@ pub const FuncGen = struct {...@@ -8284,7 +8367,8 @@ pub const FuncGen = struct {
8284 }8367 }
82858368
8286 fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !?*llvm.Value {8369 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;
8288 const bin_op = self.air.instructions.items(.data)[inst].bin_op;8372 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
8289 const dest_slice = try self.resolveInst(bin_op.lhs);8373 const dest_slice = try self.resolveInst(bin_op.lhs);
8290 const ptr_ty = self.typeOf(bin_op.lhs);8374 const ptr_ty = self.typeOf(bin_op.lhs);
...@@ -8366,7 +8450,7 @@ pub const FuncGen = struct {...@@ -8366,7 +8450,7 @@ pub const FuncGen = struct {
8366 .One => llvm_usize_ty.constInt(ptr_ty.childType(mod).arrayLen(mod), .False),8450 .One => llvm_usize_ty.constInt(ptr_ty.childType(mod).arrayLen(mod), .False),
8367 .Many, .C => unreachable,8451 .Many, .C => unreachable,
8368 };8452 };
8369 const elem_llvm_ty = try self.dg.lowerType(elem_ty);8453 const elem_llvm_ty = try o.lowerType(elem_ty);
8370 const len_gep = [_]*llvm.Value{len};8454 const len_gep = [_]*llvm.Value{len};
8371 const end_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, dest_ptr, &len_gep, len_gep.len, "");8455 const end_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, dest_ptr, &len_gep, len_gep.len, "");
8372 _ = self.builder.buildBr(loop_block);8456 _ = self.builder.buildBr(loop_block);
...@@ -8407,6 +8491,8 @@ pub const FuncGen = struct {...@@ -8407,6 +8491,8 @@ pub const FuncGen = struct {
8407 }8491 }
84088492
8409 fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8493 fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8494 const o = self.dg.object;
8495 const mod = o.module;
8410 const bin_op = self.air.instructions.items(.data)[inst].bin_op;8496 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
8411 const dest_slice = try self.resolveInst(bin_op.lhs);8497 const dest_slice = try self.resolveInst(bin_op.lhs);
8412 const dest_ptr_ty = self.typeOf(bin_op.lhs);8498 const dest_ptr_ty = self.typeOf(bin_op.lhs);
...@@ -8415,7 +8501,6 @@ pub const FuncGen = struct {...@@ -8415,7 +8501,6 @@ pub const FuncGen = struct {
8415 const src_ptr = self.sliceOrArrayPtr(src_slice, src_ptr_ty);8501 const src_ptr = self.sliceOrArrayPtr(src_slice, src_ptr_ty);
8416 const len = self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty);8502 const len = self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty);
8417 const dest_ptr = self.sliceOrArrayPtr(dest_slice, dest_ptr_ty);8503 const dest_ptr = self.sliceOrArrayPtr(dest_slice, dest_ptr_ty);
8418 const mod = self.dg.module;
8419 const is_volatile = src_ptr_ty.isVolatilePtr(mod) or dest_ptr_ty.isVolatilePtr(mod);8504 const is_volatile = src_ptr_ty.isVolatilePtr(mod) or dest_ptr_ty.isVolatilePtr(mod);
8420 _ = self.builder.buildMemCpy(8505 _ = self.builder.buildMemCpy(
8421 dest_ptr,8506 dest_ptr,
...@@ -8429,7 +8514,8 @@ pub const FuncGen = struct {...@@ -8429,7 +8514,8 @@ pub const FuncGen = struct {
8429 }8514 }
84308515
8431 fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8516 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;
8433 const bin_op = self.air.instructions.items(.data)[inst].bin_op;8519 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
8434 const un_ty = self.typeOf(bin_op.lhs).childType(mod);8520 const un_ty = self.typeOf(bin_op.lhs).childType(mod);
8435 const layout = un_ty.unionGetLayout(mod);8521 const layout = un_ty.unionGetLayout(mod);
...@@ -8441,7 +8527,7 @@ pub const FuncGen = struct {...@@ -8441,7 +8527,7 @@ pub const FuncGen = struct {
8441 _ = self.builder.buildStore(new_tag, union_ptr);8527 _ = self.builder.buildStore(new_tag, union_ptr);
8442 return null;8528 return null;
8443 }8529 }
8444 const un_llvm_ty = try self.dg.lowerType(un_ty);8530 const un_llvm_ty = try o.lowerType(un_ty);
8445 const tag_index = @intFromBool(layout.tag_align < layout.payload_align);8531 const tag_index = @intFromBool(layout.tag_align < layout.payload_align);
8446 const tag_field_ptr = self.builder.buildStructGEP(un_llvm_ty, union_ptr, tag_index, "");8532 const tag_field_ptr = self.builder.buildStructGEP(un_llvm_ty, union_ptr, tag_index, "");
8447 // TODO alignment on this store8533 // TODO alignment on this store
...@@ -8450,14 +8536,15 @@ pub const FuncGen = struct {...@@ -8450,14 +8536,15 @@ pub const FuncGen = struct {
8450 }8536 }
84518537
8452 fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8538 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;
8454 const ty_op = self.air.instructions.items(.data)[inst].ty_op;8541 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
8455 const un_ty = self.typeOf(ty_op.operand);8542 const un_ty = self.typeOf(ty_op.operand);
8456 const layout = un_ty.unionGetLayout(mod);8543 const layout = un_ty.unionGetLayout(mod);
8457 if (layout.tag_size == 0) return null;8544 if (layout.tag_size == 0) return null;
8458 const union_handle = try self.resolveInst(ty_op.operand);8545 const union_handle = try self.resolveInst(ty_op.operand);
8459 if (isByRef(un_ty, mod)) {8546 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);
8461 if (layout.payload_size == 0) {8548 if (layout.payload_size == 0) {
8462 return self.builder.buildLoad(llvm_un_ty, union_handle, "");8549 return self.builder.buildLoad(llvm_un_ty, union_handle, "");
8463 }8550 }
...@@ -8492,19 +8579,20 @@ pub const FuncGen = struct {...@@ -8492,19 +8579,20 @@ pub const FuncGen = struct {
8492 }8579 }
84938580
8494 fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {8581 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;
8496 const ty_op = self.air.instructions.items(.data)[inst].ty_op;8584 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
8497 const operand_ty = self.typeOf(ty_op.operand);8585 const operand_ty = self.typeOf(ty_op.operand);
8498 const operand = try self.resolveInst(ty_op.operand);8586 const operand = try self.resolveInst(ty_op.operand);
84998587
8500 const llvm_i1 = self.context.intType(1);8588 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);
8502 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});8590 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
85038591
8504 const params = [_]*llvm.Value{ operand, llvm_i1.constNull() };8592 const params = [_]*llvm.Value{ operand, llvm_i1.constNull() };
8505 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");8593 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
8506 const result_ty = self.typeOfIndex(inst);8594 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
8509 const bits = operand_ty.intInfo(mod).bits;8597 const bits = operand_ty.intInfo(mod).bits;
8510 const result_bits = result_ty.intInfo(mod).bits;8598 const result_bits = result_ty.intInfo(mod).bits;
...@@ -8518,18 +8606,19 @@ pub const FuncGen = struct {...@@ -8518,18 +8606,19 @@ pub const FuncGen = struct {
8518 }8606 }
85198607
8520 fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {8608 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;
8522 const ty_op = self.air.instructions.items(.data)[inst].ty_op;8611 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
8523 const operand_ty = self.typeOf(ty_op.operand);8612 const operand_ty = self.typeOf(ty_op.operand);
8524 const operand = try self.resolveInst(ty_op.operand);8613 const operand = try self.resolveInst(ty_op.operand);
85258614
8526 const params = [_]*llvm.Value{operand};8615 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);
8528 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});8617 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
85298618
8530 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");8619 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
8531 const result_ty = self.typeOfIndex(inst);8620 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
8534 const bits = operand_ty.intInfo(mod).bits;8623 const bits = operand_ty.intInfo(mod).bits;
8535 const result_bits = result_ty.intInfo(mod).bits;8624 const result_bits = result_ty.intInfo(mod).bits;
...@@ -8543,14 +8632,15 @@ pub const FuncGen = struct {...@@ -8543,14 +8632,15 @@ pub const FuncGen = struct {
8543 }8632 }
85448633
8545 fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {8634 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;
8547 const ty_op = self.air.instructions.items(.data)[inst].ty_op;8637 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
8548 const operand_ty = self.typeOf(ty_op.operand);8638 const operand_ty = self.typeOf(ty_op.operand);
8549 var bits = operand_ty.intInfo(mod).bits;8639 var bits = operand_ty.intInfo(mod).bits;
8550 assert(bits % 8 == 0);8640 assert(bits % 8 == 0);
85518641
8552 var operand = try self.resolveInst(ty_op.operand);8642 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
8555 if (bits % 16 == 8) {8645 if (bits % 16 == 8) {
8556 // If not an even byte-multiple, we need zero-extend + shift-left 1 byte8646 // If not an even byte-multiple, we need zero-extend + shift-left 1 byte
...@@ -8584,7 +8674,7 @@ pub const FuncGen = struct {...@@ -8584,7 +8674,7 @@ pub const FuncGen = struct {
8584 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");8674 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
85858675
8586 const result_ty = self.typeOfIndex(inst);8676 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);
8588 const result_bits = result_ty.intInfo(mod).bits;8678 const result_bits = result_ty.intInfo(mod).bits;
8589 if (bits > result_bits) {8679 if (bits > result_bits) {
8590 return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, "");8680 return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, "");
...@@ -8596,7 +8686,8 @@ pub const FuncGen = struct {...@@ -8596,7 +8686,8 @@ pub const FuncGen = struct {
8596 }8686 }
85978687
8598 fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8688 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;
8600 const ty_op = self.air.instructions.items(.data)[inst].ty_op;8691 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
8601 const operand = try self.resolveInst(ty_op.operand);8692 const operand = try self.resolveInst(ty_op.operand);
8602 const error_set_ty = self.air.getRefType(ty_op.ty);8693 const error_set_ty = self.air.getRefType(ty_op.ty);
...@@ -8609,7 +8700,7 @@ pub const FuncGen = struct {...@@ -8609,7 +8700,7 @@ pub const FuncGen = struct {
86098700
8610 for (names) |name| {8701 for (names) |name| {
8611 const err_int = @intCast(Module.ErrorInt, mod.global_error_set.getIndex(name).?);8702 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(.{
8613 .ty = Type.err_int,8704 .ty = Type.err_int,
8614 .val = try mod.intValue(Type.err_int, err_int),8705 .val = try mod.intValue(Type.err_int, err_int),
8615 });8706 });
...@@ -8646,13 +8737,14 @@ pub const FuncGen = struct {...@@ -8646,13 +8737,14 @@ pub const FuncGen = struct {
8646 }8737 }
86478738
8648 fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !*llvm.Value {8739 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;
8650 const enum_type = mod.intern_pool.indexToKey(enum_ty.toIntern()).enum_type;8742 const enum_type = mod.intern_pool.indexToKey(enum_ty.toIntern()).enum_type;
86518743
8652 // TODO: detect when the type changes and re-emit this function.8744 // 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);
8654 if (gop.found_existing) return gop.value_ptr.*;8746 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
8657 var arena_allocator = std.heap.ArenaAllocator.init(self.gpa);8749 var arena_allocator = std.heap.ArenaAllocator.init(self.gpa);
8658 defer arena_allocator.deinit();8750 defer arena_allocator.deinit();
...@@ -8661,14 +8753,14 @@ pub const FuncGen = struct {...@@ -8661,14 +8753,14 @@ pub const FuncGen = struct {
8661 const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);8753 const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);
8662 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{}", .{fqn.fmt(&mod.intern_pool)});8754 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);
8667 const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False);8759 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);
8669 fn_val.setLinkage(.Internal);8761 fn_val.setLinkage(.Internal);
8670 fn_val.setFunctionCallConv(.Fast);8762 fn_val.setFunctionCallConv(.Fast);
8671 self.dg.addCommonFnAttributes(fn_val);8763 o.addCommonFnAttributes(fn_val);
8672 gop.value_ptr.* = fn_val;8764 gop.value_ptr.* = fn_val;
86738765
8674 const prev_block = self.builder.getInsertBlock();8766 const prev_block = self.builder.getInsertBlock();
...@@ -8692,7 +8784,7 @@ pub const FuncGen = struct {...@@ -8692,7 +8784,7 @@ pub const FuncGen = struct {
8692 for (enum_type.names, 0..) |_, field_index_usize| {8784 for (enum_type.names, 0..) |_, field_index_usize| {
8693 const field_index = @intCast(u32, field_index_usize);8785 const field_index = @intCast(u32, field_index_usize);
8694 const this_tag_int_value = int: {8786 const this_tag_int_value = int: {
8695 break :int try self.dg.lowerValue(.{8787 break :int try o.lowerValue(.{
8696 .ty = enum_ty,8788 .ty = enum_ty,
8697 .val = try mod.enumValueFieldIndex(enum_ty, field_index),8789 .val = try mod.enumValueFieldIndex(enum_ty, field_index),
8698 });8790 });
...@@ -8718,13 +8810,14 @@ pub const FuncGen = struct {...@@ -8718,13 +8810,14 @@ pub const FuncGen = struct {
8718 }8810 }
87198811
8720 fn getEnumTagNameFunction(self: *FuncGen, enum_ty: Type) !*llvm.Value {8812 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;
8722 const enum_type = mod.intern_pool.indexToKey(enum_ty.toIntern()).enum_type;8815 const enum_type = mod.intern_pool.indexToKey(enum_ty.toIntern()).enum_type;
87238816
8724 // TODO: detect when the type changes and re-emit this function.8817 // 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);
8726 if (gop.found_existing) return gop.value_ptr.*;8819 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
8729 var arena_allocator = std.heap.ArenaAllocator.init(self.gpa);8822 var arena_allocator = std.heap.ArenaAllocator.init(self.gpa);
8730 defer arena_allocator.deinit();8823 defer arena_allocator.deinit();
...@@ -8734,17 +8827,17 @@ pub const FuncGen = struct {...@@ -8734,17 +8827,17 @@ pub const FuncGen = struct {
8734 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{fqn.fmt(&mod.intern_pool)});8827 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{fqn.fmt(&mod.intern_pool)});
87358828
8736 const slice_ty = Type.slice_const_u8_sentinel_0;8829 const slice_ty = Type.slice_const_u8_sentinel_0;
8737 const llvm_ret_ty = try self.dg.lowerType(slice_ty);8830 const llvm_ret_ty = try o.lowerType(slice_ty);
8738 const usize_llvm_ty = try self.dg.lowerType(Type.usize);8831 const usize_llvm_ty = try o.lowerType(Type.usize);
8739 const slice_alignment = slice_ty.abiAlignment(mod);8832 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
8743 const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False);8836 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);
8745 fn_val.setLinkage(.Internal);8838 fn_val.setLinkage(.Internal);
8746 fn_val.setFunctionCallConv(.Fast);8839 fn_val.setFunctionCallConv(.Fast);
8747 self.dg.addCommonFnAttributes(fn_val);8840 o.addCommonFnAttributes(fn_val);
8748 gop.value_ptr.* = fn_val;8841 gop.value_ptr.* = fn_val;
87498842
8750 const prev_block = self.builder.getInsertBlock();8843 const prev_block = self.builder.getInsertBlock();
...@@ -8773,7 +8866,7 @@ pub const FuncGen = struct {...@@ -8773,7 +8866,7 @@ pub const FuncGen = struct {
8773 const name = mod.intern_pool.stringToSlice(name_ip);8866 const name = mod.intern_pool.stringToSlice(name_ip);
8774 const str_init = self.context.constString(name.ptr, @intCast(c_uint, name.len), .False);8867 const str_init = self.context.constString(name.ptr, @intCast(c_uint, name.len), .False);
8775 const str_init_llvm_ty = str_init.typeOf();8868 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, "");
8777 str_global.setInitializer(str_init);8870 str_global.setInitializer(str_init);
8778 str_global.setLinkage(.Private);8871 str_global.setLinkage(.Private);
8779 str_global.setGlobalConstant(.True);8872 str_global.setGlobalConstant(.True);
...@@ -8785,7 +8878,7 @@ pub const FuncGen = struct {...@@ -8785,7 +8878,7 @@ pub const FuncGen = struct {
8785 usize_llvm_ty.constInt(name.len, .False),8878 usize_llvm_ty.constInt(name.len, .False),
8786 };8879 };
8787 const slice_init = llvm_ret_ty.constNamedStruct(&slice_fields, slice_fields.len);8880 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(), "");
8789 slice_global.setInitializer(slice_init);8882 slice_global.setInitializer(slice_init);
8790 slice_global.setLinkage(.Private);8883 slice_global.setLinkage(.Private);
8791 slice_global.setGlobalConstant(.True);8884 slice_global.setGlobalConstant(.True);
...@@ -8793,7 +8886,7 @@ pub const FuncGen = struct {...@@ -8793,7 +8886,7 @@ pub const FuncGen = struct {
8793 slice_global.setAlignment(slice_alignment);8886 slice_global.setAlignment(slice_alignment);
87948887
8795 const return_block = self.context.appendBasicBlock(fn_val, "Name");8888 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(.{
8797 .ty = enum_ty,8890 .ty = enum_ty,
8798 .val = try mod.enumValueFieldIndex(enum_ty, field_index),8891 .val = try mod.enumValueFieldIndex(enum_ty, field_index),
8799 });8892 });
...@@ -8811,29 +8904,32 @@ pub const FuncGen = struct {...@@ -8811,29 +8904,32 @@ pub const FuncGen = struct {
8811 }8904 }
88128905
8813 fn getCmpLtErrorsLenFunction(self: *FuncGen) !*llvm.Value {8906 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| {
8815 return llvm_fn;8910 return llvm_fn;
8816 }8911 }
88178912
8818 // Function signature: fn (anyerror) bool8913 // Function signature: fn (anyerror) bool
88198914
8820 const ret_llvm_ty = try self.dg.lowerType(Type.bool);8915 const ret_llvm_ty = try o.lowerType(Type.bool);
8821 const anyerror_llvm_ty = try self.dg.lowerType(Type.anyerror);8916 const anyerror_llvm_ty = try o.lowerType(Type.anyerror);
8822 const param_types = [_]*llvm.Type{anyerror_llvm_ty};8917 const param_types = [_]*llvm.Type{anyerror_llvm_ty};
88238918
8824 const fn_type = llvm.functionType(ret_llvm_ty, &param_types, param_types.len, .False);8919 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);
8826 llvm_fn.setLinkage(.Internal);8921 llvm_fn.setLinkage(.Internal);
8827 llvm_fn.setFunctionCallConv(.Fast);8922 llvm_fn.setFunctionCallConv(.Fast);
8828 self.dg.addCommonFnAttributes(llvm_fn);8923 o.addCommonFnAttributes(llvm_fn);
8829 return llvm_fn;8924 return llvm_fn;
8830 }8925 }
88318926
8832 fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8927 fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8928 const o = self.dg.object;
8833 const un_op = self.air.instructions.items(.data)[inst].un_op;8929 const un_op = self.air.instructions.items(.data)[inst].un_op;
8834 const operand = try self.resolveInst(un_op);8930 const operand = try self.resolveInst(un_op);
8835 const slice_ty = self.typeOfIndex(inst);8931 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
8838 const error_name_table_ptr = try self.getErrorNameTable();8934 const error_name_table_ptr = try self.getErrorNameTable();
8839 const ptr_slice_llvm_ty = self.context.pointerType(0);8935 const ptr_slice_llvm_ty = self.context.pointerType(0);
...@@ -8844,7 +8940,8 @@ pub const FuncGen = struct {...@@ -8844,7 +8940,8 @@ pub const FuncGen = struct {
8844 }8940 }
88458941
8846 fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8942 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;
8848 const ty_op = self.air.instructions.items(.data)[inst].ty_op;8945 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
8849 const scalar = try self.resolveInst(ty_op.operand);8946 const scalar = try self.resolveInst(ty_op.operand);
8850 const vector_ty = self.typeOfIndex(inst);8947 const vector_ty = self.typeOfIndex(inst);
...@@ -8863,7 +8960,8 @@ pub const FuncGen = struct {...@@ -8863,7 +8960,8 @@ pub const FuncGen = struct {
8863 }8960 }
88648961
8865 fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8962 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;
8867 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;8965 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
8868 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;8966 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
8869 const a = try self.resolveInst(extra.a);8967 const a = try self.resolveInst(extra.a);
...@@ -8916,7 +9014,8 @@ pub const FuncGen = struct {...@@ -8916,7 +9014,8 @@ pub const FuncGen = struct {
8916 vector_len: usize,9014 vector_len: usize,
8917 accum_init: *llvm.Value,9015 accum_init: *llvm.Value,
8918 ) !*llvm.Value {9016 ) !*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);
8920 const llvm_vector_len = llvm_usize_ty.constInt(vector_len, .False);9019 const llvm_vector_len = llvm_usize_ty.constInt(vector_len, .False);
8921 const llvm_result_ty = accum_init.typeOf();9020 const llvm_result_ty = accum_init.typeOf();
89229021
...@@ -8963,7 +9062,8 @@ pub const FuncGen = struct {...@@ -8963,7 +9062,8 @@ pub const FuncGen = struct {
89639062
8964 fn airReduce(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {9063 fn airReduce(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
8965 self.builder.setFastMath(want_fast_math);9064 self.builder.setFastMath(want_fast_math);
8966 const mod = self.dg.module;9065 const o = self.dg.object;
9066 const mod = o.module;
8967 const target = mod.getTarget();9067 const target = mod.getTarget();
89689068
8969 const reduce = self.air.instructions.items(.data)[inst].reduce;9069 const reduce = self.air.instructions.items(.data)[inst].reduce;
...@@ -8992,7 +9092,7 @@ pub const FuncGen = struct {...@@ -8992,7 +9092,7 @@ pub const FuncGen = struct {
8992 .Add => switch (scalar_ty.zigTypeTag(mod)) {9092 .Add => switch (scalar_ty.zigTypeTag(mod)) {
8993 .Int => return self.builder.buildAddReduce(operand),9093 .Int => return self.builder.buildAddReduce(operand),
8994 .Float => if (intrinsicsAllowed(scalar_ty, target)) {9094 .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);
8996 const neutral_value = scalar_llvm_ty.constReal(-0.0);9096 const neutral_value = scalar_llvm_ty.constReal(-0.0);
8997 return self.builder.buildFPAddReduce(neutral_value, operand);9097 return self.builder.buildFPAddReduce(neutral_value, operand);
8998 },9098 },
...@@ -9001,7 +9101,7 @@ pub const FuncGen = struct {...@@ -9001,7 +9101,7 @@ pub const FuncGen = struct {
9001 .Mul => switch (scalar_ty.zigTypeTag(mod)) {9101 .Mul => switch (scalar_ty.zigTypeTag(mod)) {
9002 .Int => return self.builder.buildMulReduce(operand),9102 .Int => return self.builder.buildMulReduce(operand),
9003 .Float => if (intrinsicsAllowed(scalar_ty, target)) {9103 .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);
9005 const neutral_value = scalar_llvm_ty.constReal(1.0);9105 const neutral_value = scalar_llvm_ty.constReal(1.0);
9006 return self.builder.buildFPMulReduce(neutral_value, operand);9106 return self.builder.buildFPMulReduce(neutral_value, operand);
9007 },9107 },
...@@ -9029,10 +9129,10 @@ pub const FuncGen = struct {...@@ -9029,10 +9129,10 @@ pub const FuncGen = struct {
9029 else => unreachable,9129 else => unreachable,
9030 };9130 };
90319131
9032 const param_llvm_ty = try self.dg.lowerType(scalar_ty);9132 const param_llvm_ty = try o.lowerType(scalar_ty);
9033 const param_types = [2]*llvm.Type{ param_llvm_ty, param_llvm_ty };9133 const param_types = [2]*llvm.Type{ param_llvm_ty, param_llvm_ty };
9034 const libc_fn = self.getLibcFunction(fn_name, &param_types, param_llvm_ty);9134 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(.{
9036 .ty = scalar_ty,9136 .ty = scalar_ty,
9037 .val = try mod.floatValue(scalar_ty, switch (reduce.operation) {9137 .val = try mod.floatValue(scalar_ty, switch (reduce.operation) {
9038 .Min => std.math.nan(f32),9138 .Min => std.math.nan(f32),
...@@ -9046,12 +9146,13 @@ pub const FuncGen = struct {...@@ -9046,12 +9146,13 @@ pub const FuncGen = struct {
9046 }9146 }
90479147
9048 fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {9148 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;
9050 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;9151 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
9051 const result_ty = self.typeOfIndex(inst);9152 const result_ty = self.typeOfIndex(inst);
9052 const len = @intCast(usize, result_ty.arrayLen(mod));9153 const len = @intCast(usize, result_ty.arrayLen(mod));
9053 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);9154 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
9056 switch (result_ty.zigTypeTag(mod)) {9157 switch (result_ty.zigTypeTag(mod)) {
9057 .Vector => {9158 .Vector => {
...@@ -9139,7 +9240,7 @@ pub const FuncGen = struct {...@@ -9139,7 +9240,7 @@ pub const FuncGen = struct {
9139 .Array => {9240 .Array => {
9140 assert(isByRef(result_ty, mod));9241 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);
9143 const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod));9244 const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod));
91449245
9145 const array_info = result_ty.arrayInfo(mod);9246 const array_info = result_ty.arrayInfo(mod);
...@@ -9177,11 +9278,12 @@ pub const FuncGen = struct {...@@ -9177,11 +9278,12 @@ pub const FuncGen = struct {
9177 }9278 }
91789279
9179 fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {9280 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;
9181 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;9283 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
9182 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;9284 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
9183 const union_ty = self.typeOfIndex(inst);9285 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);
9185 const layout = union_ty.unionGetLayout(mod);9287 const layout = union_ty.unionGetLayout(mod);
9186 const union_obj = mod.typeToUnion(union_ty).?;9288 const union_obj = mod.typeToUnion(union_ty).?;
91879289
...@@ -9223,7 +9325,7 @@ pub const FuncGen = struct {...@@ -9223,7 +9325,7 @@ pub const FuncGen = struct {
9223 const llvm_payload = try self.resolveInst(extra.init);9325 const llvm_payload = try self.resolveInst(extra.init);
9224 assert(union_obj.haveFieldTypes());9326 assert(union_obj.haveFieldTypes());
9225 const field = union_obj.fields.values()[extra.field_index];9327 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);
9227 const field_size = field.ty.abiSize(mod);9329 const field_size = field.ty.abiSize(mod);
9228 const field_align = field.normalAlignment(mod);9330 const field_align = field.normalAlignment(mod);
92299331
...@@ -9246,7 +9348,7 @@ pub const FuncGen = struct {...@@ -9246,7 +9348,7 @@ pub const FuncGen = struct {
9246 const fields: [1]*llvm.Type = .{payload};9348 const fields: [1]*llvm.Type = .{payload};
9247 break :t self.context.structType(&fields, fields.len, .False);9349 break :t self.context.structType(&fields, fields.len, .False);
9248 }9350 }
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);
9250 var fields: [3]*llvm.Type = undefined;9352 var fields: [3]*llvm.Type = undefined;
9251 var fields_len: c_uint = 2;9353 var fields_len: c_uint = 2;
9252 if (layout.tag_align >= layout.payload_align) {9354 if (layout.tag_align >= layout.payload_align) {
...@@ -9299,7 +9401,7 @@ pub const FuncGen = struct {...@@ -9299,7 +9401,7 @@ pub const FuncGen = struct {
9299 index_type.constInt(@intFromBool(layout.tag_align < layout.payload_align), .False),9401 index_type.constInt(@intFromBool(layout.tag_align < layout.payload_align), .False),
9300 };9402 };
9301 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, indices.len, "");9403 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);
9303 const llvm_tag = tag_llvm_ty.constInt(tag_int, .False);9405 const llvm_tag = tag_llvm_ty.constInt(tag_int, .False);
9304 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);9406 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);
9305 store_inst.setAlignment(union_obj.tag_ty.abiAlignment(mod));9407 store_inst.setAlignment(union_obj.tag_ty.abiAlignment(mod));
...@@ -9309,6 +9411,7 @@ pub const FuncGen = struct {...@@ -9309,6 +9411,7 @@ pub const FuncGen = struct {
9309 }9411 }
93109412
9311 fn airPrefetch(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {9413 fn airPrefetch(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9414 const o = self.dg.object;
9312 const prefetch = self.air.instructions.items(.data)[inst].prefetch;9415 const prefetch = self.air.instructions.items(.data)[inst].prefetch;
93139416
9314 comptime assert(@intFromEnum(std.builtin.PrefetchOptions.Rw.read) == 0);9417 comptime assert(@intFromEnum(std.builtin.PrefetchOptions.Rw.read) == 0);
...@@ -9326,7 +9429,7 @@ pub const FuncGen = struct {...@@ -9326,7 +9429,7 @@ pub const FuncGen = struct {
9326 // by the target.9429 // by the target.
9327 // To work around this, don't emit llvm.prefetch in this case.9430 // To work around this, don't emit llvm.prefetch in this case.
9328 // See https://bugs.llvm.org/show_bug.cgi?id=210379431 // See https://bugs.llvm.org/show_bug.cgi?id=21037
9329 const mod = self.dg.module;9432 const mod = o.module;
9330 const target = mod.getTarget();9433 const target = mod.getTarget();
9331 switch (prefetch.cache) {9434 switch (prefetch.cache) {
9332 .instruction => switch (target.cpu.arch) {9435 .instruction => switch (target.cpu.arch) {
...@@ -9352,14 +9455,14 @@ pub const FuncGen = struct {...@@ -9352,14 +9455,14 @@ pub const FuncGen = struct {
9352 const llvm_u32 = self.context.intType(32);9455 const llvm_u32 = self.context.intType(32);
93539456
9354 const llvm_fn_name = "llvm.prefetch.p0";9457 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: {
9356 // declare void @llvm.prefetch(i8*, i32, i32, i32)9459 // declare void @llvm.prefetch(i8*, i32, i32, i32)
9357 const llvm_void = self.context.voidType();9460 const llvm_void = self.context.voidType();
9358 const param_types = [_]*llvm.Type{9461 const param_types = [_]*llvm.Type{
9359 llvm_ptr_u8, llvm_u32, llvm_u32, llvm_u32,9462 llvm_ptr_u8, llvm_u32, llvm_u32, llvm_u32,
9360 };9463 };
9361 const fn_type = llvm.functionType(llvm_void, &param_types, param_types.len, .False);9464 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);
9363 };9466 };
93649467
9365 const ptr = try self.resolveInst(prefetch.ptr);9468 const ptr = try self.resolveInst(prefetch.ptr);
...@@ -9375,11 +9478,12 @@ pub const FuncGen = struct {...@@ -9375,11 +9478,12 @@ pub const FuncGen = struct {
9375 }9478 }
93769479
9377 fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {9480 fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9481 const o = self.dg.object;
9378 const ty_op = self.air.instructions.items(.data)[inst].ty_op;9482 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
9379 const inst_ty = self.typeOfIndex(inst);9483 const inst_ty = self.typeOfIndex(inst);
9380 const operand = try self.resolveInst(ty_op.operand);9484 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);
9383 return self.builder.buildAddrSpaceCast(operand, llvm_dest_ty, "");9487 return self.builder.buildAddrSpaceCast(operand, llvm_dest_ty, "");
9384 }9488 }
93859489
...@@ -9399,7 +9503,8 @@ pub const FuncGen = struct {...@@ -9399,7 +9503,8 @@ pub const FuncGen = struct {
9399 }9503 }
94009504
9401 fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {9505 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();
9403 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures9508 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
94049509
9405 const pl_op = self.air.instructions.items(.data)[inst].pl_op;9510 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
...@@ -9408,7 +9513,8 @@ pub const FuncGen = struct {...@@ -9408,7 +9513,8 @@ pub const FuncGen = struct {
9408 }9513 }
94099514
9410 fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {9515 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();
9412 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures9518 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
94139519
9414 const pl_op = self.air.instructions.items(.data)[inst].pl_op;9520 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
...@@ -9437,7 +9543,8 @@ pub const FuncGen = struct {...@@ -9437,7 +9543,8 @@ pub const FuncGen = struct {
9437 }9543 }
94389544
9439 fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {9545 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();
9441 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures9548 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
94429549
9443 const pl_op = self.air.instructions.items(.data)[inst].pl_op;9550 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
...@@ -9446,23 +9553,24 @@ pub const FuncGen = struct {...@@ -9446,23 +9553,24 @@ pub const FuncGen = struct {
9446 }9553 }
94479554
9448 fn getErrorNameTable(self: *FuncGen) !*llvm.Value {9555 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| {
9450 return table;9558 return table;
9451 }9559 }
94529560
9453 const mod = self.dg.module;9561 const mod = o.module;
9454 const slice_ty = Type.slice_const_u8_sentinel_0;9562 const slice_ty = Type.slice_const_u8_sentinel_0;
9455 const slice_alignment = slice_ty.abiAlignment(mod);9563 const slice_alignment = slice_ty.abiAlignment(mod);
9456 const llvm_slice_ptr_ty = self.context.pointerType(0); // TODO: Address space9564 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");
9459 error_name_table_global.setInitializer(llvm_slice_ptr_ty.getUndef());9567 error_name_table_global.setInitializer(llvm_slice_ptr_ty.getUndef());
9460 error_name_table_global.setLinkage(.Private);9568 error_name_table_global.setLinkage(.Private);
9461 error_name_table_global.setGlobalConstant(.True);9569 error_name_table_global.setGlobalConstant(.True);
9462 error_name_table_global.setUnnamedAddr(.True);9570 error_name_table_global.setUnnamedAddr(.True);
9463 error_name_table_global.setAlignment(slice_alignment);9571 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;
9466 return error_name_table_global;9574 return error_name_table_global;
9467 }9575 }
94689576
...@@ -9494,7 +9602,8 @@ pub const FuncGen = struct {...@@ -9494,7 +9602,8 @@ pub const FuncGen = struct {
9494 opt_ty: Type,9602 opt_ty: Type,
9495 can_elide_load: bool,9603 can_elide_load: bool,
9496 ) !*llvm.Value {9604 ) !*llvm.Value {
9497 const mod = fg.dg.module;9605 const o = fg.dg.object;
9606 const mod = o.module;
9498 const payload_ty = opt_ty.optionalChild(mod);9607 const payload_ty = opt_ty.optionalChild(mod);
94999608
9500 if (isByRef(opt_ty, mod)) {9609 if (isByRef(opt_ty, mod)) {
...@@ -9508,7 +9617,7 @@ pub const FuncGen = struct {...@@ -9508,7 +9617,7 @@ pub const FuncGen = struct {
95089617
9509 return fg.loadByRef(payload_ptr, payload_ty, payload_alignment, false);9618 return fg.loadByRef(payload_ptr, payload_ty, payload_alignment, false);
9510 }9619 }
9511 const payload_llvm_ty = try fg.dg.lowerType(payload_ty);9620 const payload_llvm_ty = try o.lowerType(payload_ty);
9512 const load_inst = fg.builder.buildLoad(payload_llvm_ty, payload_ptr, "");9621 const load_inst = fg.builder.buildLoad(payload_llvm_ty, payload_ptr, "");
9513 load_inst.setAlignment(payload_alignment);9622 load_inst.setAlignment(payload_alignment);
9514 return load_inst;9623 return load_inst;
...@@ -9524,9 +9633,10 @@ pub const FuncGen = struct {...@@ -9524,9 +9633,10 @@ pub const FuncGen = struct {
9524 payload: *llvm.Value,9633 payload: *llvm.Value,
9525 non_null_bit: *llvm.Value,9634 non_null_bit: *llvm.Value,
9526 ) !?*llvm.Value {9635 ) !?*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);
9528 const non_null_field = self.builder.buildZExt(non_null_bit, self.context.intType(8), "");9638 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
9531 if (isByRef(optional_ty, mod)) {9641 if (isByRef(optional_ty, mod)) {
9532 const payload_alignment = optional_ty.abiAlignment(mod);9642 const payload_alignment = optional_ty.abiAlignment(mod);
...@@ -9557,7 +9667,8 @@ pub const FuncGen = struct {...@@ -9557,7 +9667,8 @@ pub const FuncGen = struct {
9557 struct_ptr_ty: Type,9667 struct_ptr_ty: Type,
9558 field_index: u32,9668 field_index: u32,
9559 ) !?*llvm.Value {9669 ) !?*llvm.Value {
9560 const mod = self.dg.module;9670 const o = self.dg.object;
9671 const mod = o.module;
9561 const struct_ty = struct_ptr_ty.childType(mod);9672 const struct_ty = struct_ptr_ty.childType(mod);
9562 switch (struct_ty.zigTypeTag(mod)) {9673 switch (struct_ty.zigTypeTag(mod)) {
9563 .Struct => switch (struct_ty.containerLayout(mod)) {9674 .Struct => switch (struct_ty.containerLayout(mod)) {
...@@ -9578,13 +9689,13 @@ pub const FuncGen = struct {...@@ -9578,13 +9689,13 @@ pub const FuncGen = struct {
9578 const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, mod);9689 const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, mod);
9579 if (byte_offset == 0) return struct_ptr;9690 if (byte_offset == 0) return struct_ptr;
9580 const byte_llvm_ty = self.context.intType(8);9691 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);
9582 const llvm_index = llvm_usize.constInt(byte_offset, .False);9693 const llvm_index = llvm_usize.constInt(byte_offset, .False);
9583 const indices: [1]*llvm.Value = .{llvm_index};9694 const indices: [1]*llvm.Value = .{llvm_index};
9584 return self.builder.buildInBoundsGEP(byte_llvm_ty, struct_ptr, &indices, indices.len, "");9695 return self.builder.buildInBoundsGEP(byte_llvm_ty, struct_ptr, &indices, indices.len, "");
9585 },9696 },
9586 else => {9697 else => {
9587 const struct_llvm_ty = try self.dg.lowerPtrElemTy(struct_ty);9698 const struct_llvm_ty = try o.lowerPtrElemTy(struct_ty);
95889699
9589 if (llvmField(struct_ty, field_index, mod)) |llvm_field| {9700 if (llvmField(struct_ty, field_index, mod)) |llvm_field| {
9590 return self.builder.buildStructGEP(struct_llvm_ty, struct_ptr, llvm_field.index, "");9701 return self.builder.buildStructGEP(struct_llvm_ty, struct_ptr, llvm_field.index, "");
...@@ -9604,7 +9715,7 @@ pub const FuncGen = struct {...@@ -9604,7 +9715,7 @@ pub const FuncGen = struct {
9604 const layout = struct_ty.unionGetLayout(mod);9715 const layout = struct_ty.unionGetLayout(mod);
9605 if (layout.payload_size == 0 or struct_ty.containerLayout(mod) == .Packed) return struct_ptr;9716 if (layout.payload_size == 0 or struct_ty.containerLayout(mod) == .Packed) return struct_ptr;
9606 const payload_index = @intFromBool(layout.tag_align >= layout.payload_align);9717 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);
9608 const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_ptr, payload_index, "");9719 const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_ptr, payload_index, "");
9609 return union_field_ptr;9720 return union_field_ptr;
9610 },9721 },
...@@ -9612,10 +9723,11 @@ pub const FuncGen = struct {...@@ -9612,10 +9723,11 @@ pub const FuncGen = struct {
9612 }9723 }
9613 }9724 }
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 {
9616 const id = llvm.lookupIntrinsicID(name.ptr, name.len);9727 const id = llvm.lookupIntrinsicID(name.ptr, name.len);
9617 assert(id != 0);9728 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);
9619 }9731 }
96209732
9621 /// Load a by-ref type by constructing a new alloca and performing a memcpy.9733 /// Load a by-ref type by constructing a new alloca and performing a memcpy.
...@@ -9626,8 +9738,9 @@ pub const FuncGen = struct {...@@ -9626,8 +9738,9 @@ pub const FuncGen = struct {
9626 ptr_alignment: u32,9738 ptr_alignment: u32,
9627 is_volatile: bool,9739 is_volatile: bool,
9628 ) !*llvm.Value {9740 ) !*llvm.Value {
9629 const mod = fg.dg.module;9741 const o = fg.dg.object;
9630 const pointee_llvm_ty = try fg.dg.lowerType(pointee_type);9742 const mod = o.module;
9743 const pointee_llvm_ty = try o.lowerType(pointee_type);
9631 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(mod));9744 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(mod));
9632 const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align);9745 const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align);
9633 const llvm_usize = fg.context.intType(Type.usize.intInfo(mod).bits);9746 const llvm_usize = fg.context.intType(Type.usize.intInfo(mod).bits);
...@@ -9647,7 +9760,8 @@ pub const FuncGen = struct {...@@ -9647,7 +9760,8 @@ pub const FuncGen = struct {
9647 /// alloca and copies the value into it, then returns the alloca instruction.9760 /// alloca and copies the value into it, then returns the alloca instruction.
9648 /// For isByRef=false types, it creates a load instruction and returns it.9761 /// For isByRef=false types, it creates a load instruction and returns it.
9649 fn load(self: *FuncGen, ptr: *llvm.Value, ptr_ty: Type) !?*llvm.Value {9762 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;
9651 const info = ptr_ty.ptrInfo(mod);9765 const info = ptr_ty.ptrInfo(mod);
9652 const elem_ty = info.child.toType();9766 const elem_ty = info.child.toType();
9653 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;9767 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
...@@ -9659,7 +9773,7 @@ pub const FuncGen = struct {...@@ -9659,7 +9773,7 @@ pub const FuncGen = struct {
9659 assert(info.flags.vector_index != .runtime);9773 assert(info.flags.vector_index != .runtime);
9660 if (info.flags.vector_index != .none) {9774 if (info.flags.vector_index != .none) {
9661 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False);9775 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);
9663 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);9777 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);
96649778
9665 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");9779 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");
...@@ -9673,7 +9787,7 @@ pub const FuncGen = struct {...@@ -9673,7 +9787,7 @@ pub const FuncGen = struct {
9673 if (isByRef(elem_ty, mod)) {9787 if (isByRef(elem_ty, mod)) {
9674 return self.loadByRef(ptr, elem_ty, ptr_alignment, info.flags.is_volatile);9788 return self.loadByRef(ptr, elem_ty, ptr_alignment, info.flags.is_volatile);
9675 }9789 }
9676 const elem_llvm_ty = try self.dg.lowerType(elem_ty);9790 const elem_llvm_ty = try o.lowerType(elem_ty);
9677 const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, "");9791 const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, "");
9678 llvm_inst.setAlignment(ptr_alignment);9792 llvm_inst.setAlignment(ptr_alignment);
9679 llvm_inst.setVolatile(ptr_volatile);9793 llvm_inst.setVolatile(ptr_volatile);
...@@ -9688,7 +9802,7 @@ pub const FuncGen = struct {...@@ -9688,7 +9802,7 @@ pub const FuncGen = struct {
9688 const elem_bits = @intCast(c_uint, ptr_ty.childType(mod).bitSize(mod));9802 const elem_bits = @intCast(c_uint, ptr_ty.childType(mod).bitSize(mod));
9689 const shift_amt = containing_int.typeOf().constInt(info.packed_offset.bit_offset, .False);9803 const shift_amt = containing_int.typeOf().constInt(info.packed_offset.bit_offset, .False);
9690 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");9804 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
9693 if (isByRef(elem_ty, mod)) {9807 if (isByRef(elem_ty, mod)) {
9694 const result_align = elem_ty.abiAlignment(mod);9808 const result_align = elem_ty.abiAlignment(mod);
...@@ -9723,7 +9837,8 @@ pub const FuncGen = struct {...@@ -9723,7 +9837,8 @@ pub const FuncGen = struct {
9723 elem: *llvm.Value,9837 elem: *llvm.Value,
9724 ordering: llvm.AtomicOrdering,9838 ordering: llvm.AtomicOrdering,
9725 ) !void {9839 ) !void {
9726 const mod = self.dg.module;9840 const o = self.dg.object;
9841 const mod = o.module;
9727 const info = ptr_ty.ptrInfo(mod);9842 const info = ptr_ty.ptrInfo(mod);
9728 const elem_ty = info.child.toType();9843 const elem_ty = info.child.toType();
9729 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {9844 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
...@@ -9735,7 +9850,7 @@ pub const FuncGen = struct {...@@ -9735,7 +9850,7 @@ pub const FuncGen = struct {
9735 assert(info.flags.vector_index != .runtime);9850 assert(info.flags.vector_index != .runtime);
9736 if (info.flags.vector_index != .none) {9851 if (info.flags.vector_index != .none) {
9737 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False);9852 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);
9739 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);9854 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);
97409855
9741 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");9856 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");
...@@ -9805,7 +9920,8 @@ pub const FuncGen = struct {...@@ -9805,7 +9920,8 @@ pub const FuncGen = struct {
98059920
9806 fn valgrindMarkUndef(fg: *FuncGen, ptr: *llvm.Value, len: *llvm.Value) void {9921 fn valgrindMarkUndef(fg: *FuncGen, ptr: *llvm.Value, len: *llvm.Value) void {
9807 const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545;9922 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();
9809 const usize_llvm_ty = fg.context.intType(target.ptrBitWidth());9925 const usize_llvm_ty = fg.context.intType(target.ptrBitWidth());
9810 const zero = usize_llvm_ty.constInt(0, .False);9926 const zero = usize_llvm_ty.constInt(0, .False);
9811 const req = usize_llvm_ty.constInt(VG_USERREQ__MAKE_MEM_UNDEFINED, .False);9927 const req = usize_llvm_ty.constInt(VG_USERREQ__MAKE_MEM_UNDEFINED, .False);
...@@ -9823,7 +9939,8 @@ pub const FuncGen = struct {...@@ -9823,7 +9939,8 @@ pub const FuncGen = struct {
9823 a4: *llvm.Value,9939 a4: *llvm.Value,
9824 a5: *llvm.Value,9940 a5: *llvm.Value,
9825 ) *llvm.Value {9941 ) *llvm.Value {
9826 const mod = fg.dg.module;9942 const o = fg.dg.object;
9943 const mod = o.module;
9827 const target = mod.getTarget();9944 const target = mod.getTarget();
9828 if (!target_util.hasValgrindSupport(target)) return default_value;9945 if (!target_util.hasValgrindSupport(target)) return default_value;
98299946
...@@ -9907,12 +10024,14 @@ pub const FuncGen = struct {...@@ -9907,12 +10024,14 @@ pub const FuncGen = struct {
9907 }10024 }
990810025
9909 fn typeOf(fg: *FuncGen, inst: Air.Inst.Ref) Type {10026 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;
9911 return fg.air.typeOf(inst, &mod.intern_pool);10029 return fg.air.typeOf(inst, &mod.intern_pool);
9912 }10030 }
991310031
9914 fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type {10032 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;
9916 return fg.air.typeOfIndex(inst, &mod.intern_pool);10035 return fg.air.typeOfIndex(inst, &mod.intern_pool);
9917 }10036 }
9918};10037};
...@@ -10370,160 +10489,160 @@ fn firstParamSRetSystemV(ty: Type, mod: *Module) bool {...@@ -10370,160 +10489,160 @@ fn firstParamSRetSystemV(ty: Type, mod: *Module) bool {
10370/// In order to support the C calling convention, some return types need to be lowered10489/// In order to support the C calling convention, some return types need to be lowered
10371/// completely differently in the function prototype to honor the C ABI, and then10490/// completely differently in the function prototype to honor the C ABI, and then
10372/// be effectively bitcasted to the actual return type.10491/// be effectively bitcasted to the actual return type.
10373fn lowerFnRetTy(dg: *DeclGen, fn_info: InternPool.Key.FuncType) !*llvm.Type {10492fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type {
10374 const mod = dg.module;10493 const mod = o.module;
10375 const return_type = fn_info.return_type.toType();10494 const return_type = fn_info.return_type.toType();
10376 if (!return_type.hasRuntimeBitsIgnoreComptime(mod)) {10495 if (!return_type.hasRuntimeBitsIgnoreComptime(mod)) {
10377 // If the return type is an error set or an error union, then we make this10496 // If the return type is an error set or an error union, then we make this
10378 // anyerror return type instead, so that it can be coerced into a function10497 // anyerror return type instead, so that it can be coerced into a function
10379 // pointer type which has anyerror as the return type.10498 // pointer type which has anyerror as the return type.
10380 if (return_type.isError(mod)) {10499 if (return_type.isError(mod)) {
10381 return dg.lowerType(Type.anyerror);10500 return o.lowerType(Type.anyerror);
10382 } else {10501 } else {
10383 return dg.context.voidType();10502 return o.context.voidType();
10384 }10503 }
10385 }10504 }
10386 const target = mod.getTarget();10505 const target = mod.getTarget();
10387 switch (fn_info.cc) {10506 switch (fn_info.cc) {
10388 .Unspecified, .Inline => {10507 .Unspecified, .Inline => {
10389 if (isByRef(return_type, mod)) {10508 if (isByRef(return_type, mod)) {
10390 return dg.context.voidType();10509 return o.context.voidType();
10391 } else {10510 } else {
10392 return dg.lowerType(return_type);10511 return o.lowerType(return_type);
10393 }10512 }
10394 },10513 },
10395 .C => {10514 .C => {
10396 switch (target.cpu.arch) {10515 switch (target.cpu.arch) {
10397 .mips, .mipsel => return dg.lowerType(return_type),10516 .mips, .mipsel => return o.lowerType(return_type),
10398 .x86_64 => switch (target.os.tag) {10517 .x86_64 => switch (target.os.tag) {
10399 .windows => return lowerWin64FnRetTy(dg, fn_info),10518 .windows => return lowerWin64FnRetTy(o, fn_info),
10400 else => return lowerSystemVFnRetTy(dg, fn_info),10519 else => return lowerSystemVFnRetTy(o, fn_info),
10401 },10520 },
10402 .wasm32 => {10521 .wasm32 => {
10403 if (isScalar(mod, return_type)) {10522 if (isScalar(mod, return_type)) {
10404 return dg.lowerType(return_type);10523 return o.lowerType(return_type);
10405 }10524 }
10406 const classes = wasm_c_abi.classifyType(return_type, mod);10525 const classes = wasm_c_abi.classifyType(return_type, mod);
10407 if (classes[0] == .indirect or classes[0] == .none) {10526 if (classes[0] == .indirect or classes[0] == .none) {
10408 return dg.context.voidType();10527 return o.context.voidType();
10409 }10528 }
1041010529
10411 assert(classes[0] == .direct and classes[1] == .none);10530 assert(classes[0] == .direct and classes[1] == .none);
10412 const scalar_type = wasm_c_abi.scalarType(return_type, mod);10531 const scalar_type = wasm_c_abi.scalarType(return_type, mod);
10413 const abi_size = scalar_type.abiSize(mod);10532 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));
10415 },10534 },
10416 .aarch64, .aarch64_be => {10535 .aarch64, .aarch64_be => {
10417 switch (aarch64_c_abi.classifyType(return_type, mod)) {10536 switch (aarch64_c_abi.classifyType(return_type, mod)) {
10418 .memory => return dg.context.voidType(),10537 .memory => return o.context.voidType(),
10419 .float_array => return dg.lowerType(return_type),10538 .float_array => return o.lowerType(return_type),
10420 .byval => return dg.lowerType(return_type),10539 .byval => return o.lowerType(return_type),
10421 .integer => {10540 .integer => {
10422 const bit_size = return_type.bitSize(mod);10541 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));
10424 },10543 },
10425 .double_integer => return dg.context.intType(64).arrayType(2),10544 .double_integer => return o.context.intType(64).arrayType(2),
10426 }10545 }
10427 },10546 },
10428 .arm, .armeb => {10547 .arm, .armeb => {
10429 switch (arm_c_abi.classifyType(return_type, mod, .ret)) {10548 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(),
10431 .i32_array => |len| if (len == 1) {10550 .i32_array => |len| if (len == 1) {
10432 return dg.context.intType(32);10551 return o.context.intType(32);
10433 } else {10552 } else {
10434 return dg.context.voidType();10553 return o.context.voidType();
10435 },10554 },
10436 .byval => return dg.lowerType(return_type),10555 .byval => return o.lowerType(return_type),
10437 }10556 }
10438 },10557 },
10439 .riscv32, .riscv64 => {10558 .riscv32, .riscv64 => {
10440 switch (riscv_c_abi.classifyType(return_type, mod)) {10559 switch (riscv_c_abi.classifyType(return_type, mod)) {
10441 .memory => return dg.context.voidType(),10560 .memory => return o.context.voidType(),
10442 .integer => {10561 .integer => {
10443 const bit_size = return_type.bitSize(mod);10562 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));
10445 },10564 },
10446 .double_integer => {10565 .double_integer => {
10447 var llvm_types_buffer: [2]*llvm.Type = .{10566 var llvm_types_buffer: [2]*llvm.Type = .{
10448 dg.context.intType(64),10567 o.context.intType(64),
10449 dg.context.intType(64),10568 o.context.intType(64),
10450 };10569 };
10451 return dg.context.structType(&llvm_types_buffer, 2, .False);10570 return o.context.structType(&llvm_types_buffer, 2, .False);
10452 },10571 },
10453 .byval => return dg.lowerType(return_type),10572 .byval => return o.lowerType(return_type),
10454 }10573 }
10455 },10574 },
10456 // TODO investigate C ABI for other architectures10575 // TODO investigate C ABI for other architectures
10457 else => return dg.lowerType(return_type),10576 else => return o.lowerType(return_type),
10458 }10577 }
10459 },10578 },
10460 .Win64 => return lowerWin64FnRetTy(dg, fn_info),10579 .Win64 => return lowerWin64FnRetTy(o, fn_info),
10461 .SysV => return lowerSystemVFnRetTy(dg, fn_info),10580 .SysV => return lowerSystemVFnRetTy(o, fn_info),
10462 .Stdcall => {10581 .Stdcall => {
10463 if (isScalar(mod, return_type)) {10582 if (isScalar(mod, return_type)) {
10464 return dg.lowerType(return_type);10583 return o.lowerType(return_type);
10465 } else {10584 } else {
10466 return dg.context.voidType();10585 return o.context.voidType();
10467 }10586 }
10468 },10587 },
10469 else => return dg.lowerType(return_type),10588 else => return o.lowerType(return_type),
10470 }10589 }
10471}10590}
1047210591
10473fn lowerWin64FnRetTy(dg: *DeclGen, fn_info: InternPool.Key.FuncType) !*llvm.Type {10592fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type {
10474 const mod = dg.module;10593 const mod = o.module;
10475 const return_type = fn_info.return_type.toType();10594 const return_type = fn_info.return_type.toType();
10476 switch (x86_64_abi.classifyWindows(return_type, mod)) {10595 switch (x86_64_abi.classifyWindows(return_type, mod)) {
10477 .integer => {10596 .integer => {
10478 if (isScalar(mod, return_type)) {10597 if (isScalar(mod, return_type)) {
10479 return dg.lowerType(return_type);10598 return o.lowerType(return_type);
10480 } else {10599 } else {
10481 const abi_size = return_type.abiSize(mod);10600 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));
10483 }10602 }
10484 },10603 },
10485 .win_i128 => return dg.context.intType(64).vectorType(2),10604 .win_i128 => return o.context.intType(64).vectorType(2),
10486 .memory => return dg.context.voidType(),10605 .memory => return o.context.voidType(),
10487 .sse => return dg.lowerType(return_type),10606 .sse => return o.lowerType(return_type),
10488 else => unreachable,10607 else => unreachable,
10489 }10608 }
10490}10609}
1049110610
10492fn lowerSystemVFnRetTy(dg: *DeclGen, fn_info: InternPool.Key.FuncType) !*llvm.Type {10611fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type {
10493 const mod = dg.module;10612 const mod = o.module;
10494 const return_type = fn_info.return_type.toType();10613 const return_type = fn_info.return_type.toType();
10495 if (isScalar(mod, return_type)) {10614 if (isScalar(mod, return_type)) {
10496 return dg.lowerType(return_type);10615 return o.lowerType(return_type);
10497 }10616 }
10498 const classes = x86_64_abi.classifySystemV(return_type, mod, .ret);10617 const classes = x86_64_abi.classifySystemV(return_type, mod, .ret);
10499 if (classes[0] == .memory) {10618 if (classes[0] == .memory) {
10500 return dg.context.voidType();10619 return o.context.voidType();
10501 }10620 }
10502 var llvm_types_buffer: [8]*llvm.Type = undefined;10621 var llvm_types_buffer: [8]*llvm.Type = undefined;
10503 var llvm_types_index: u32 = 0;10622 var llvm_types_index: u32 = 0;
10504 for (classes) |class| {10623 for (classes) |class| {
10505 switch (class) {10624 switch (class) {
10506 .integer => {10625 .integer => {
10507 llvm_types_buffer[llvm_types_index] = dg.context.intType(64);10626 llvm_types_buffer[llvm_types_index] = o.context.intType(64);
10508 llvm_types_index += 1;10627 llvm_types_index += 1;
10509 },10628 },
10510 .sse, .sseup => {10629 .sse, .sseup => {
10511 llvm_types_buffer[llvm_types_index] = dg.context.doubleType();10630 llvm_types_buffer[llvm_types_index] = o.context.doubleType();
10512 llvm_types_index += 1;10631 llvm_types_index += 1;
10513 },10632 },
10514 .float => {10633 .float => {
10515 llvm_types_buffer[llvm_types_index] = dg.context.floatType();10634 llvm_types_buffer[llvm_types_index] = o.context.floatType();
10516 llvm_types_index += 1;10635 llvm_types_index += 1;
10517 },10636 },
10518 .float_combine => {10637 .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);
10520 llvm_types_index += 1;10639 llvm_types_index += 1;
10521 },10640 },
10522 .x87 => {10641 .x87 => {
10523 if (llvm_types_index != 0 or classes[2] != .none) {10642 if (llvm_types_index != 0 or classes[2] != .none) {
10524 return dg.context.voidType();10643 return o.context.voidType();
10525 }10644 }
10526 llvm_types_buffer[llvm_types_index] = dg.context.x86FP80Type();10645 llvm_types_buffer[llvm_types_index] = o.context.x86FP80Type();
10527 llvm_types_index += 1;10646 llvm_types_index += 1;
10528 },10647 },
10529 .x87up => continue,10648 .x87up => continue,
...@@ -10537,13 +10656,13 @@ fn lowerSystemVFnRetTy(dg: *DeclGen, fn_info: InternPool.Key.FuncType) !*llvm.Ty...@@ -10537,13 +10656,13 @@ fn lowerSystemVFnRetTy(dg: *DeclGen, fn_info: InternPool.Key.FuncType) !*llvm.Ty
10537 }10656 }
10538 if (classes[0] == .integer and classes[1] == .none) {10657 if (classes[0] == .integer and classes[1] == .none) {
10539 const abi_size = return_type.abiSize(mod);10658 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));
10541 }10660 }
10542 return dg.context.structType(&llvm_types_buffer, llvm_types_index, .False);10661 return o.context.structType(&llvm_types_buffer, llvm_types_index, .False);
10543}10662}
1054410663
10545const ParamTypeIterator = struct {10664const ParamTypeIterator = struct {
10546 dg: *DeclGen,10665 object: *Object,
10547 fn_info: InternPool.Key.FuncType,10666 fn_info: InternPool.Key.FuncType,
10548 zig_index: u32,10667 zig_index: u32,
10549 llvm_index: u32,10668 llvm_index: u32,
...@@ -10586,7 +10705,7 @@ const ParamTypeIterator = struct {...@@ -10586,7 +10705,7 @@ const ParamTypeIterator = struct {
10586 }10705 }
1058710706
10588 fn nextInner(it: *ParamTypeIterator, ty: Type) ?Lowering {10707 fn nextInner(it: *ParamTypeIterator, ty: Type) ?Lowering {
10589 const mod = it.dg.module;10708 const mod = it.object.module;
10590 const target = mod.getTarget();10709 const target = mod.getTarget();
1059110710
10592 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) {10711 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -10641,7 +10760,7 @@ const ParamTypeIterator = struct {...@@ -10641,7 +10760,7 @@ const ParamTypeIterator = struct {
10641 .byval => return .byval,10760 .byval => return .byval,
10642 .integer => {10761 .integer => {
10643 it.llvm_types_len = 1;10762 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);
10645 return .multiple_llvm_types;10764 return .multiple_llvm_types;
10646 },10765 },
10647 .double_integer => return Lowering{ .i64_array = 2 },10766 .double_integer => return Lowering{ .i64_array = 2 },
...@@ -10703,7 +10822,7 @@ const ParamTypeIterator = struct {...@@ -10703,7 +10822,7 @@ const ParamTypeIterator = struct {
10703 }10822 }
1070410823
10705 fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering {10824 fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering {
10706 const mod = it.dg.module;10825 const mod = it.object.module;
10707 switch (x86_64_abi.classifyWindows(ty, mod)) {10826 switch (x86_64_abi.classifyWindows(ty, mod)) {
10708 .integer => {10827 .integer => {
10709 if (isScalar(mod, ty)) {10828 if (isScalar(mod, ty)) {
...@@ -10736,7 +10855,7 @@ const ParamTypeIterator = struct {...@@ -10736,7 +10855,7 @@ const ParamTypeIterator = struct {
10736 }10855 }
1073710856
10738 fn nextSystemV(it: *ParamTypeIterator, ty: Type) ?Lowering {10857 fn nextSystemV(it: *ParamTypeIterator, ty: Type) ?Lowering {
10739 const mod = it.dg.module;10858 const mod = it.object.module;
10740 const classes = x86_64_abi.classifySystemV(ty, mod, .arg);10859 const classes = x86_64_abi.classifySystemV(ty, mod, .arg);
10741 if (classes[0] == .memory) {10860 if (classes[0] == .memory) {
10742 it.zig_index += 1;10861 it.zig_index += 1;
...@@ -10754,19 +10873,19 @@ const ParamTypeIterator = struct {...@@ -10754,19 +10873,19 @@ const ParamTypeIterator = struct {
10754 for (classes) |class| {10873 for (classes) |class| {
10755 switch (class) {10874 switch (class) {
10756 .integer => {10875 .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);
10758 llvm_types_index += 1;10877 llvm_types_index += 1;
10759 },10878 },
10760 .sse, .sseup => {10879 .sse, .sseup => {
10761 llvm_types_buffer[llvm_types_index] = it.dg.context.doubleType();10880 llvm_types_buffer[llvm_types_index] = it.object.context.doubleType();
10762 llvm_types_index += 1;10881 llvm_types_index += 1;
10763 },10882 },
10764 .float => {10883 .float => {
10765 llvm_types_buffer[llvm_types_index] = it.dg.context.floatType();10884 llvm_types_buffer[llvm_types_index] = it.object.context.floatType();
10766 llvm_types_index += 1;10885 llvm_types_index += 1;
10767 },10886 },
10768 .float_combine => {10887 .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);
10770 llvm_types_index += 1;10889 llvm_types_index += 1;
10771 },10890 },
10772 .x87 => {10891 .x87 => {
...@@ -10797,9 +10916,9 @@ const ParamTypeIterator = struct {...@@ -10797,9 +10916,9 @@ const ParamTypeIterator = struct {
10797 }10916 }
10798};10917};
1079910918
10800fn iterateParamTypes(dg: *DeclGen, fn_info: InternPool.Key.FuncType) ParamTypeIterator {10919fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) ParamTypeIterator {
10801 return .{10920 return .{
10802 .dg = dg,10921 .object = object,
10803 .fn_info = fn_info,10922 .fn_info = fn_info,
10804 .zig_index = 0,10923 .zig_index = 0,
10805 .llvm_index = 0,10924 .llvm_index = 0,
...@@ -11055,8 +11174,8 @@ const lt_errors_fn_name = "__zig_lt_errors_len";...@@ -11055,8 +11174,8 @@ const lt_errors_fn_name = "__zig_lt_errors_len";
1105511174
11056/// Without this workaround, LLVM crashes with "unknown codeview register H1"11175/// Without this workaround, LLVM crashes with "unknown codeview register H1"
11057/// https://github.com/llvm/llvm-project/issues/5648411176/// https://github.com/llvm/llvm-project/issues/56484
11058fn needDbgVarWorkaround(dg: *DeclGen) bool {11177fn needDbgVarWorkaround(o: *Object) bool {
11059 const target = dg.module.getTarget();11178 const target = o.module.getTarget();
11060 if (target.os.tag == .windows and target.cpu.arch == .aarch64) {11179 if (target.os.tag == .windows and target.cpu.arch == .aarch64) {
11061 return true;11180 return true;
11062 }11181 }