| ... | @@ -374,12 +374,11 @@ const DataLayoutBuilder = struct { | ... | @@ -374,12 +374,11 @@ const DataLayoutBuilder = struct { |
| 374 | .pref = 64, | 374 | .pref = 64, |
| 375 | .idx = 64, | 375 | .idx = 64, |
| 376 | }; | 376 | }; |
| 377 | const address_space_info = llvmAddressSpaceInfo(self.target); | 377 | const addr_space_info = llvmAddrSpaceInfo(self.target); |
| 378 | assert(address_space_info[0].llvm == llvm.address_space.default); | 378 | for (addr_space_info, 0..) |info, i| { |
| 379 | for (address_space_info) |info| { | 379 | assert((info.llvm == .default) == (i == 0)); |
| 380 | const is_default = info.llvm == llvm.address_space.default; | | |
| 381 | if (info.non_integral) { | 380 | if (info.non_integral) { |
| 382 | assert(!is_default); | 381 | assert(info.llvm != .default); |
| 383 | any_non_integral = true; | 382 | any_non_integral = true; |
| 384 | } | 383 | } |
| 385 | const size = info.size orelse ptr_bit_width; | 384 | const size = info.size orelse ptr_bit_width; |
| ... | @@ -391,7 +390,7 @@ const DataLayoutBuilder = struct { | ... | @@ -391,7 +390,7 @@ const DataLayoutBuilder = struct { |
| 391 | abi == default_info.abi and | 390 | abi == default_info.abi and |
| 392 | pref == default_info.pref and | 391 | pref == default_info.pref and |
| 393 | idx == default_info.idx; | 392 | idx == default_info.idx; |
| 394 | if (is_default) default_info = .{ | 393 | if (info.llvm == .default) default_info = .{ |
| 395 | .size = size, | 394 | .size = size, |
| 396 | .abi = abi, | 395 | .abi = abi, |
| 397 | .pref = pref, | 396 | .pref = pref, |
| ... | @@ -400,7 +399,7 @@ const DataLayoutBuilder = struct { | ... | @@ -400,7 +399,7 @@ const DataLayoutBuilder = struct { |
| 400 | if (!info.force_in_data_layout and matches_default and | 399 | if (!info.force_in_data_layout and matches_default and |
| 401 | self.target.cpu.arch != .riscv64 and !is_aarch64_windows) continue; | 400 | self.target.cpu.arch != .riscv64 and !is_aarch64_windows) continue; |
| 402 | try writer.writeAll("-p"); | 401 | try writer.writeAll("-p"); |
| 403 | if (!is_default) try writer.print("{d}", .{info.llvm}); | 402 | if (info.llvm != .default) try writer.print("{d}", .{@intFromEnum(info.llvm)}); |
| 404 | try writer.print(":{d}:{d}", .{ size, abi }); | 403 | try writer.print(":{d}:{d}", .{ size, abi }); |
| 405 | if (pref != abi or idx != size) { | 404 | if (pref != abi or idx != size) { |
| 406 | try writer.print(":{d}", .{pref}); | 405 | try writer.print(":{d}", .{pref}); |
| ... | @@ -459,8 +458,8 @@ const DataLayoutBuilder = struct { | ... | @@ -459,8 +458,8 @@ const DataLayoutBuilder = struct { |
| 459 | try self.typeAlignment(.vector, 512, 128, 128, true, writer); | 458 | try self.typeAlignment(.vector, 512, 128, 128, true, writer); |
| 460 | if (any_non_integral) { | 459 | if (any_non_integral) { |
| 461 | try writer.writeAll("-ni"); | 460 | try writer.writeAll("-ni"); |
| 462 | for (address_space_info) |info| if (info.non_integral) | 461 | for (addr_space_info) |info| if (info.non_integral) |
| 463 | try writer.print(":{d}", .{info.llvm}); | 462 | try writer.print(":{d}", .{@intFromEnum(info.llvm)}); |
| 464 | } | 463 | } |
| 465 | } | 464 | } |
| 466 | | 465 | |
| ... | @@ -589,7 +588,7 @@ pub const Object = struct { | ... | @@ -589,7 +588,7 @@ pub const Object = struct { |
| 589 | /// Memoizes a null `?usize` value. | 588 | /// Memoizes a null `?usize` value. |
| 590 | null_opt_addr: ?*llvm.Value, | 589 | null_opt_addr: ?*llvm.Value, |
| 591 | | 590 | |
| 592 | pub const TypeMap = std.AutoHashMapUnmanaged(InternPool.Index, *llvm.Type); | 591 | pub const TypeMap = std.AutoHashMapUnmanaged(InternPool.Index, Builder.Type); |
| 593 | | 592 | |
| 594 | /// This is an ArrayHashMap as opposed to a HashMap because in `flushModule` we | 593 | /// This is an ArrayHashMap as opposed to a HashMap because in `flushModule` we |
| 595 | /// want to iterate over it while adding entries to it. | 594 | /// want to iterate over it while adding entries to it. |
| ... | @@ -809,15 +808,10 @@ pub const Object = struct { | ... | @@ -809,15 +808,10 @@ pub const Object = struct { |
| 809 | const error_name_table_ptr_global = o.error_name_table orelse return; | 808 | const error_name_table_ptr_global = o.error_name_table orelse return; |
| 810 | | 809 | |
| 811 | const mod = o.module; | 810 | const mod = o.module; |
| 812 | const target = mod.getTarget(); | | |
| 813 | | 811 | |
| 814 | const llvm_ptr_ty = o.context.pointerType(0); // TODO: Address space | 812 | // TODO: Address space |
| 815 | const llvm_usize_ty = o.context.intType(target.ptrBitWidth()); | 813 | const llvm_usize_ty = try o.lowerType(Type.usize); |
| 816 | const type_fields = [_]*llvm.Type{ | 814 | const llvm_slice_ty = (try o.builder.structType(.normal, &.{ .ptr, llvm_usize_ty })).toLlvm(&o.builder); |
| 817 | llvm_ptr_ty, | | |
| 818 | llvm_usize_ty, | | |
| 819 | }; | | |
| 820 | const llvm_slice_ty = o.context.structType(&type_fields, type_fields.len, .False); | | |
| 821 | const slice_ty = Type.slice_const_u8_sentinel_0; | 815 | const slice_ty = Type.slice_const_u8_sentinel_0; |
| 822 | const slice_alignment = slice_ty.abiAlignment(mod); | 816 | const slice_alignment = slice_ty.abiAlignment(mod); |
| 823 | | 817 | |
| ... | @@ -838,7 +832,7 @@ pub const Object = struct { | ... | @@ -838,7 +832,7 @@ pub const Object = struct { |
| 838 | | 832 | |
| 839 | const slice_fields = [_]*llvm.Value{ | 833 | const slice_fields = [_]*llvm.Value{ |
| 840 | str_global, | 834 | str_global, |
| 841 | llvm_usize_ty.constInt(name.len, .False), | 835 | llvm_usize_ty.toLlvm(&o.builder).constInt(name.len, .False), |
| 842 | }; | 836 | }; |
| 843 | llvm_error.* = llvm_slice_ty.constNamedStruct(&slice_fields, slice_fields.len); | 837 | llvm_error.* = llvm_slice_ty.constNamedStruct(&slice_fields, slice_fields.len); |
| 844 | } | 838 | } |
| ... | @@ -1204,7 +1198,7 @@ pub const Object = struct { | ... | @@ -1204,7 +1198,7 @@ pub const Object = struct { |
| 1204 | { | 1198 | { |
| 1205 | var llvm_arg_i = @as(c_uint, @intFromBool(ret_ptr != null)) + @intFromBool(err_return_tracing); | 1199 | var llvm_arg_i = @as(c_uint, @intFromBool(ret_ptr != null)) + @intFromBool(err_return_tracing); |
| 1206 | var it = iterateParamTypes(o, fn_info); | 1200 | var it = iterateParamTypes(o, fn_info); |
| 1207 | while (it.next()) |lowering| switch (lowering) { | 1201 | while (try it.next()) |lowering| switch (lowering) { |
| 1208 | .no_bits => continue, | 1202 | .no_bits => continue, |
| 1209 | .byval => { | 1203 | .byval => { |
| 1210 | assert(!it.byval_attr); | 1204 | assert(!it.byval_attr); |
| ... | @@ -1229,7 +1223,7 @@ pub const Object = struct { | ... | @@ -1229,7 +1223,7 @@ pub const Object = struct { |
| 1229 | }, | 1223 | }, |
| 1230 | .byref => { | 1224 | .byref => { |
| 1231 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); | 1225 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); |
| 1232 | const param_llvm_ty = try o.lowerLlvmType(param_ty); | 1226 | const param_llvm_ty = try o.lowerType(param_ty); |
| 1233 | const param = llvm_func.getParam(llvm_arg_i); | 1227 | const param = llvm_func.getParam(llvm_arg_i); |
| 1234 | const alignment = param_ty.abiAlignment(mod); | 1228 | const alignment = param_ty.abiAlignment(mod); |
| 1235 | | 1229 | |
| ... | @@ -1241,14 +1235,14 @@ pub const Object = struct { | ... | @@ -1241,14 +1235,14 @@ pub const Object = struct { |
| 1241 | if (isByRef(param_ty, mod)) { | 1235 | if (isByRef(param_ty, mod)) { |
| 1242 | args.appendAssumeCapacity(param); | 1236 | args.appendAssumeCapacity(param); |
| 1243 | } else { | 1237 | } else { |
| 1244 | const load_inst = builder.buildLoad(param_llvm_ty, param, ""); | 1238 | const load_inst = builder.buildLoad(param_llvm_ty.toLlvm(&o.builder), param, ""); |
| 1245 | load_inst.setAlignment(alignment); | 1239 | load_inst.setAlignment(alignment); |
| 1246 | args.appendAssumeCapacity(load_inst); | 1240 | args.appendAssumeCapacity(load_inst); |
| 1247 | } | 1241 | } |
| 1248 | }, | 1242 | }, |
| 1249 | .byref_mut => { | 1243 | .byref_mut => { |
| 1250 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); | 1244 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); |
| 1251 | const param_llvm_ty = try o.lowerLlvmType(param_ty); | 1245 | const param_llvm_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder); |
| 1252 | const param = llvm_func.getParam(llvm_arg_i); | 1246 | const param = llvm_func.getParam(llvm_arg_i); |
| 1253 | const alignment = param_ty.abiAlignment(mod); | 1247 | const alignment = param_ty.abiAlignment(mod); |
| 1254 | | 1248 | |
| ... | @@ -1271,7 +1265,7 @@ pub const Object = struct { | ... | @@ -1271,7 +1265,7 @@ pub const Object = struct { |
| 1271 | const param = llvm_func.getParam(llvm_arg_i); | 1265 | const param = llvm_func.getParam(llvm_arg_i); |
| 1272 | llvm_arg_i += 1; | 1266 | llvm_arg_i += 1; |
| 1273 | | 1267 | |
| 1274 | const param_llvm_ty = try o.lowerLlvmType(param_ty); | 1268 | const param_llvm_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder); |
| 1275 | const abi_size = @as(c_uint, @intCast(param_ty.abiSize(mod))); | 1269 | const abi_size = @as(c_uint, @intCast(param_ty.abiSize(mod))); |
| 1276 | const int_llvm_ty = o.context.intType(abi_size * 8); | 1270 | const int_llvm_ty = o.context.intType(abi_size * 8); |
| 1277 | const alignment = @max( | 1271 | const alignment = @max( |
| ... | @@ -1316,16 +1310,16 @@ pub const Object = struct { | ... | @@ -1316,16 +1310,16 @@ pub const Object = struct { |
| 1316 | const len_param = llvm_func.getParam(llvm_arg_i); | 1310 | const len_param = llvm_func.getParam(llvm_arg_i); |
| 1317 | llvm_arg_i += 1; | 1311 | llvm_arg_i += 1; |
| 1318 | | 1312 | |
| 1319 | const slice_llvm_ty = try o.lowerLlvmType(param_ty); | 1313 | const slice_llvm_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder); |
| 1320 | const partial = builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr_param, 0, ""); | 1314 | const partial = builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr_param, 0, ""); |
| 1321 | const aggregate = builder.buildInsertValue(partial, len_param, 1, ""); | 1315 | const aggregate = builder.buildInsertValue(partial, len_param, 1, ""); |
| 1322 | try args.append(aggregate); | 1316 | try args.append(aggregate); |
| 1323 | }, | 1317 | }, |
| 1324 | .multiple_llvm_types => { | 1318 | .multiple_llvm_types => { |
| 1325 | assert(!it.byval_attr); | 1319 | assert(!it.byval_attr); |
| 1326 | const field_types = it.llvm_types_buffer[0..it.llvm_types_len]; | 1320 | const field_types = it.llvm_types_buffer[0..it.types_len]; |
| 1327 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); | 1321 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); |
| 1328 | const param_llvm_ty = try o.lowerLlvmType(param_ty); | 1322 | const param_llvm_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder); |
| 1329 | const param_alignment = param_ty.abiAlignment(mod); | 1323 | const param_alignment = param_ty.abiAlignment(mod); |
| 1330 | const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, param_alignment, target); | 1324 | const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, param_alignment, target); |
| 1331 | const llvm_ty = o.context.structType(field_types.ptr, @as(c_uint, @intCast(field_types.len)), .False); | 1325 | const llvm_ty = o.context.structType(field_types.ptr, @as(c_uint, @intCast(field_types.len)), .False); |
| ... | @@ -1356,7 +1350,7 @@ pub const Object = struct { | ... | @@ -1356,7 +1350,7 @@ pub const Object = struct { |
| 1356 | }, | 1350 | }, |
| 1357 | .float_array => { | 1351 | .float_array => { |
| 1358 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); | 1352 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); |
| 1359 | const param_llvm_ty = try o.lowerLlvmType(param_ty); | 1353 | const param_llvm_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder); |
| 1360 | const param = llvm_func.getParam(llvm_arg_i); | 1354 | const param = llvm_func.getParam(llvm_arg_i); |
| 1361 | llvm_arg_i += 1; | 1355 | llvm_arg_i += 1; |
| 1362 | | 1356 | |
| ... | @@ -1374,7 +1368,7 @@ pub const Object = struct { | ... | @@ -1374,7 +1368,7 @@ pub const Object = struct { |
| 1374 | }, | 1368 | }, |
| 1375 | .i32_array, .i64_array => { | 1369 | .i32_array, .i64_array => { |
| 1376 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); | 1370 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); |
| 1377 | const param_llvm_ty = try o.lowerLlvmType(param_ty); | 1371 | const param_llvm_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder); |
| 1378 | const param = llvm_func.getParam(llvm_arg_i); | 1372 | const param = llvm_func.getParam(llvm_arg_i); |
| 1379 | llvm_arg_i += 1; | 1373 | llvm_arg_i += 1; |
| 1380 | | 1374 | |
| ... | @@ -2678,7 +2672,7 @@ pub const Object = struct { | ... | @@ -2678,7 +2672,7 @@ pub const Object = struct { |
| 2678 | const global = o.llvm_module.addGlobalInAddressSpace( | 2672 | const global = o.llvm_module.addGlobalInAddressSpace( |
| 2679 | llvm_init.typeOf(), | 2673 | llvm_init.typeOf(), |
| 2680 | "", | 2674 | "", |
| 2681 | llvm_actual_addrspace, | 2675 | @intFromEnum(llvm_actual_addrspace), |
| 2682 | ); | 2676 | ); |
| 2683 | global.setLinkage(.Internal); | 2677 | global.setLinkage(.Internal); |
| 2684 | global.setUnnamedAddr(.True); | 2678 | global.setUnnamedAddr(.True); |
| ... | @@ -2686,7 +2680,7 @@ pub const Object = struct { | ... | @@ -2686,7 +2680,7 @@ pub const Object = struct { |
| 2686 | global.setInitializer(llvm_init); | 2680 | global.setInitializer(llvm_init); |
| 2687 | | 2681 | |
| 2688 | const addrspace_casted_global = if (llvm_wanted_addrspace != llvm_actual_addrspace) | 2682 | const addrspace_casted_global = if (llvm_wanted_addrspace != llvm_actual_addrspace) |
| 2689 | global.constAddrSpaceCast(o.context.pointerType(llvm_wanted_addrspace)) | 2683 | global.constAddrSpaceCast(o.context.pointerType(@intFromEnum(llvm_wanted_addrspace))) |
| 2690 | else | 2684 | else |
| 2691 | global; | 2685 | global; |
| 2692 | | 2686 | |
| ... | @@ -2710,16 +2704,16 @@ pub const Object = struct { | ... | @@ -2710,16 +2704,16 @@ pub const Object = struct { |
| 2710 | const target = mod.getTarget(); | 2704 | const target = mod.getTarget(); |
| 2711 | const sret = firstParamSRet(fn_info, mod); | 2705 | const sret = firstParamSRet(fn_info, mod); |
| 2712 | | 2706 | |
| 2713 | const fn_type = try o.lowerLlvmType(zig_fn_type); | 2707 | const fn_type = try o.lowerType(zig_fn_type); |
| 2714 | | 2708 | |
| 2715 | const ip = &mod.intern_pool; | 2709 | const ip = &mod.intern_pool; |
| 2716 | const fqn = try o.builder.string(ip.stringToSlice(try decl.getFullyQualifiedName(mod))); | 2710 | const fqn = try o.builder.string(ip.stringToSlice(try decl.getFullyQualifiedName(mod))); |
| 2717 | | 2711 | |
| 2718 | const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); | 2712 | const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); |
| 2719 | const llvm_fn = o.llvm_module.addFunctionInAddressSpace(fqn.toSlice(&o.builder).?, fn_type, llvm_addrspace); | 2713 | const llvm_fn = o.llvm_module.addFunctionInAddressSpace(fqn.toSlice(&o.builder).?, fn_type.toLlvm(&o.builder), @intFromEnum(llvm_addrspace)); |
| 2720 | | 2714 | |
| 2721 | var global = Builder.Global{ | 2715 | var global = Builder.Global{ |
| 2722 | .type = .void, | 2716 | .type = fn_type, |
| 2723 | .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) }, | 2717 | .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) }, |
| 2724 | }; | 2718 | }; |
| 2725 | var function = Builder.Function{ | 2719 | var function = Builder.Function{ |
| ... | @@ -2745,7 +2739,7 @@ pub const Object = struct { | ... | @@ -2745,7 +2739,7 @@ pub const Object = struct { |
| 2745 | o.addArgAttr(llvm_fn, 0, "nonnull"); // Sret pointers must not be address 0 | 2739 | o.addArgAttr(llvm_fn, 0, "nonnull"); // Sret pointers must not be address 0 |
| 2746 | o.addArgAttr(llvm_fn, 0, "noalias"); | 2740 | o.addArgAttr(llvm_fn, 0, "noalias"); |
| 2747 | | 2741 | |
| 2748 | const raw_llvm_ret_ty = try o.lowerLlvmType(fn_info.return_type.toType()); | 2742 | const raw_llvm_ret_ty = (try o.lowerType(fn_info.return_type.toType())).toLlvm(&o.builder); |
| 2749 | llvm_fn.addSretAttr(raw_llvm_ret_ty); | 2743 | llvm_fn.addSretAttr(raw_llvm_ret_ty); |
| 2750 | } | 2744 | } |
| 2751 | | 2745 | |
| ... | @@ -2789,7 +2783,7 @@ pub const Object = struct { | ... | @@ -2789,7 +2783,7 @@ pub const Object = struct { |
| 2789 | var it = iterateParamTypes(o, fn_info); | 2783 | var it = iterateParamTypes(o, fn_info); |
| 2790 | it.llvm_index += @intFromBool(sret); | 2784 | it.llvm_index += @intFromBool(sret); |
| 2791 | it.llvm_index += @intFromBool(err_return_tracing); | 2785 | it.llvm_index += @intFromBool(err_return_tracing); |
| 2792 | while (it.next()) |lowering| switch (lowering) { | 2786 | while (try it.next()) |lowering| switch (lowering) { |
| 2793 | .byval => { | 2787 | .byval => { |
| 2794 | const param_index = it.zig_index - 1; | 2788 | const param_index = it.zig_index - 1; |
| 2795 | const param_ty = fn_info.param_types.get(ip)[param_index].toType(); | 2789 | const param_ty = fn_info.param_types.get(ip)[param_index].toType(); |
| ... | @@ -2799,7 +2793,7 @@ pub const Object = struct { | ... | @@ -2799,7 +2793,7 @@ pub const Object = struct { |
| 2799 | }, | 2793 | }, |
| 2800 | .byref => { | 2794 | .byref => { |
| 2801 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1]; | 2795 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1]; |
| 2802 | const param_llvm_ty = try o.lowerLlvmType(param_ty.toType()); | 2796 | const param_llvm_ty = try o.lowerType(param_ty.toType()); |
| 2803 | const alignment = param_ty.toType().abiAlignment(mod); | 2797 | const alignment = param_ty.toType().abiAlignment(mod); |
| 2804 | o.addByRefParamAttrs(llvm_fn, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty); | 2798 | o.addByRefParamAttrs(llvm_fn, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty); |
| 2805 | }, | 2799 | }, |
| ... | @@ -2883,15 +2877,9 @@ pub const Object = struct { | ... | @@ -2883,15 +2877,9 @@ pub const Object = struct { |
| 2883 | | 2877 | |
| 2884 | const target = mod.getTarget(); | 2878 | const target = mod.getTarget(); |
| 2885 | | 2879 | |
| 2886 | const ty = try o.lowerType(decl.ty); | | |
| 2887 | const llvm_type = if (ty != .none) | | |
| 2888 | o.builder.llvm_types.items[@intFromEnum(ty)] | | |
| 2889 | else | | |
| 2890 | try o.lowerLlvmType(decl.ty); | | |
| 2891 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target); | | |
| 2892 | | | |
| 2893 | var global = Builder.Global{ | 2880 | var global = Builder.Global{ |
| 2894 | .type = if (ty != .none) ty else .void, | 2881 | .addr_space = toLlvmGlobalAddressSpace(decl.@"addrspace", target), |
| | 2882 | .type = try o.lowerType(decl.ty), |
| 2895 | .kind = .{ .object = @enumFromInt(o.builder.objects.items.len) }, | 2883 | .kind = .{ .object = @enumFromInt(o.builder.objects.items.len) }, |
| 2896 | }; | 2884 | }; |
| 2897 | var object = Builder.Object{ | 2885 | var object = Builder.Object{ |
| ... | @@ -2904,9 +2892,9 @@ pub const Object = struct { | ... | @@ -2904,9 +2892,9 @@ pub const Object = struct { |
| 2904 | else | 2892 | else |
| 2905 | fqn; | 2893 | fqn; |
| 2906 | const llvm_global = o.llvm_module.addGlobalInAddressSpace( | 2894 | const llvm_global = o.llvm_module.addGlobalInAddressSpace( |
| 2907 | llvm_type, | 2895 | global.type.toLlvm(&o.builder), |
| 2908 | fqn.toSlice(&o.builder).?, | 2896 | fqn.toSlice(&o.builder).?, |
| 2909 | llvm_actual_addrspace, | 2897 | @intFromEnum(global.addr_space), |
| 2910 | ); | 2898 | ); |
| 2911 | | 2899 | |
| 2912 | // This is needed for declarations created by `@extern`. | 2900 | // This is needed for declarations created by `@extern`. |
| ... | @@ -2943,22 +2931,19 @@ pub const Object = struct { | ... | @@ -2943,22 +2931,19 @@ pub const Object = struct { |
| 2943 | } | 2931 | } |
| 2944 | | 2932 | |
| 2945 | fn isUnnamedType(o: *Object, ty: Type, val: *llvm.Value) bool { | 2933 | fn isUnnamedType(o: *Object, ty: Type, val: *llvm.Value) bool { |
| 2946 | // Once `lowerLlvmType` succeeds, successive calls to it with the same Zig type | 2934 | // Once `lowerType` succeeds, successive calls to it with the same Zig type |
| 2947 | // are guaranteed to succeed. So if a call to `lowerLlvmType` fails here it means | 2935 | // are guaranteed to succeed. So if a call to `lowerType` fails here it means |
| 2948 | // it is the first time lowering the type, which means the value can't possible | 2936 | // it is the first time lowering the type, which means the value can't possible |
| 2949 | // have that type. | 2937 | // have that type. |
| 2950 | const llvm_ty = o.lowerLlvmType(ty) catch return true; | 2938 | const llvm_ty = (o.lowerType(ty) catch return true).toLlvm(&o.builder); |
| 2951 | return val.typeOf() != llvm_ty; | 2939 | return val.typeOf() != llvm_ty; |
| 2952 | } | 2940 | } |
| 2953 | | 2941 | |
| 2954 | fn lowerLlvmType(o: *Object, t: Type) Allocator.Error!*llvm.Type { | 2942 | fn lowerType(o: *Object, t: Type) Allocator.Error!Builder.Type { |
| 2955 | const ty = try o.lowerType(t); | 2943 | const ty = try o.lowerTypeInner(t); |
| 2956 | const llvm_ty = if (ty != .none) | | |
| 2957 | o.builder.llvm_types.items[@intFromEnum(ty)] | | |
| 2958 | else | | |
| 2959 | try o.lowerLlvmTypeInner(t); | | |
| 2960 | const mod = o.module; | 2944 | const mod = o.module; |
| 2961 | if (std.debug.runtime_safety and false) check: { | 2945 | if (std.debug.runtime_safety and false) check: { |
| | 2946 | const llvm_ty = ty.toLlvm(&o.builder); |
| 2962 | if (t.zigTypeTag(mod) == .Opaque) break :check; | 2947 | if (t.zigTypeTag(mod) == .Opaque) break :check; |
| 2963 | if (!t.hasRuntimeBits(mod)) break :check; | 2948 | if (!t.hasRuntimeBits(mod)) break :check; |
| 2964 | if (!llvm_ty.isSized().toBool()) break :check; | 2949 | if (!llvm_ty.isSized().toBool()) break :check; |
| ... | @@ -2971,445 +2956,10 @@ pub const Object = struct { | ... | @@ -2971,445 +2956,10 @@ pub const Object = struct { |
| 2971 | }); | 2956 | }); |
| 2972 | } | 2957 | } |
| 2973 | } | 2958 | } |
| 2974 | return llvm_ty; | 2959 | return ty; |
| 2975 | } | | |
| 2976 | | | |
| 2977 | fn lowerLlvmTypeInner(o: *Object, t: Type) Allocator.Error!*llvm.Type { | | |
| 2978 | const gpa = o.gpa; | | |
| 2979 | const mod = o.module; | | |
| 2980 | const target = mod.getTarget(); | | |
| 2981 | switch (t.zigTypeTag(mod)) { | | |
| 2982 | .Void, .NoReturn => return o.context.voidType(), | | |
| 2983 | .Int => { | | |
| 2984 | const info = t.intInfo(mod); | | |
| 2985 | assert(info.bits != 0); | | |
| 2986 | return o.context.intType(info.bits); | | |
| 2987 | }, | | |
| 2988 | .Enum => { | | |
| 2989 | const int_ty = t.intTagType(mod); | | |
| 2990 | const bit_count = int_ty.intInfo(mod).bits; | | |
| 2991 | assert(bit_count != 0); | | |
| 2992 | return o.context.intType(bit_count); | | |
| 2993 | }, | | |
| 2994 | .Float => switch (t.floatBits(target)) { | | |
| 2995 | 16 => return if (backendSupportsF16(target)) o.context.halfType() else o.context.intType(16), | | |
| 2996 | 32 => return o.context.floatType(), | | |
| 2997 | 64 => return o.context.doubleType(), | | |
| 2998 | 80 => return if (backendSupportsF80(target)) o.context.x86_fp80Type() else o.context.intType(80), | | |
| 2999 | 128 => return o.context.fp128Type(), | | |
| 3000 | else => unreachable, | | |
| 3001 | }, | | |
| 3002 | .Bool => return o.context.intType(1), | | |
| 3003 | .Pointer => { | | |
| 3004 | if (t.isSlice(mod)) { | | |
| 3005 | const ptr_type = t.slicePtrFieldType(mod); | | |
| 3006 | | | |
| 3007 | const fields: [2]*llvm.Type = .{ | | |
| 3008 | try o.lowerLlvmType(ptr_type), | | |
| 3009 | try o.lowerLlvmType(Type.usize), | | |
| 3010 | }; | | |
| 3011 | return o.context.structType(&fields, fields.len, .False); | | |
| 3012 | } | | |
| 3013 | const ptr_info = t.ptrInfo(mod); | | |
| 3014 | const llvm_addrspace = toLlvmAddressSpace(ptr_info.flags.address_space, target); | | |
| 3015 | return o.context.pointerType(llvm_addrspace); | | |
| 3016 | }, | | |
| 3017 | .Opaque => { | | |
| 3018 | if (t.toIntern() == .anyopaque_type) return o.context.intType(8); | | |
| 3019 | | | |
| 3020 | const gop = try o.type_map.getOrPut(gpa, t.toIntern()); | | |
| 3021 | if (gop.found_existing) return gop.value_ptr.*; | | |
| 3022 | | | |
| 3023 | const opaque_type = mod.intern_pool.indexToKey(t.toIntern()).opaque_type; | | |
| 3024 | const name = mod.intern_pool.stringToSlice(try mod.opaqueFullyQualifiedName(opaque_type)); | | |
| 3025 | | | |
| 3026 | const llvm_struct_ty = o.context.structCreateNamed(name); | | |
| 3027 | gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls | | |
| 3028 | return llvm_struct_ty; | | |
| 3029 | }, | | |
| 3030 | .Array => { | | |
| 3031 | const elem_ty = t.childType(mod); | | |
| 3032 | if (std.debug.runtime_safety) assert((try elem_ty.onePossibleValue(mod)) == null); | | |
| 3033 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); | | |
| 3034 | const total_len = t.arrayLen(mod) + @intFromBool(t.sentinel(mod) != null); | | |
| 3035 | return elem_llvm_ty.arrayType(@as(c_uint, @intCast(total_len))); | | |
| 3036 | }, | | |
| 3037 | .Vector => { | | |
| 3038 | const elem_type = try o.lowerLlvmType(t.childType(mod)); | | |
| 3039 | return elem_type.vectorType(t.vectorLen(mod)); | | |
| 3040 | }, | | |
| 3041 | .Optional => { | | |
| 3042 | const child_ty = t.optionalChild(mod); | | |
| 3043 | if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) { | | |
| 3044 | return o.context.intType(8); | | |
| 3045 | } | | |
| 3046 | const payload_llvm_ty = try o.lowerLlvmType(child_ty); | | |
| 3047 | if (t.optionalReprIsPayload(mod)) { | | |
| 3048 | return payload_llvm_ty; | | |
| 3049 | } | | |
| 3050 | | | |
| 3051 | comptime assert(optional_layout_version == 3); | | |
| 3052 | var fields_buf: [3]*llvm.Type = .{ | | |
| 3053 | payload_llvm_ty, o.context.intType(8), undefined, | | |
| 3054 | }; | | |
| 3055 | const offset = child_ty.abiSize(mod) + 1; | | |
| 3056 | const abi_size = t.abiSize(mod); | | |
| 3057 | const padding = @as(c_uint, @intCast(abi_size - offset)); | | |
| 3058 | if (padding == 0) { | | |
| 3059 | return o.context.structType(&fields_buf, 2, .False); | | |
| 3060 | } | | |
| 3061 | fields_buf[2] = o.context.intType(8).arrayType(padding); | | |
| 3062 | return o.context.structType(&fields_buf, 3, .False); | | |
| 3063 | }, | | |
| 3064 | .ErrorUnion => { | | |
| 3065 | const payload_ty = t.errorUnionPayload(mod); | | |
| 3066 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | | |
| 3067 | return try o.lowerLlvmType(Type.anyerror); | | |
| 3068 | } | | |
| 3069 | const llvm_error_type = try o.lowerLlvmType(Type.anyerror); | | |
| 3070 | const llvm_payload_type = try o.lowerLlvmType(payload_ty); | | |
| 3071 | | | |
| 3072 | const payload_align = payload_ty.abiAlignment(mod); | | |
| 3073 | const error_align = Type.anyerror.abiAlignment(mod); | | |
| 3074 | | | |
| 3075 | const payload_size = payload_ty.abiSize(mod); | | |
| 3076 | const error_size = Type.anyerror.abiSize(mod); | | |
| 3077 | | | |
| 3078 | var fields_buf: [3]*llvm.Type = undefined; | | |
| 3079 | if (error_align > payload_align) { | | |
| 3080 | fields_buf[0] = llvm_error_type; | | |
| 3081 | fields_buf[1] = llvm_payload_type; | | |
| 3082 | const payload_end = | | |
| 3083 | std.mem.alignForward(u64, error_size, payload_align) + | | |
| 3084 | payload_size; | | |
| 3085 | const abi_size = std.mem.alignForward(u64, payload_end, error_align); | | |
| 3086 | const padding = @as(c_uint, @intCast(abi_size - payload_end)); | | |
| 3087 | if (padding == 0) { | | |
| 3088 | return o.context.structType(&fields_buf, 2, .False); | | |
| 3089 | } | | |
| 3090 | fields_buf[2] = o.context.intType(8).arrayType(padding); | | |
| 3091 | return o.context.structType(&fields_buf, 3, .False); | | |
| 3092 | } else { | | |
| 3093 | fields_buf[0] = llvm_payload_type; | | |
| 3094 | fields_buf[1] = llvm_error_type; | | |
| 3095 | const error_end = | | |
| 3096 | std.mem.alignForward(u64, payload_size, error_align) + | | |
| 3097 | error_size; | | |
| 3098 | const abi_size = std.mem.alignForward(u64, error_end, payload_align); | | |
| 3099 | const padding = @as(c_uint, @intCast(abi_size - error_end)); | | |
| 3100 | if (padding == 0) { | | |
| 3101 | return o.context.structType(&fields_buf, 2, .False); | | |
| 3102 | } | | |
| 3103 | fields_buf[2] = o.context.intType(8).arrayType(padding); | | |
| 3104 | return o.context.structType(&fields_buf, 3, .False); | | |
| 3105 | } | | |
| 3106 | }, | | |
| 3107 | .ErrorSet => return o.context.intType(16), | | |
| 3108 | .Struct => { | | |
| 3109 | const gop = try o.type_map.getOrPut(gpa, t.toIntern()); | | |
| 3110 | if (gop.found_existing) return gop.value_ptr.*; | | |
| 3111 | | | |
| 3112 | const struct_type = switch (mod.intern_pool.indexToKey(t.toIntern())) { | | |
| 3113 | .anon_struct_type => |tuple| { | | |
| 3114 | const llvm_struct_ty = o.context.structCreateNamed(""); | | |
| 3115 | gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls | | |
| 3116 | | | |
| 3117 | var llvm_field_types: std.ArrayListUnmanaged(*llvm.Type) = .{}; | | |
| 3118 | defer llvm_field_types.deinit(gpa); | | |
| 3119 | | | |
| 3120 | try llvm_field_types.ensureUnusedCapacity(gpa, tuple.types.len); | | |
| 3121 | | | |
| 3122 | comptime assert(struct_layout_version == 2); | | |
| 3123 | var offset: u64 = 0; | | |
| 3124 | var big_align: u32 = 0; | | |
| 3125 | | | |
| 3126 | for (tuple.types, tuple.values) |field_ty, field_val| { | | |
| 3127 | if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue; | | |
| 3128 | | | |
| 3129 | const field_align = field_ty.toType().abiAlignment(mod); | | |
| 3130 | big_align = @max(big_align, field_align); | | |
| 3131 | const prev_offset = offset; | | |
| 3132 | offset = std.mem.alignForward(u64, offset, field_align); | | |
| 3133 | | | |
| 3134 | const padding_len = offset - prev_offset; | | |
| 3135 | if (padding_len > 0) { | | |
| 3136 | const llvm_array_ty = o.context.intType(8).arrayType(@as(c_uint, @intCast(padding_len))); | | |
| 3137 | try llvm_field_types.append(gpa, llvm_array_ty); | | |
| 3138 | } | | |
| 3139 | const field_llvm_ty = try o.lowerLlvmType(field_ty.toType()); | | |
| 3140 | try llvm_field_types.append(gpa, field_llvm_ty); | | |
| 3141 | | | |
| 3142 | offset += field_ty.toType().abiSize(mod); | | |
| 3143 | } | | |
| 3144 | { | | |
| 3145 | const prev_offset = offset; | | |
| 3146 | offset = std.mem.alignForward(u64, offset, big_align); | | |
| 3147 | const padding_len = offset - prev_offset; | | |
| 3148 | if (padding_len > 0) { | | |
| 3149 | const llvm_array_ty = o.context.intType(8).arrayType(@as(c_uint, @intCast(padding_len))); | | |
| 3150 | try llvm_field_types.append(gpa, llvm_array_ty); | | |
| 3151 | } | | |
| 3152 | } | | |
| 3153 | | | |
| 3154 | llvm_struct_ty.structSetBody( | | |
| 3155 | llvm_field_types.items.ptr, | | |
| 3156 | @as(c_uint, @intCast(llvm_field_types.items.len)), | | |
| 3157 | .False, | | |
| 3158 | ); | | |
| 3159 | | | |
| 3160 | return llvm_struct_ty; | | |
| 3161 | }, | | |
| 3162 | .struct_type => |struct_type| struct_type, | | |
| 3163 | else => unreachable, | | |
| 3164 | }; | | |
| 3165 | | | |
| 3166 | const struct_obj = mod.structPtrUnwrap(struct_type.index).?; | | |
| 3167 | | | |
| 3168 | if (struct_obj.layout == .Packed) { | | |
| 3169 | assert(struct_obj.haveLayout()); | | |
| 3170 | const int_llvm_ty = try o.lowerLlvmType(struct_obj.backing_int_ty); | | |
| 3171 | gop.value_ptr.* = int_llvm_ty; | | |
| 3172 | return int_llvm_ty; | | |
| 3173 | } | | |
| 3174 | | | |
| 3175 | const name = try o.builder.string(mod.intern_pool.stringToSlice( | | |
| 3176 | try struct_obj.getFullyQualifiedName(mod), | | |
| 3177 | )); | | |
| 3178 | const ty = try o.builder.opaqueType(name); | | |
| 3179 | | | |
| 3180 | const llvm_struct_ty = o.builder.llvm_types.items[@intFromEnum(ty)]; | | |
| 3181 | gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls | | |
| 3182 | | | |
| 3183 | assert(struct_obj.haveFieldTypes()); | | |
| 3184 | | | |
| 3185 | var llvm_field_types: std.ArrayListUnmanaged(*llvm.Type) = .{}; | | |
| 3186 | defer llvm_field_types.deinit(gpa); | | |
| 3187 | | | |
| 3188 | try llvm_field_types.ensureUnusedCapacity(gpa, struct_obj.fields.count()); | | |
| 3189 | | | |
| 3190 | comptime assert(struct_layout_version == 2); | | |
| 3191 | var offset: u64 = 0; | | |
| 3192 | var big_align: u32 = 1; | | |
| 3193 | var any_underaligned_fields = false; | | |
| 3194 | | | |
| 3195 | var it = struct_obj.runtimeFieldIterator(mod); | | |
| 3196 | while (it.next()) |field_and_index| { | | |
| 3197 | const field = field_and_index.field; | | |
| 3198 | const field_align = field.alignment(mod, struct_obj.layout); | | |
| 3199 | const field_ty_align = field.ty.abiAlignment(mod); | | |
| 3200 | any_underaligned_fields = any_underaligned_fields or | | |
| 3201 | field_align < field_ty_align; | | |
| 3202 | big_align = @max(big_align, field_align); | | |
| 3203 | const prev_offset = offset; | | |
| 3204 | offset = std.mem.alignForward(u64, offset, field_align); | | |
| 3205 | | | |
| 3206 | const padding_len = offset - prev_offset; | | |
| 3207 | if (padding_len > 0) { | | |
| 3208 | const llvm_array_ty = o.context.intType(8).arrayType(@as(c_uint, @intCast(padding_len))); | | |
| 3209 | try llvm_field_types.append(gpa, llvm_array_ty); | | |
| 3210 | } | | |
| 3211 | const field_llvm_ty = try o.lowerLlvmType(field.ty); | | |
| 3212 | try llvm_field_types.append(gpa, field_llvm_ty); | | |
| 3213 | | | |
| 3214 | offset += field.ty.abiSize(mod); | | |
| 3215 | } | | |
| 3216 | { | | |
| 3217 | const prev_offset = offset; | | |
| 3218 | offset = std.mem.alignForward(u64, offset, big_align); | | |
| 3219 | const padding_len = offset - prev_offset; | | |
| 3220 | if (padding_len > 0) { | | |
| 3221 | const llvm_array_ty = o.context.intType(8).arrayType(@as(c_uint, @intCast(padding_len))); | | |
| 3222 | try llvm_field_types.append(gpa, llvm_array_ty); | | |
| 3223 | } | | |
| 3224 | } | | |
| 3225 | | | |
| 3226 | llvm_struct_ty.structSetBody( | | |
| 3227 | llvm_field_types.items.ptr, | | |
| 3228 | @as(c_uint, @intCast(llvm_field_types.items.len)), | | |
| 3229 | llvm.Bool.fromBool(any_underaligned_fields), | | |
| 3230 | ); | | |
| 3231 | | | |
| 3232 | return llvm_struct_ty; | | |
| 3233 | }, | | |
| 3234 | .Union => { | | |
| 3235 | const gop = try o.type_map.getOrPut(gpa, t.toIntern()); | | |
| 3236 | if (gop.found_existing) return gop.value_ptr.*; | | |
| 3237 | | | |
| 3238 | const layout = t.unionGetLayout(mod); | | |
| 3239 | const union_obj = mod.typeToUnion(t).?; | | |
| 3240 | | | |
| 3241 | if (union_obj.layout == .Packed) { | | |
| 3242 | const bitsize = @as(c_uint, @intCast(t.bitSize(mod))); | | |
| 3243 | const int_llvm_ty = o.context.intType(bitsize); | | |
| 3244 | gop.value_ptr.* = int_llvm_ty; | | |
| 3245 | return int_llvm_ty; | | |
| 3246 | } | | |
| 3247 | | | |
| 3248 | if (layout.payload_size == 0) { | | |
| 3249 | const enum_tag_llvm_ty = try o.lowerLlvmType(union_obj.tag_ty); | | |
| 3250 | gop.value_ptr.* = enum_tag_llvm_ty; | | |
| 3251 | return enum_tag_llvm_ty; | | |
| 3252 | } | | |
| 3253 | | | |
| 3254 | const name = mod.intern_pool.stringToSlice(try union_obj.getFullyQualifiedName(mod)); | | |
| 3255 | | | |
| 3256 | const llvm_union_ty = o.context.structCreateNamed(name); | | |
| 3257 | gop.value_ptr.* = llvm_union_ty; // must be done before any recursive calls | | |
| 3258 | | | |
| 3259 | const aligned_field = union_obj.fields.values()[layout.most_aligned_field]; | | |
| 3260 | const llvm_aligned_field_ty = try o.lowerLlvmType(aligned_field.ty); | | |
| 3261 | | | |
| 3262 | const llvm_payload_ty = t: { | | |
| 3263 | if (layout.most_aligned_field_size == layout.payload_size) { | | |
| 3264 | break :t llvm_aligned_field_ty; | | |
| 3265 | } | | |
| 3266 | const padding_len = if (layout.tag_size == 0) | | |
| 3267 | @as(c_uint, @intCast(layout.abi_size - layout.most_aligned_field_size)) | | |
| 3268 | else | | |
| 3269 | @as(c_uint, @intCast(layout.payload_size - layout.most_aligned_field_size)); | | |
| 3270 | const fields: [2]*llvm.Type = .{ | | |
| 3271 | llvm_aligned_field_ty, | | |
| 3272 | o.context.intType(8).arrayType(padding_len), | | |
| 3273 | }; | | |
| 3274 | break :t o.context.structType(&fields, fields.len, .True); | | |
| 3275 | }; | | |
| 3276 | | | |
| 3277 | if (layout.tag_size == 0) { | | |
| 3278 | var llvm_fields: [1]*llvm.Type = .{llvm_payload_ty}; | | |
| 3279 | llvm_union_ty.structSetBody(&llvm_fields, llvm_fields.len, .False); | | |
| 3280 | return llvm_union_ty; | | |
| 3281 | } | | |
| 3282 | const enum_tag_llvm_ty = try o.lowerLlvmType(union_obj.tag_ty); | | |
| 3283 | | | |
| 3284 | // Put the tag before or after the payload depending on which one's | | |
| 3285 | // alignment is greater. | | |
| 3286 | var llvm_fields: [3]*llvm.Type = undefined; | | |
| 3287 | var llvm_fields_len: c_uint = 2; | | |
| 3288 | | | |
| 3289 | if (layout.tag_align >= layout.payload_align) { | | |
| 3290 | llvm_fields = .{ enum_tag_llvm_ty, llvm_payload_ty, undefined }; | | |
| 3291 | } else { | | |
| 3292 | llvm_fields = .{ llvm_payload_ty, enum_tag_llvm_ty, undefined }; | | |
| 3293 | } | | |
| 3294 | | | |
| 3295 | // Insert padding to make the LLVM struct ABI size match the Zig union ABI size. | | |
| 3296 | if (layout.padding != 0) { | | |
| 3297 | llvm_fields[2] = o.context.intType(8).arrayType(layout.padding); | | |
| 3298 | llvm_fields_len = 3; | | |
| 3299 | } | | |
| 3300 | | | |
| 3301 | llvm_union_ty.structSetBody(&llvm_fields, llvm_fields_len, .False); | | |
| 3302 | return llvm_union_ty; | | |
| 3303 | }, | | |
| 3304 | .Fn => return lowerLlvmTypeFn(o, t), | | |
| 3305 | .ComptimeInt => unreachable, | | |
| 3306 | .ComptimeFloat => unreachable, | | |
| 3307 | .Type => unreachable, | | |
| 3308 | .Undefined => unreachable, | | |
| 3309 | .Null => unreachable, | | |
| 3310 | .EnumLiteral => unreachable, | | |
| 3311 | | | |
| 3312 | .Frame => @panic("TODO implement llvmType for Frame types"), | | |
| 3313 | .AnyFrame => @panic("TODO implement llvmType for AnyFrame types"), | | |
| 3314 | } | | |
| 3315 | } | | |
| 3316 | | | |
| 3317 | fn lowerLlvmTypeFn(o: *Object, fn_ty: Type) Allocator.Error!*llvm.Type { | | |
| 3318 | const mod = o.module; | | |
| 3319 | const ip = &mod.intern_pool; | | |
| 3320 | const fn_info = mod.typeToFunc(fn_ty).?; | | |
| 3321 | const llvm_ret_ty = try lowerFnRetTy(o, fn_info); | | |
| 3322 | | | |
| 3323 | var llvm_params = std.ArrayList(*llvm.Type).init(o.gpa); | | |
| 3324 | defer llvm_params.deinit(); | | |
| 3325 | | | |
| 3326 | if (firstParamSRet(fn_info, mod)) { | | |
| 3327 | try llvm_params.append(o.context.pointerType(0)); | | |
| 3328 | } | | |
| 3329 | | | |
| 3330 | if (fn_info.return_type.toType().isError(mod) and | | |
| 3331 | mod.comp.bin_file.options.error_return_tracing) | | |
| 3332 | { | | |
| 3333 | const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType()); | | |
| 3334 | try llvm_params.append(try o.lowerLlvmType(ptr_ty)); | | |
| 3335 | } | | |
| 3336 | | | |
| 3337 | var it = iterateParamTypes(o, fn_info); | | |
| 3338 | while (it.next()) |lowering| switch (lowering) { | | |
| 3339 | .no_bits => continue, | | |
| 3340 | .byval => { | | |
| 3341 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); | | |
| 3342 | try llvm_params.append(try o.lowerLlvmType(param_ty)); | | |
| 3343 | }, | | |
| 3344 | .byref, .byref_mut => { | | |
| 3345 | try llvm_params.append(o.context.pointerType(0)); | | |
| 3346 | }, | | |
| 3347 | .abi_sized_int => { | | |
| 3348 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); | | |
| 3349 | const abi_size = @as(c_uint, @intCast(param_ty.abiSize(mod))); | | |
| 3350 | try llvm_params.append(o.context.intType(abi_size * 8)); | | |
| 3351 | }, | | |
| 3352 | .slice => { | | |
| 3353 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); | | |
| 3354 | const ptr_ty = if (param_ty.zigTypeTag(mod) == .Optional) | | |
| 3355 | param_ty.optionalChild(mod).slicePtrFieldType(mod) | | |
| 3356 | else | | |
| 3357 | param_ty.slicePtrFieldType(mod); | | |
| 3358 | const ptr_llvm_ty = try o.lowerLlvmType(ptr_ty); | | |
| 3359 | const len_llvm_ty = try o.lowerLlvmType(Type.usize); | | |
| 3360 | | | |
| 3361 | try llvm_params.ensureUnusedCapacity(2); | | |
| 3362 | llvm_params.appendAssumeCapacity(ptr_llvm_ty); | | |
| 3363 | llvm_params.appendAssumeCapacity(len_llvm_ty); | | |
| 3364 | }, | | |
| 3365 | .multiple_llvm_types => { | | |
| 3366 | try llvm_params.appendSlice(it.llvm_types_buffer[0..it.llvm_types_len]); | | |
| 3367 | }, | | |
| 3368 | .as_u16 => { | | |
| 3369 | try llvm_params.append(o.context.intType(16)); | | |
| 3370 | }, | | |
| 3371 | .float_array => |count| { | | |
| 3372 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); | | |
| 3373 | const float_ty = try o.lowerLlvmType(aarch64_c_abi.getFloatArrayType(param_ty, mod).?); | | |
| 3374 | const field_count = @as(c_uint, @intCast(count)); | | |
| 3375 | const arr_ty = float_ty.arrayType(field_count); | | |
| 3376 | try llvm_params.append(arr_ty); | | |
| 3377 | }, | | |
| 3378 | .i32_array, .i64_array => |arr_len| { | | |
| 3379 | const elem_size: u8 = if (lowering == .i32_array) 32 else 64; | | |
| 3380 | const arr_ty = o.context.intType(elem_size).arrayType(arr_len); | | |
| 3381 | try llvm_params.append(arr_ty); | | |
| 3382 | }, | | |
| 3383 | }; | | |
| 3384 | | | |
| 3385 | return llvm.functionType( | | |
| 3386 | llvm_ret_ty, | | |
| 3387 | llvm_params.items.ptr, | | |
| 3388 | @as(c_uint, @intCast(llvm_params.items.len)), | | |
| 3389 | llvm.Bool.fromBool(fn_info.is_var_args), | | |
| 3390 | ); | | |
| 3391 | } | 2960 | } |
| 3392 | | 2961 | |
| 3393 | /// Use this instead of lowerLlvmType when you want to handle correctly the case of elem_ty | 2962 | fn lowerTypeInner(o: *Object, t: Type) Allocator.Error!Builder.Type { |
| 3394 | /// being a zero bit type, but it should still be lowered as an i8 in such case. | | |
| 3395 | /// There are other similar cases handled here as well. | | |
| 3396 | fn lowerPtrElemTy(o: *Object, elem_ty: Type) Allocator.Error!*llvm.Type { | | |
| 3397 | const mod = o.module; | | |
| 3398 | const lower_elem_ty = switch (elem_ty.zigTypeTag(mod)) { | | |
| 3399 | .Opaque => true, | | |
| 3400 | .Fn => !mod.typeToFunc(elem_ty).?.is_generic, | | |
| 3401 | .Array => elem_ty.childType(mod).hasRuntimeBitsIgnoreComptime(mod), | | |
| 3402 | else => elem_ty.hasRuntimeBitsIgnoreComptime(mod), | | |
| 3403 | }; | | |
| 3404 | const llvm_elem_ty = if (lower_elem_ty) | | |
| 3405 | try o.lowerLlvmType(elem_ty) | | |
| 3406 | else | | |
| 3407 | o.context.intType(8); | | |
| 3408 | | | |
| 3409 | return llvm_elem_ty; | | |
| 3410 | } | | |
| 3411 | | | |
| 3412 | fn lowerType(o: *Object, t: Type) Allocator.Error!Builder.Type { | | |
| 3413 | const mod = o.module; | 2963 | const mod = o.module; |
| 3414 | const target = mod.getTarget(); | 2964 | const target = mod.getTarget(); |
| 3415 | return switch (t.toIntern()) { | 2965 | return switch (t.toIntern()) { |
| ... | @@ -3459,8 +3009,11 @@ pub const Object = struct { | ... | @@ -3459,8 +3009,11 @@ pub const Object = struct { |
| 3459 | .bool_type => .i1, | 3009 | .bool_type => .i1, |
| 3460 | .void_type => .void, | 3010 | .void_type => .void, |
| 3461 | .type_type => unreachable, | 3011 | .type_type => unreachable, |
| 3462 | .anyerror_type => .i16, | 3012 | .anyerror_type => Builder.Type.err_int, |
| 3463 | .comptime_int_type, .comptime_float_type, .noreturn_type => unreachable, | 3013 | .comptime_int_type, |
| | 3014 | .comptime_float_type, |
| | 3015 | .noreturn_type, |
| | 3016 | => unreachable, |
| 3464 | .anyframe_type => @panic("TODO implement lowerType for AnyFrame types"), | 3017 | .anyframe_type => @panic("TODO implement lowerType for AnyFrame types"), |
| 3465 | .null_type, | 3018 | .null_type, |
| 3466 | .undefined_type, | 3019 | .undefined_type, |
| ... | @@ -3482,10 +3035,16 @@ pub const Object = struct { | ... | @@ -3482,10 +3035,16 @@ pub const Object = struct { |
| 3482 | .manyptr_const_u8_sentinel_0_type, | 3035 | .manyptr_const_u8_sentinel_0_type, |
| 3483 | .single_const_pointer_to_comptime_int_type, | 3036 | .single_const_pointer_to_comptime_int_type, |
| 3484 | => .ptr, | 3037 | => .ptr, |
| 3485 | .slice_const_u8_type, .slice_const_u8_sentinel_0_type => .none, | 3038 | .slice_const_u8_type, |
| | 3039 | .slice_const_u8_sentinel_0_type, |
| | 3040 | => try o.builder.structType(.normal, &.{ .ptr, try o.lowerType(Type.usize) }), |
| 3486 | .optional_noreturn_type => unreachable, | 3041 | .optional_noreturn_type => unreachable, |
| 3487 | .anyerror_void_error_union_type => .i16, | 3042 | .anyerror_void_error_union_type, |
| 3488 | .generic_poison_type, .empty_struct_type => unreachable, | 3043 | .adhoc_inferred_error_set_type, |
| | 3044 | => Builder.Type.err_int, |
| | 3045 | .generic_poison_type, |
| | 3046 | .empty_struct_type, |
| | 3047 | => unreachable, |
| 3489 | // values, not types | 3048 | // values, not types |
| 3490 | .undef, | 3049 | .undef, |
| 3491 | .zero, | 3050 | .zero, |
| ... | @@ -3511,22 +3070,265 @@ pub const Object = struct { | ... | @@ -3511,22 +3070,265 @@ pub const Object = struct { |
| 3511 | else => switch (mod.intern_pool.indexToKey(t.toIntern())) { | 3070 | else => switch (mod.intern_pool.indexToKey(t.toIntern())) { |
| 3512 | .int_type => |int_type| try o.builder.intType(int_type.bits), | 3071 | .int_type => |int_type| try o.builder.intType(int_type.bits), |
| 3513 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { | 3072 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 3514 | .One, .Many, .C => try o.builder.pointerType(@enumFromInt( | 3073 | .One, .Many, .C => try o.builder.ptrType( |
| 3515 | toLlvmAddressSpace(ptr_type.flags.address_space, target), | 3074 | toLlvmAddressSpace(ptr_type.flags.address_space, target), |
| 3516 | )), | 3075 | ), |
| 3517 | .Slice => .none, | 3076 | .Slice => try o.builder.structType(.normal, &.{ |
| | 3077 | .ptr, |
| | 3078 | try o.lowerType(Type.usize), |
| | 3079 | }), |
| | 3080 | }, |
| | 3081 | .array_type => |array_type| o.builder.arrayType( |
| | 3082 | array_type.len + @intFromBool(array_type.sentinel != .none), |
| | 3083 | try o.lowerType(array_type.child.toType()), |
| | 3084 | ), |
| | 3085 | .vector_type => |vector_type| o.builder.vectorType( |
| | 3086 | .normal, |
| | 3087 | vector_type.len, |
| | 3088 | try o.lowerType(vector_type.child.toType()), |
| | 3089 | ), |
| | 3090 | .opt_type => |child_ty| { |
| | 3091 | if (!child_ty.toType().hasRuntimeBitsIgnoreComptime(mod)) return .i8; |
| | 3092 | |
| | 3093 | const payload_ty = try o.lowerType(child_ty.toType()); |
| | 3094 | if (t.optionalReprIsPayload(mod)) return payload_ty; |
| | 3095 | |
| | 3096 | comptime assert(optional_layout_version == 3); |
| | 3097 | var fields_buf: [3]Builder.Type = .{ payload_ty, .i8, .none }; |
| | 3098 | const offset = child_ty.toType().abiSize(mod) + 1; |
| | 3099 | const abi_size = t.abiSize(mod); |
| | 3100 | const padding = abi_size - offset; |
| | 3101 | if (padding == 0) return o.builder.structType(.normal, fields_buf[0..2]); |
| | 3102 | fields_buf[2] = try o.builder.arrayType(padding, .i8); |
| | 3103 | return o.builder.structType(.normal, fields_buf[0..3]); |
| 3518 | }, | 3104 | }, |
| 3519 | .array_type, .vector_type, .opt_type => .none, | | |
| 3520 | .anyframe_type => @panic("TODO implement lowerType for AnyFrame types"), | 3105 | .anyframe_type => @panic("TODO implement lowerType for AnyFrame types"), |
| 3521 | .error_union_type => .none, | 3106 | .error_union_type => |error_union_type| { |
| | 3107 | const error_type = Builder.Type.err_int; |
| | 3108 | if (!error_union_type.payload_type.toType().hasRuntimeBitsIgnoreComptime(mod)) |
| | 3109 | return error_type; |
| | 3110 | const payload_type = try o.lowerType(error_union_type.payload_type.toType()); |
| | 3111 | |
| | 3112 | const payload_align = error_union_type.payload_type.toType().abiAlignment(mod); |
| | 3113 | const error_align = Type.err_int.abiAlignment(mod); |
| | 3114 | |
| | 3115 | const payload_size = error_union_type.payload_type.toType().abiSize(mod); |
| | 3116 | const error_size = Type.err_int.abiSize(mod); |
| | 3117 | |
| | 3118 | var fields_buf: [3]Builder.Type = undefined; |
| | 3119 | if (error_align > payload_align) { |
| | 3120 | fields_buf[0] = error_type; |
| | 3121 | fields_buf[1] = payload_type; |
| | 3122 | const payload_end = |
| | 3123 | std.mem.alignForward(u64, error_size, payload_align) + |
| | 3124 | payload_size; |
| | 3125 | const abi_size = std.mem.alignForward(u64, payload_end, error_align); |
| | 3126 | const padding = abi_size - payload_end; |
| | 3127 | if (padding == 0) return o.builder.structType(.normal, fields_buf[0..2]); |
| | 3128 | fields_buf[2] = try o.builder.arrayType(padding, .i8); |
| | 3129 | return o.builder.structType(.normal, fields_buf[0..3]); |
| | 3130 | } else { |
| | 3131 | fields_buf[0] = payload_type; |
| | 3132 | fields_buf[1] = error_type; |
| | 3133 | const error_end = |
| | 3134 | std.mem.alignForward(u64, payload_size, error_align) + |
| | 3135 | error_size; |
| | 3136 | const abi_size = std.mem.alignForward(u64, error_end, payload_align); |
| | 3137 | const padding = abi_size - error_end; |
| | 3138 | if (padding == 0) return o.builder.structType(.normal, fields_buf[0..2]); |
| | 3139 | fields_buf[2] = try o.builder.arrayType(padding, .i8); |
| | 3140 | return o.builder.structType(.normal, fields_buf[0..3]); |
| | 3141 | } |
| | 3142 | }, |
| 3522 | .simple_type => unreachable, | 3143 | .simple_type => unreachable, |
| 3523 | .struct_type, | 3144 | .struct_type => |struct_type| { |
| 3524 | .anon_struct_type, | 3145 | const gop = try o.type_map.getOrPut(o.gpa, t.toIntern()); |
| 3525 | .union_type, | 3146 | if (gop.found_existing) return gop.value_ptr.*; |
| 3526 | .opaque_type, | 3147 | |
| 3527 | => .none, | 3148 | const struct_obj = mod.structPtrUnwrap(struct_type.index).?; |
| | 3149 | if (struct_obj.layout == .Packed) { |
| | 3150 | assert(struct_obj.haveLayout()); |
| | 3151 | const int_ty = try o.lowerType(struct_obj.backing_int_ty); |
| | 3152 | gop.value_ptr.* = int_ty; |
| | 3153 | return int_ty; |
| | 3154 | } |
| | 3155 | |
| | 3156 | const name = try o.builder.string(mod.intern_pool.stringToSlice( |
| | 3157 | try struct_obj.getFullyQualifiedName(mod), |
| | 3158 | )); |
| | 3159 | const ty = try o.builder.opaqueType(name); |
| | 3160 | gop.value_ptr.* = ty; // must be done before any recursive calls |
| | 3161 | |
| | 3162 | assert(struct_obj.haveFieldTypes()); |
| | 3163 | |
| | 3164 | var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){}; |
| | 3165 | defer llvm_field_types.deinit(o.gpa); |
| | 3166 | try llvm_field_types.ensureUnusedCapacity(o.gpa, struct_obj.fields.count()); |
| | 3167 | |
| | 3168 | comptime assert(struct_layout_version == 2); |
| | 3169 | var offset: u64 = 0; |
| | 3170 | var big_align: u32 = 1; |
| | 3171 | var struct_kind: Builder.Type.Structure.Kind = .normal; |
| | 3172 | |
| | 3173 | var it = struct_obj.runtimeFieldIterator(mod); |
| | 3174 | while (it.next()) |field_and_index| { |
| | 3175 | const field = field_and_index.field; |
| | 3176 | const field_align = field.alignment(mod, struct_obj.layout); |
| | 3177 | const field_ty_align = field.ty.abiAlignment(mod); |
| | 3178 | if (field_align < field_ty_align) struct_kind = .@"packed"; |
| | 3179 | big_align = @max(big_align, field_align); |
| | 3180 | const prev_offset = offset; |
| | 3181 | offset = std.mem.alignForward(u64, offset, field_align); |
| | 3182 | |
| | 3183 | const padding_len = offset - prev_offset; |
| | 3184 | if (padding_len > 0) try llvm_field_types.append( |
| | 3185 | o.gpa, |
| | 3186 | try o.builder.arrayType(padding_len, .i8), |
| | 3187 | ); |
| | 3188 | try llvm_field_types.append(o.gpa, try o.lowerType(field.ty)); |
| | 3189 | |
| | 3190 | offset += field.ty.abiSize(mod); |
| | 3191 | } |
| | 3192 | { |
| | 3193 | const prev_offset = offset; |
| | 3194 | offset = std.mem.alignForward(u64, offset, big_align); |
| | 3195 | const padding_len = offset - prev_offset; |
| | 3196 | if (padding_len > 0) try llvm_field_types.append( |
| | 3197 | o.gpa, |
| | 3198 | try o.builder.arrayType(padding_len, .i8), |
| | 3199 | ); |
| | 3200 | } |
| | 3201 | |
| | 3202 | try o.builder.namedTypeSetBody( |
| | 3203 | ty, |
| | 3204 | try o.builder.structType(struct_kind, llvm_field_types.items), |
| | 3205 | ); |
| | 3206 | return ty; |
| | 3207 | }, |
| | 3208 | .anon_struct_type => |anon_struct_type| { |
| | 3209 | var llvm_field_types: std.ArrayListUnmanaged(Builder.Type) = .{}; |
| | 3210 | defer llvm_field_types.deinit(o.gpa); |
| | 3211 | try llvm_field_types.ensureUnusedCapacity(o.gpa, anon_struct_type.types.len); |
| | 3212 | |
| | 3213 | comptime assert(struct_layout_version == 2); |
| | 3214 | var offset: u64 = 0; |
| | 3215 | var big_align: u32 = 0; |
| | 3216 | |
| | 3217 | for (anon_struct_type.types, anon_struct_type.values) |field_ty, field_val| { |
| | 3218 | if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue; |
| | 3219 | |
| | 3220 | const field_align = field_ty.toType().abiAlignment(mod); |
| | 3221 | big_align = @max(big_align, field_align); |
| | 3222 | const prev_offset = offset; |
| | 3223 | offset = std.mem.alignForward(u64, offset, field_align); |
| | 3224 | |
| | 3225 | const padding_len = offset - prev_offset; |
| | 3226 | if (padding_len > 0) try llvm_field_types.append( |
| | 3227 | o.gpa, |
| | 3228 | try o.builder.arrayType(padding_len, .i8), |
| | 3229 | ); |
| | 3230 | try llvm_field_types.append(o.gpa, try o.lowerType(field_ty.toType())); |
| | 3231 | |
| | 3232 | offset += field_ty.toType().abiSize(mod); |
| | 3233 | } |
| | 3234 | { |
| | 3235 | const prev_offset = offset; |
| | 3236 | offset = std.mem.alignForward(u64, offset, big_align); |
| | 3237 | const padding_len = offset - prev_offset; |
| | 3238 | if (padding_len > 0) try llvm_field_types.append( |
| | 3239 | o.gpa, |
| | 3240 | try o.builder.arrayType(padding_len, .i8), |
| | 3241 | ); |
| | 3242 | } |
| | 3243 | return o.builder.structType(.normal, llvm_field_types.items); |
| | 3244 | }, |
| | 3245 | .union_type => |union_type| { |
| | 3246 | const gop = try o.type_map.getOrPut(o.gpa, t.toIntern()); |
| | 3247 | if (gop.found_existing) return gop.value_ptr.*; |
| | 3248 | |
| | 3249 | const union_obj = mod.unionPtr(union_type.index); |
| | 3250 | const layout = union_obj.getLayout(mod, union_type.hasTag()); |
| | 3251 | |
| | 3252 | if (union_obj.layout == .Packed) { |
| | 3253 | const int_ty = try o.builder.intType(@intCast(t.bitSize(mod))); |
| | 3254 | gop.value_ptr.* = int_ty; |
| | 3255 | return int_ty; |
| | 3256 | } |
| | 3257 | |
| | 3258 | if (layout.payload_size == 0) { |
| | 3259 | const enum_tag_ty = try o.lowerType(union_obj.tag_ty); |
| | 3260 | gop.value_ptr.* = enum_tag_ty; |
| | 3261 | return enum_tag_ty; |
| | 3262 | } |
| | 3263 | |
| | 3264 | const name = try o.builder.string(mod.intern_pool.stringToSlice( |
| | 3265 | try union_obj.getFullyQualifiedName(mod), |
| | 3266 | )); |
| | 3267 | const ty = try o.builder.opaqueType(name); |
| | 3268 | gop.value_ptr.* = ty; // must be done before any recursive calls |
| | 3269 | |
| | 3270 | const aligned_field = union_obj.fields.values()[layout.most_aligned_field]; |
| | 3271 | const aligned_field_ty = try o.lowerType(aligned_field.ty); |
| | 3272 | |
| | 3273 | const payload_ty = ty: { |
| | 3274 | if (layout.most_aligned_field_size == layout.payload_size) { |
| | 3275 | break :ty aligned_field_ty; |
| | 3276 | } |
| | 3277 | const padding_len = if (layout.tag_size == 0) |
| | 3278 | layout.abi_size - layout.most_aligned_field_size |
| | 3279 | else |
| | 3280 | layout.payload_size - layout.most_aligned_field_size; |
| | 3281 | break :ty try o.builder.structType(.@"packed", &.{ |
| | 3282 | aligned_field_ty, |
| | 3283 | try o.builder.arrayType(padding_len, .i8), |
| | 3284 | }); |
| | 3285 | }; |
| | 3286 | |
| | 3287 | if (layout.tag_size == 0) { |
| | 3288 | try o.builder.namedTypeSetBody( |
| | 3289 | ty, |
| | 3290 | try o.builder.structType(.normal, &.{payload_ty}), |
| | 3291 | ); |
| | 3292 | return ty; |
| | 3293 | } |
| | 3294 | const enum_tag_ty = try o.lowerType(union_obj.tag_ty); |
| | 3295 | |
| | 3296 | // Put the tag before or after the payload depending on which one's |
| | 3297 | // alignment is greater. |
| | 3298 | var llvm_fields: [3]Builder.Type = undefined; |
| | 3299 | var llvm_fields_len: usize = 2; |
| | 3300 | |
| | 3301 | if (layout.tag_align >= layout.payload_align) { |
| | 3302 | llvm_fields = .{ enum_tag_ty, payload_ty, .none }; |
| | 3303 | } else { |
| | 3304 | llvm_fields = .{ payload_ty, enum_tag_ty, .none }; |
| | 3305 | } |
| | 3306 | |
| | 3307 | // Insert padding to make the LLVM struct ABI size match the Zig union ABI size. |
| | 3308 | if (layout.padding != 0) { |
| | 3309 | llvm_fields[llvm_fields_len] = try o.builder.arrayType(layout.padding, .i8); |
| | 3310 | llvm_fields_len += 1; |
| | 3311 | } |
| | 3312 | |
| | 3313 | try o.builder.namedTypeSetBody( |
| | 3314 | ty, |
| | 3315 | try o.builder.structType(.normal, llvm_fields[0..llvm_fields_len]), |
| | 3316 | ); |
| | 3317 | return ty; |
| | 3318 | }, |
| | 3319 | .opaque_type => |opaque_type| { |
| | 3320 | const gop = try o.type_map.getOrPut(o.gpa, t.toIntern()); |
| | 3321 | if (!gop.found_existing) { |
| | 3322 | const name = try o.builder.string(mod.intern_pool.stringToSlice( |
| | 3323 | try mod.opaqueFullyQualifiedName(opaque_type), |
| | 3324 | )); |
| | 3325 | gop.value_ptr.* = try o.builder.opaqueType(name); |
| | 3326 | } |
| | 3327 | return gop.value_ptr.*; |
| | 3328 | }, |
| 3528 | .enum_type => |enum_type| try o.lowerType(enum_type.tag_ty.toType()), | 3329 | .enum_type => |enum_type| try o.lowerType(enum_type.tag_ty.toType()), |
| 3529 | .func_type, .error_set_type, .inferred_error_set_type => .none, | 3330 | .func_type => |func_type| try o.lowerTypeFn(func_type), |
| | 3331 | .error_set_type, .inferred_error_set_type => Builder.Type.err_int, |
| 3530 | // values, not types | 3332 | // values, not types |
| 3531 | .undef, | 3333 | .undef, |
| 3532 | .runtime_value, | 3334 | .runtime_value, |
| ... | @@ -3552,6 +3354,85 @@ pub const Object = struct { | ... | @@ -3552,6 +3354,85 @@ pub const Object = struct { |
| 3552 | }; | 3354 | }; |
| 3553 | } | 3355 | } |
| 3554 | | 3356 | |
| | 3357 | /// Use this instead of lowerType when you want to handle correctly the case of elem_ty |
| | 3358 | /// being a zero bit type, but it should still be lowered as an i8 in such case. |
| | 3359 | /// There are other similar cases handled here as well. |
| | 3360 | fn lowerPtrElemTy(o: *Object, elem_ty: Type) Allocator.Error!Builder.Type { |
| | 3361 | const mod = o.module; |
| | 3362 | const lower_elem_ty = switch (elem_ty.zigTypeTag(mod)) { |
| | 3363 | .Opaque => true, |
| | 3364 | .Fn => !mod.typeToFunc(elem_ty).?.is_generic, |
| | 3365 | .Array => elem_ty.childType(mod).hasRuntimeBitsIgnoreComptime(mod), |
| | 3366 | else => elem_ty.hasRuntimeBitsIgnoreComptime(mod), |
| | 3367 | }; |
| | 3368 | return if (lower_elem_ty) try o.lowerType(elem_ty) else .i8; |
| | 3369 | } |
| | 3370 | |
| | 3371 | fn lowerTypeFn(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { |
| | 3372 | const mod = o.module; |
| | 3373 | const ip = &mod.intern_pool; |
| | 3374 | const ret_ty = try lowerFnRetTy(o, fn_info); |
| | 3375 | |
| | 3376 | var llvm_params = std.ArrayListUnmanaged(Builder.Type){}; |
| | 3377 | defer llvm_params.deinit(o.gpa); |
| | 3378 | |
| | 3379 | if (firstParamSRet(fn_info, mod)) { |
| | 3380 | try llvm_params.append(o.gpa, .ptr); |
| | 3381 | } |
| | 3382 | |
| | 3383 | if (fn_info.return_type.toType().isError(mod) and |
| | 3384 | mod.comp.bin_file.options.error_return_tracing) |
| | 3385 | { |
| | 3386 | const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType()); |
| | 3387 | try llvm_params.append(o.gpa, try o.lowerType(ptr_ty)); |
| | 3388 | } |
| | 3389 | |
| | 3390 | var it = iterateParamTypes(o, fn_info); |
| | 3391 | while (try it.next()) |lowering| switch (lowering) { |
| | 3392 | .no_bits => continue, |
| | 3393 | .byval => { |
| | 3394 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); |
| | 3395 | try llvm_params.append(o.gpa, try o.lowerType(param_ty)); |
| | 3396 | }, |
| | 3397 | .byref, .byref_mut => { |
| | 3398 | try llvm_params.append(o.gpa, .ptr); |
| | 3399 | }, |
| | 3400 | .abi_sized_int => { |
| | 3401 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); |
| | 3402 | try llvm_params.append(o.gpa, try o.builder.intType( |
| | 3403 | @intCast(param_ty.abiSize(mod) * 8), |
| | 3404 | )); |
| | 3405 | }, |
| | 3406 | .slice => { |
| | 3407 | try llvm_params.appendSlice(o.gpa, &.{ .ptr, try o.lowerType(Type.usize) }); |
| | 3408 | }, |
| | 3409 | .multiple_llvm_types => { |
| | 3410 | try llvm_params.appendSlice(o.gpa, it.types_buffer[0..it.types_len]); |
| | 3411 | }, |
| | 3412 | .as_u16 => { |
| | 3413 | try llvm_params.append(o.gpa, .i16); |
| | 3414 | }, |
| | 3415 | .float_array => |count| { |
| | 3416 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); |
| | 3417 | const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(param_ty, mod).?); |
| | 3418 | try llvm_params.append(o.gpa, try o.builder.arrayType(count, float_ty)); |
| | 3419 | }, |
| | 3420 | .i32_array, .i64_array => |arr_len| { |
| | 3421 | try llvm_params.append(o.gpa, try o.builder.arrayType(arr_len, switch (lowering) { |
| | 3422 | .i32_array => .i32, |
| | 3423 | .i64_array => .i64, |
| | 3424 | else => unreachable, |
| | 3425 | })); |
| | 3426 | }, |
| | 3427 | }; |
| | 3428 | |
| | 3429 | return o.builder.fnType( |
| | 3430 | ret_ty, |
| | 3431 | llvm_params.items, |
| | 3432 | if (fn_info.is_var_args) .vararg else .normal, |
| | 3433 | ); |
| | 3434 | } |
| | 3435 | |
| 3555 | fn lowerValue(o: *Object, arg_tv: TypedValue) Error!*llvm.Value { | 3436 | fn lowerValue(o: *Object, arg_tv: TypedValue) Error!*llvm.Value { |
| 3556 | const mod = o.module; | 3437 | const mod = o.module; |
| 3557 | const gpa = o.gpa; | 3438 | const gpa = o.gpa; |
| ... | @@ -3562,8 +3443,7 @@ pub const Object = struct { | ... | @@ -3562,8 +3443,7 @@ pub const Object = struct { |
| 3562 | else => {}, | 3443 | else => {}, |
| 3563 | } | 3444 | } |
| 3564 | if (tv.val.isUndefDeep(mod)) { | 3445 | if (tv.val.isUndefDeep(mod)) { |
| 3565 | const llvm_type = try o.lowerLlvmType(tv.ty); | 3446 | return (try o.lowerType(tv.ty)).toLlvm(&o.builder).getUndef(); |
| 3566 | return llvm_type.getUndef(); | | |
| 3567 | } | 3447 | } |
| 3568 | | 3448 | |
| 3569 | switch (mod.intern_pool.indexToKey(tv.val.toIntern())) { | 3449 | switch (mod.intern_pool.indexToKey(tv.val.toIntern())) { |
| ... | @@ -3595,7 +3475,7 @@ pub const Object = struct { | ... | @@ -3595,7 +3475,7 @@ pub const Object = struct { |
| 3595 | .generic_poison, | 3475 | .generic_poison, |
| 3596 | => unreachable, // non-runtime values | 3476 | => unreachable, // non-runtime values |
| 3597 | .false, .true => { | 3477 | .false, .true => { |
| 3598 | const llvm_type = try o.lowerLlvmType(tv.ty); | 3478 | const llvm_type = (try o.lowerType(tv.ty)).toLlvm(&o.builder); |
| 3599 | return if (tv.val.toBool()) llvm_type.constAllOnes() else llvm_type.constNull(); | 3479 | return if (tv.val.toBool()) llvm_type.constAllOnes() else llvm_type.constNull(); |
| 3600 | }, | 3480 | }, |
| 3601 | }, | 3481 | }, |
| ... | @@ -3623,7 +3503,7 @@ pub const Object = struct { | ... | @@ -3623,7 +3503,7 @@ pub const Object = struct { |
| 3623 | return lowerBigInt(o, tv.ty, bigint); | 3503 | return lowerBigInt(o, tv.ty, bigint); |
| 3624 | }, | 3504 | }, |
| 3625 | .err => |err| { | 3505 | .err => |err| { |
| 3626 | const llvm_ty = try o.lowerLlvmType(Type.anyerror); | 3506 | const llvm_ty = Builder.Type.err_int.toLlvm(&o.builder); |
| 3627 | const int = try mod.getErrorValue(err.name); | 3507 | const int = try mod.getErrorValue(err.name); |
| 3628 | return llvm_ty.constInt(int, .False); | 3508 | return llvm_ty.constInt(int, .False); |
| 3629 | }, | 3509 | }, |
| ... | @@ -3659,7 +3539,7 @@ pub const Object = struct { | ... | @@ -3659,7 +3539,7 @@ pub const Object = struct { |
| 3659 | }); | 3539 | }); |
| 3660 | var fields_buf: [3]*llvm.Value = undefined; | 3540 | var fields_buf: [3]*llvm.Value = undefined; |
| 3661 | | 3541 | |
| 3662 | const llvm_ty = try o.lowerLlvmType(tv.ty); | 3542 | const llvm_ty = (try o.lowerType(tv.ty)).toLlvm(&o.builder); |
| 3663 | const llvm_field_count = llvm_ty.countStructElementTypes(); | 3543 | const llvm_field_count = llvm_ty.countStructElementTypes(); |
| 3664 | if (llvm_field_count > 2) { | 3544 | if (llvm_field_count > 2) { |
| 3665 | assert(llvm_field_count == 3); | 3545 | assert(llvm_field_count == 3); |
| ... | @@ -3703,7 +3583,7 @@ pub const Object = struct { | ... | @@ -3703,7 +3583,7 @@ pub const Object = struct { |
| 3703 | return unsigned_val; | 3583 | return unsigned_val; |
| 3704 | }, | 3584 | }, |
| 3705 | .float => { | 3585 | .float => { |
| 3706 | const llvm_ty = try o.lowerLlvmType(tv.ty); | 3586 | const llvm_ty = (try o.lowerType(tv.ty)).toLlvm(&o.builder); |
| 3707 | switch (tv.ty.floatBits(target)) { | 3587 | switch (tv.ty.floatBits(target)) { |
| 3708 | 16 => { | 3588 | 16 => { |
| 3709 | const repr = @as(u16, @bitCast(tv.val.toFloat(f16, mod))); | 3589 | const repr = @as(u16, @bitCast(tv.val.toFloat(f16, mod))); |
| ... | @@ -3788,7 +3668,7 @@ pub const Object = struct { | ... | @@ -3788,7 +3668,7 @@ pub const Object = struct { |
| 3788 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 3668 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 3789 | return non_null_bit; | 3669 | return non_null_bit; |
| 3790 | } | 3670 | } |
| 3791 | const llvm_ty = try o.lowerLlvmType(tv.ty); | 3671 | const llvm_ty = (try o.lowerType(tv.ty)).toLlvm(&o.builder); |
| 3792 | if (tv.ty.optionalReprIsPayload(mod)) return switch (opt.val) { | 3672 | if (tv.ty.optionalReprIsPayload(mod)) return switch (opt.val) { |
| 3793 | .none => llvm_ty.constNull(), | 3673 | .none => llvm_ty.constNull(), |
| 3794 | else => |payload| o.lowerValue(.{ .ty = payload_ty, .val = payload.toValue() }), | 3674 | else => |payload| o.lowerValue(.{ .ty = payload_ty, .val = payload.toValue() }), |
| ... | @@ -3834,7 +3714,7 @@ pub const Object = struct { | ... | @@ -3834,7 +3714,7 @@ pub const Object = struct { |
| 3834 | .True, | 3714 | .True, |
| 3835 | ); | 3715 | ); |
| 3836 | } else { | 3716 | } else { |
| 3837 | const llvm_elem_ty = try o.lowerLlvmType(elem_ty); | 3717 | const llvm_elem_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder); |
| 3838 | return llvm_elem_ty.constArray( | 3718 | return llvm_elem_ty.constArray( |
| 3839 | llvm_elems.ptr, | 3719 | llvm_elems.ptr, |
| 3840 | @as(c_uint, @intCast(llvm_elems.len)), | 3720 | @as(c_uint, @intCast(llvm_elems.len)), |
| ... | @@ -3869,7 +3749,7 @@ pub const Object = struct { | ... | @@ -3869,7 +3749,7 @@ pub const Object = struct { |
| 3869 | .True, | 3749 | .True, |
| 3870 | ); | 3750 | ); |
| 3871 | } else { | 3751 | } else { |
| 3872 | const llvm_elem_ty = try o.lowerLlvmType(elem_ty); | 3752 | const llvm_elem_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder); |
| 3873 | return llvm_elem_ty.constArray( | 3753 | return llvm_elem_ty.constArray( |
| 3874 | llvm_elems.ptr, | 3754 | llvm_elems.ptr, |
| 3875 | @as(c_uint, @intCast(llvm_elems.len)), | 3755 | @as(c_uint, @intCast(llvm_elems.len)), |
| ... | @@ -3956,7 +3836,7 @@ pub const Object = struct { | ... | @@ -3956,7 +3836,7 @@ pub const Object = struct { |
| 3956 | .False, | 3836 | .False, |
| 3957 | ); | 3837 | ); |
| 3958 | } else { | 3838 | } else { |
| 3959 | const llvm_struct_ty = try o.lowerLlvmType(tv.ty); | 3839 | const llvm_struct_ty = (try o.lowerType(tv.ty)).toLlvm(&o.builder); |
| 3960 | return llvm_struct_ty.constNamedStruct( | 3840 | return llvm_struct_ty.constNamedStruct( |
| 3961 | llvm_fields.items.ptr, | 3841 | llvm_fields.items.ptr, |
| 3962 | @as(c_uint, @intCast(llvm_fields.items.len)), | 3842 | @as(c_uint, @intCast(llvm_fields.items.len)), |
| ... | @@ -3965,7 +3845,7 @@ pub const Object = struct { | ... | @@ -3965,7 +3845,7 @@ pub const Object = struct { |
| 3965 | }, | 3845 | }, |
| 3966 | .struct_type => |struct_type| { | 3846 | .struct_type => |struct_type| { |
| 3967 | const struct_obj = mod.structPtrUnwrap(struct_type.index).?; | 3847 | const struct_obj = mod.structPtrUnwrap(struct_type.index).?; |
| 3968 | const llvm_struct_ty = try o.lowerLlvmType(tv.ty); | 3848 | const llvm_struct_ty = (try o.lowerType(tv.ty)).toLlvm(&o.builder); |
| 3969 | | 3849 | |
| 3970 | if (struct_obj.layout == .Packed) { | 3850 | if (struct_obj.layout == .Packed) { |
| 3971 | assert(struct_obj.haveLayout()); | 3851 | assert(struct_obj.haveLayout()); |
| ... | @@ -4062,7 +3942,7 @@ pub const Object = struct { | ... | @@ -4062,7 +3942,7 @@ pub const Object = struct { |
| 4062 | else => unreachable, | 3942 | else => unreachable, |
| 4063 | }, | 3943 | }, |
| 4064 | .un => { | 3944 | .un => { |
| 4065 | const llvm_union_ty = try o.lowerLlvmType(tv.ty); | 3945 | const llvm_union_ty = (try o.lowerType(tv.ty)).toLlvm(&o.builder); |
| 4066 | const tag_and_val: Value.Payload.Union.Data = switch (tv.val.toIntern()) { | 3946 | const tag_and_val: Value.Payload.Union.Data = switch (tv.val.toIntern()) { |
| 4067 | .none => tv.val.castTag(.@"union").?.data, | 3947 | .none => tv.val.castTag(.@"union").?.data, |
| 4068 | else => switch (mod.intern_pool.indexToKey(tv.val.toIntern())) { | 3948 | else => switch (mod.intern_pool.indexToKey(tv.val.toIntern())) { |
| ... | @@ -4232,7 +4112,7 @@ pub const Object = struct { | ... | @@ -4232,7 +4112,7 @@ pub const Object = struct { |
| 4232 | llvm_u32.constInt(0, .False), | 4112 | llvm_u32.constInt(0, .False), |
| 4233 | llvm_u32.constInt(payload_offset, .False), | 4113 | llvm_u32.constInt(payload_offset, .False), |
| 4234 | }; | 4114 | }; |
| 4235 | const eu_llvm_ty = try o.lowerLlvmType(eu_ty); | 4115 | const eu_llvm_ty = (try o.lowerType(eu_ty)).toLlvm(&o.builder); |
| 4236 | return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 4116 | return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4237 | }, | 4117 | }, |
| 4238 | .opt_payload => |opt_ptr| { | 4118 | .opt_payload => |opt_ptr| { |
| ... | @@ -4253,19 +4133,19 @@ pub const Object = struct { | ... | @@ -4253,19 +4133,19 @@ pub const Object = struct { |
| 4253 | llvm_u32.constInt(0, .False), | 4133 | llvm_u32.constInt(0, .False), |
| 4254 | llvm_u32.constInt(0, .False), | 4134 | llvm_u32.constInt(0, .False), |
| 4255 | }; | 4135 | }; |
| 4256 | const opt_llvm_ty = try o.lowerLlvmType(opt_ty); | 4136 | const opt_llvm_ty = (try o.lowerType(opt_ty)).toLlvm(&o.builder); |
| 4257 | return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 4137 | return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4258 | }, | 4138 | }, |
| 4259 | .comptime_field => unreachable, | 4139 | .comptime_field => unreachable, |
| 4260 | .elem => |elem_ptr| { | 4140 | .elem => |elem_ptr| { |
| 4261 | const parent_llvm_ptr = try o.lowerParentPtr(elem_ptr.base.toValue(), true); | 4141 | const parent_llvm_ptr = try o.lowerParentPtr(elem_ptr.base.toValue(), true); |
| 4262 | | 4142 | |
| 4263 | const llvm_usize = try o.lowerLlvmType(Type.usize); | 4143 | const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder); |
| 4264 | const indices: [1]*llvm.Value = .{ | 4144 | const indices: [1]*llvm.Value = .{ |
| 4265 | llvm_usize.constInt(elem_ptr.index, .False), | 4145 | llvm_usize.constInt(elem_ptr.index, .False), |
| 4266 | }; | 4146 | }; |
| 4267 | const elem_ty = mod.intern_pool.typeOf(elem_ptr.base).toType().elemType2(mod); | 4147 | const elem_ty = mod.intern_pool.typeOf(elem_ptr.base).toType().elemType2(mod); |
| 4268 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); | 4148 | const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder); |
| 4269 | return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 4149 | return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4270 | }, | 4150 | }, |
| 4271 | .field => |field_ptr| { | 4151 | .field => |field_ptr| { |
| ... | @@ -4294,7 +4174,7 @@ pub const Object = struct { | ... | @@ -4294,7 +4174,7 @@ pub const Object = struct { |
| 4294 | llvm_u32.constInt(0, .False), | 4174 | llvm_u32.constInt(0, .False), |
| 4295 | llvm_u32.constInt(llvm_pl_index, .False), | 4175 | llvm_u32.constInt(llvm_pl_index, .False), |
| 4296 | }; | 4176 | }; |
| 4297 | const parent_llvm_ty = try o.lowerLlvmType(parent_ty); | 4177 | const parent_llvm_ty = (try o.lowerType(parent_ty)).toLlvm(&o.builder); |
| 4298 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 4178 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4299 | }, | 4179 | }, |
| 4300 | .Struct => { | 4180 | .Struct => { |
| ... | @@ -4317,7 +4197,7 @@ pub const Object = struct { | ... | @@ -4317,7 +4197,7 @@ pub const Object = struct { |
| 4317 | return field_addr.constIntToPtr(final_llvm_ty); | 4197 | return field_addr.constIntToPtr(final_llvm_ty); |
| 4318 | } | 4198 | } |
| 4319 | | 4199 | |
| 4320 | const parent_llvm_ty = try o.lowerLlvmType(parent_ty); | 4200 | const parent_llvm_ty = (try o.lowerType(parent_ty)).toLlvm(&o.builder); |
| 4321 | if (llvmField(parent_ty, field_index, mod)) |llvm_field| { | 4201 | if (llvmField(parent_ty, field_index, mod)) |llvm_field| { |
| 4322 | const indices: [2]*llvm.Value = .{ | 4202 | const indices: [2]*llvm.Value = .{ |
| 4323 | llvm_u32.constInt(0, .False), | 4203 | llvm_u32.constInt(0, .False), |
| ... | @@ -4336,7 +4216,7 @@ pub const Object = struct { | ... | @@ -4336,7 +4216,7 @@ pub const Object = struct { |
| 4336 | llvm_u32.constInt(0, .False), | 4216 | llvm_u32.constInt(0, .False), |
| 4337 | llvm_u32.constInt(field_index, .False), | 4217 | llvm_u32.constInt(field_index, .False), |
| 4338 | }; | 4218 | }; |
| 4339 | const parent_llvm_ty = try o.lowerLlvmType(parent_ty); | 4219 | const parent_llvm_ty = (try o.lowerType(parent_ty)).toLlvm(&o.builder); |
| 4340 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 4220 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 4341 | }, | 4221 | }, |
| 4342 | else => unreachable, | 4222 | else => unreachable, |
| ... | @@ -4386,11 +4266,11 @@ pub const Object = struct { | ... | @@ -4386,11 +4266,11 @@ pub const Object = struct { |
| 4386 | const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); | 4266 | const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); |
| 4387 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target); | 4267 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target); |
| 4388 | const llvm_val = if (llvm_wanted_addrspace != llvm_actual_addrspace) blk: { | 4268 | const llvm_val = if (llvm_wanted_addrspace != llvm_actual_addrspace) blk: { |
| 4389 | const llvm_decl_wanted_ptr_ty = o.context.pointerType(llvm_wanted_addrspace); | 4269 | const llvm_decl_wanted_ptr_ty = o.context.pointerType(@intFromEnum(llvm_wanted_addrspace)); |
| 4390 | break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty); | 4270 | break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty); |
| 4391 | } else llvm_decl_val; | 4271 | } else llvm_decl_val; |
| 4392 | | 4272 | |
| 4393 | const llvm_type = try o.lowerLlvmType(tv.ty); | 4273 | const llvm_type = (try o.lowerType(tv.ty)).toLlvm(&o.builder); |
| 4394 | if (tv.ty.zigTypeTag(mod) == .Int) { | 4274 | if (tv.ty.zigTypeTag(mod) == .Int) { |
| 4395 | return llvm_val.constPtrToInt(llvm_type); | 4275 | return llvm_val.constPtrToInt(llvm_type); |
| 4396 | } else { | 4276 | } else { |
| ... | @@ -4405,8 +4285,8 @@ pub const Object = struct { | ... | @@ -4405,8 +4285,8 @@ pub const Object = struct { |
| 4405 | // The value cannot be undefined, because we use the `nonnull` annotation | 4285 | // The value cannot be undefined, because we use the `nonnull` annotation |
| 4406 | // for non-optional pointers. We also need to respect the alignment, even though | 4286 | // for non-optional pointers. We also need to respect the alignment, even though |
| 4407 | // the address will never be dereferenced. | 4287 | // the address will never be dereferenced. |
| 4408 | const llvm_usize = try o.lowerLlvmType(Type.usize); | 4288 | const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder); |
| 4409 | const llvm_ptr_ty = try o.lowerLlvmType(ptr_ty); | 4289 | const llvm_ptr_ty = (try o.lowerType(ptr_ty)).toLlvm(&o.builder); |
| 4410 | if (ptr_ty.ptrInfo(mod).flags.alignment.toByteUnitsOptional()) |alignment| { | 4290 | if (ptr_ty.ptrInfo(mod).flags.alignment.toByteUnitsOptional()) |alignment| { |
| 4411 | return llvm_usize.constInt(alignment, .False).constIntToPtr(llvm_ptr_ty); | 4291 | return llvm_usize.constInt(alignment, .False).constIntToPtr(llvm_ptr_ty); |
| 4412 | } | 4292 | } |
| ... | @@ -4492,23 +4372,23 @@ pub const Object = struct { | ... | @@ -4492,23 +4372,23 @@ pub const Object = struct { |
| 4492 | /// widen it before using it and then truncate the result. | 4372 | /// widen it before using it and then truncate the result. |
| 4493 | /// RMW exchange of floating-point values is bitcasted to same-sized integer | 4373 | /// RMW exchange of floating-point values is bitcasted to same-sized integer |
| 4494 | /// types to work around a LLVM deficiency when targeting ARM/AArch64. | 4374 | /// types to work around a LLVM deficiency when targeting ARM/AArch64. |
| 4495 | fn getAtomicAbiType(o: *Object, ty: Type, is_rmw_xchg: bool) ?*llvm.Type { | 4375 | fn getAtomicAbiType(o: *Object, ty: Type, is_rmw_xchg: bool) Allocator.Error!Builder.Type { |
| 4496 | const mod = o.module; | 4376 | const mod = o.module; |
| 4497 | const int_ty = switch (ty.zigTypeTag(mod)) { | 4377 | const int_ty = switch (ty.zigTypeTag(mod)) { |
| 4498 | .Int => ty, | 4378 | .Int => ty, |
| 4499 | .Enum => ty.intTagType(mod), | 4379 | .Enum => ty.intTagType(mod), |
| 4500 | .Float => { | 4380 | .Float => { |
| 4501 | if (!is_rmw_xchg) return null; | 4381 | if (!is_rmw_xchg) return .none; |
| 4502 | return o.context.intType(@as(c_uint, @intCast(ty.abiSize(mod) * 8))); | 4382 | return o.builder.intType(@intCast(ty.abiSize(mod) * 8)); |
| 4503 | }, | 4383 | }, |
| 4504 | .Bool => return o.context.intType(8), | 4384 | .Bool => return .i8, |
| 4505 | else => return null, | 4385 | else => return .none, |
| 4506 | }; | 4386 | }; |
| 4507 | const bit_count = int_ty.intInfo(mod).bits; | 4387 | const bit_count = int_ty.intInfo(mod).bits; |
| 4508 | if (!std.math.isPowerOfTwo(bit_count) or (bit_count % 8) != 0) { | 4388 | if (!std.math.isPowerOfTwo(bit_count) or (bit_count % 8) != 0) { |
| 4509 | return o.context.intType(@as(c_uint, @intCast(int_ty.abiSize(mod) * 8))); | 4389 | return o.builder.intType(@intCast(int_ty.abiSize(mod) * 8)); |
| 4510 | } else { | 4390 | } else { |
| 4511 | return null; | 4391 | return .none; |
| 4512 | } | 4392 | } |
| 4513 | } | 4393 | } |
| 4514 | | 4394 | |
| ... | @@ -4549,13 +4429,13 @@ pub const Object = struct { | ... | @@ -4549,13 +4429,13 @@ pub const Object = struct { |
| 4549 | llvm_arg_i: u32, | 4429 | llvm_arg_i: u32, |
| 4550 | alignment: u32, | 4430 | alignment: u32, |
| 4551 | byval_attr: bool, | 4431 | byval_attr: bool, |
| 4552 | param_llvm_ty: *llvm.Type, | 4432 | param_llvm_ty: Builder.Type, |
| 4553 | ) void { | 4433 | ) void { |
| 4554 | o.addArgAttr(llvm_fn, llvm_arg_i, "nonnull"); | 4434 | o.addArgAttr(llvm_fn, llvm_arg_i, "nonnull"); |
| 4555 | o.addArgAttr(llvm_fn, llvm_arg_i, "readonly"); | 4435 | o.addArgAttr(llvm_fn, llvm_arg_i, "readonly"); |
| 4556 | o.addArgAttrInt(llvm_fn, llvm_arg_i, "align", alignment); | 4436 | o.addArgAttrInt(llvm_fn, llvm_arg_i, "align", alignment); |
| 4557 | if (byval_attr) { | 4437 | if (byval_attr) { |
| 4558 | llvm_fn.addByValAttr(llvm_arg_i, param_llvm_ty); | 4438 | llvm_fn.addByValAttr(llvm_arg_i, param_llvm_ty.toLlvm(&o.builder)); |
| 4559 | } | 4439 | } |
| 4560 | } | 4440 | } |
| 4561 | }; | 4441 | }; |
| ... | @@ -4626,7 +4506,7 @@ pub const DeclGen = struct { | ... | @@ -4626,7 +4506,7 @@ pub const DeclGen = struct { |
| 4626 | const new_global = o.llvm_module.addGlobalInAddressSpace( | 4506 | const new_global = o.llvm_module.addGlobalInAddressSpace( |
| 4627 | llvm_init.typeOf(), | 4507 | llvm_init.typeOf(), |
| 4628 | "", | 4508 | "", |
| 4629 | llvm_global_addrspace, | 4509 | @intFromEnum(llvm_global_addrspace), |
| 4630 | ); | 4510 | ); |
| 4631 | new_global.setLinkage(llvm_global.getLinkage()); | 4511 | new_global.setLinkage(llvm_global.getLinkage()); |
| 4632 | new_global.setUnnamedAddr(llvm_global.getUnnamedAddress()); | 4512 | new_global.setUnnamedAddr(llvm_global.getUnnamedAddress()); |
| ... | @@ -4761,14 +4641,14 @@ pub const FuncGen = struct { | ... | @@ -4761,14 +4641,14 @@ pub const FuncGen = struct { |
| 4761 | const target = mod.getTarget(); | 4641 | const target = mod.getTarget(); |
| 4762 | const llvm_wanted_addrspace = toLlvmAddressSpace(.generic, target); | 4642 | const llvm_wanted_addrspace = toLlvmAddressSpace(.generic, target); |
| 4763 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(.generic, target); | 4643 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(.generic, target); |
| 4764 | const global = o.llvm_module.addGlobalInAddressSpace(llvm_val.typeOf(), "", llvm_actual_addrspace); | 4644 | const global = o.llvm_module.addGlobalInAddressSpace(llvm_val.typeOf(), "", @intFromEnum(llvm_actual_addrspace)); |
| 4765 | global.setInitializer(llvm_val); | 4645 | global.setInitializer(llvm_val); |
| 4766 | global.setLinkage(.Private); | 4646 | global.setLinkage(.Private); |
| 4767 | global.setGlobalConstant(.True); | 4647 | global.setGlobalConstant(.True); |
| 4768 | global.setUnnamedAddr(.True); | 4648 | global.setUnnamedAddr(.True); |
| 4769 | global.setAlignment(tv.ty.abiAlignment(mod)); | 4649 | global.setAlignment(tv.ty.abiAlignment(mod)); |
| 4770 | const addrspace_casted_ptr = if (llvm_actual_addrspace != llvm_wanted_addrspace) | 4650 | const addrspace_casted_ptr = if (llvm_actual_addrspace != llvm_wanted_addrspace) |
| 4771 | global.constAddrSpaceCast(self.context.pointerType(llvm_wanted_addrspace)) | 4651 | global.constAddrSpaceCast(self.context.pointerType(@intFromEnum(llvm_wanted_addrspace))) |
| 4772 | else | 4652 | else |
| 4773 | global; | 4653 | global; |
| 4774 | return addrspace_casted_ptr; | 4654 | return addrspace_casted_ptr; |
| ... | @@ -5053,7 +4933,7 @@ pub const FuncGen = struct { | ... | @@ -5053,7 +4933,7 @@ pub const FuncGen = struct { |
| 5053 | defer llvm_args.deinit(); | 4933 | defer llvm_args.deinit(); |
| 5054 | | 4934 | |
| 5055 | const ret_ptr = if (!sret) null else blk: { | 4935 | const ret_ptr = if (!sret) null else blk: { |
| 5056 | const llvm_ret_ty = try o.lowerLlvmType(return_type); | 4936 | const llvm_ret_ty = (try o.lowerType(return_type)).toLlvm(&o.builder); |
| 5057 | const ret_ptr = self.buildAlloca(llvm_ret_ty, return_type.abiAlignment(mod)); | 4937 | const ret_ptr = self.buildAlloca(llvm_ret_ty, return_type.abiAlignment(mod)); |
| 5058 | try llvm_args.append(ret_ptr); | 4938 | try llvm_args.append(ret_ptr); |
| 5059 | break :blk ret_ptr; | 4939 | break :blk ret_ptr; |
| ... | @@ -5066,13 +4946,13 @@ pub const FuncGen = struct { | ... | @@ -5066,13 +4946,13 @@ pub const FuncGen = struct { |
| 5066 | } | 4946 | } |
| 5067 | | 4947 | |
| 5068 | var it = iterateParamTypes(o, fn_info); | 4948 | var it = iterateParamTypes(o, fn_info); |
| 5069 | while (it.nextCall(self, args)) |lowering| switch (lowering) { | 4949 | while (try it.nextCall(self, args)) |lowering| switch (lowering) { |
| 5070 | .no_bits => continue, | 4950 | .no_bits => continue, |
| 5071 | .byval => { | 4951 | .byval => { |
| 5072 | const arg = args[it.zig_index - 1]; | 4952 | const arg = args[it.zig_index - 1]; |
| 5073 | const param_ty = self.typeOf(arg); | 4953 | const param_ty = self.typeOf(arg); |
| 5074 | const llvm_arg = try self.resolveInst(arg); | 4954 | const llvm_arg = try self.resolveInst(arg); |
| 5075 | const llvm_param_ty = try o.lowerLlvmType(param_ty); | 4955 | const llvm_param_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder); |
| 5076 | if (isByRef(param_ty, mod)) { | 4956 | if (isByRef(param_ty, mod)) { |
| 5077 | const alignment = param_ty.abiAlignment(mod); | 4957 | const alignment = param_ty.abiAlignment(mod); |
| 5078 | const load_inst = self.builder.buildLoad(llvm_param_ty, llvm_arg, ""); | 4958 | const load_inst = self.builder.buildLoad(llvm_param_ty, llvm_arg, ""); |
| ... | @@ -5103,7 +4983,7 @@ pub const FuncGen = struct { | ... | @@ -5103,7 +4983,7 @@ pub const FuncGen = struct { |
| 5103 | const llvm_arg = try self.resolveInst(arg); | 4983 | const llvm_arg = try self.resolveInst(arg); |
| 5104 | | 4984 | |
| 5105 | const alignment = param_ty.abiAlignment(mod); | 4985 | const alignment = param_ty.abiAlignment(mod); |
| 5106 | const param_llvm_ty = try o.lowerLlvmType(param_ty); | 4986 | const param_llvm_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder); |
| 5107 | const arg_ptr = self.buildAlloca(param_llvm_ty, alignment); | 4987 | const arg_ptr = self.buildAlloca(param_llvm_ty, alignment); |
| 5108 | if (isByRef(param_ty, mod)) { | 4988 | if (isByRef(param_ty, mod)) { |
| 5109 | const load_inst = self.builder.buildLoad(param_llvm_ty, llvm_arg, ""); | 4989 | const load_inst = self.builder.buildLoad(param_llvm_ty, llvm_arg, ""); |
| ... | @@ -5157,7 +5037,7 @@ pub const FuncGen = struct { | ... | @@ -5157,7 +5037,7 @@ pub const FuncGen = struct { |
| 5157 | .multiple_llvm_types => { | 5037 | .multiple_llvm_types => { |
| 5158 | const arg = args[it.zig_index - 1]; | 5038 | const arg = args[it.zig_index - 1]; |
| 5159 | const param_ty = self.typeOf(arg); | 5039 | const param_ty = self.typeOf(arg); |
| 5160 | const llvm_types = it.llvm_types_buffer[0..it.llvm_types_len]; | 5040 | const llvm_types = it.llvm_types_buffer[0..it.types_len]; |
| 5161 | const llvm_arg = try self.resolveInst(arg); | 5041 | const llvm_arg = try self.resolveInst(arg); |
| 5162 | const is_by_ref = isByRef(param_ty, mod); | 5042 | const is_by_ref = isByRef(param_ty, mod); |
| 5163 | const arg_ptr = if (is_by_ref) llvm_arg else p: { | 5043 | const arg_ptr = if (is_by_ref) llvm_arg else p: { |
| ... | @@ -5168,7 +5048,7 @@ pub const FuncGen = struct { | ... | @@ -5168,7 +5048,7 @@ pub const FuncGen = struct { |
| 5168 | }; | 5048 | }; |
| 5169 | | 5049 | |
| 5170 | const llvm_ty = self.context.structType(llvm_types.ptr, @as(c_uint, @intCast(llvm_types.len)), .False); | 5050 | const llvm_ty = self.context.structType(llvm_types.ptr, @as(c_uint, @intCast(llvm_types.len)), .False); |
| 5171 | try llvm_args.ensureUnusedCapacity(it.llvm_types_len); | 5051 | try llvm_args.ensureUnusedCapacity(it.types_len); |
| 5172 | for (llvm_types, 0..) |field_ty, i_usize| { | 5052 | for (llvm_types, 0..) |field_ty, i_usize| { |
| 5173 | const i = @as(c_uint, @intCast(i_usize)); | 5053 | const i = @as(c_uint, @intCast(i_usize)); |
| 5174 | const field_ptr = self.builder.buildStructGEP(llvm_ty, arg_ptr, i, ""); | 5054 | const field_ptr = self.builder.buildStructGEP(llvm_ty, arg_ptr, i, ""); |
| ... | @@ -5194,7 +5074,7 @@ pub const FuncGen = struct { | ... | @@ -5194,7 +5074,7 @@ pub const FuncGen = struct { |
| 5194 | llvm_arg = store_inst; | 5074 | llvm_arg = store_inst; |
| 5195 | } | 5075 | } |
| 5196 | | 5076 | |
| 5197 | const float_ty = try o.lowerLlvmType(aarch64_c_abi.getFloatArrayType(arg_ty, mod).?); | 5077 | const float_ty = (try o.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty, mod).?)).toLlvm(&o.builder); |
| 5198 | const array_llvm_ty = float_ty.arrayType(count); | 5078 | const array_llvm_ty = float_ty.arrayType(count); |
| 5199 | | 5079 | |
| 5200 | const alignment = arg_ty.abiAlignment(mod); | 5080 | const alignment = arg_ty.abiAlignment(mod); |
| ... | @@ -5223,7 +5103,7 @@ pub const FuncGen = struct { | ... | @@ -5223,7 +5103,7 @@ pub const FuncGen = struct { |
| 5223 | }; | 5103 | }; |
| 5224 | | 5104 | |
| 5225 | const call = self.builder.buildCall( | 5105 | const call = self.builder.buildCall( |
| 5226 | try o.lowerLlvmType(zig_fn_ty), | 5106 | (try o.lowerType(zig_fn_ty)).toLlvm(&o.builder), |
| 5227 | llvm_fn, | 5107 | llvm_fn, |
| 5228 | llvm_args.items.ptr, | 5108 | llvm_args.items.ptr, |
| 5229 | @as(c_uint, @intCast(llvm_args.items.len)), | 5109 | @as(c_uint, @intCast(llvm_args.items.len)), |
| ... | @@ -5237,7 +5117,7 @@ pub const FuncGen = struct { | ... | @@ -5237,7 +5117,7 @@ pub const FuncGen = struct { |
| 5237 | it = iterateParamTypes(o, fn_info); | 5117 | it = iterateParamTypes(o, fn_info); |
| 5238 | it.llvm_index += @intFromBool(sret); | 5118 | it.llvm_index += @intFromBool(sret); |
| 5239 | it.llvm_index += @intFromBool(err_return_tracing); | 5119 | it.llvm_index += @intFromBool(err_return_tracing); |
| 5240 | while (it.next()) |lowering| switch (lowering) { | 5120 | while (try it.next()) |lowering| switch (lowering) { |
| 5241 | .byval => { | 5121 | .byval => { |
| 5242 | const param_index = it.zig_index - 1; | 5122 | const param_index = it.zig_index - 1; |
| 5243 | const param_ty = fn_info.param_types.get(ip)[param_index].toType(); | 5123 | const param_ty = fn_info.param_types.get(ip)[param_index].toType(); |
| ... | @@ -5248,7 +5128,7 @@ pub const FuncGen = struct { | ... | @@ -5248,7 +5128,7 @@ pub const FuncGen = struct { |
| 5248 | .byref => { | 5128 | .byref => { |
| 5249 | const param_index = it.zig_index - 1; | 5129 | const param_index = it.zig_index - 1; |
| 5250 | const param_ty = fn_info.param_types.get(ip)[param_index].toType(); | 5130 | const param_ty = fn_info.param_types.get(ip)[param_index].toType(); |
| 5251 | const param_llvm_ty = try o.lowerLlvmType(param_ty); | 5131 | const param_llvm_ty = try o.lowerType(param_ty); |
| 5252 | const alignment = param_ty.abiAlignment(mod); | 5132 | const alignment = param_ty.abiAlignment(mod); |
| 5253 | o.addByRefParamAttrs(call, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty); | 5133 | o.addByRefParamAttrs(call, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty); |
| 5254 | }, | 5134 | }, |
| ... | @@ -5297,7 +5177,7 @@ pub const FuncGen = struct { | ... | @@ -5297,7 +5177,7 @@ pub const FuncGen = struct { |
| 5297 | return null; | 5177 | return null; |
| 5298 | } | 5178 | } |
| 5299 | | 5179 | |
| 5300 | const llvm_ret_ty = try o.lowerLlvmType(return_type); | 5180 | const llvm_ret_ty = (try o.lowerType(return_type)).toLlvm(&o.builder); |
| 5301 | | 5181 | |
| 5302 | if (ret_ptr) |rp| { | 5182 | if (ret_ptr) |rp| { |
| 5303 | call.setCallSret(llvm_ret_ty); | 5183 | call.setCallSret(llvm_ret_ty); |
| ... | @@ -5311,7 +5191,7 @@ pub const FuncGen = struct { | ... | @@ -5311,7 +5191,7 @@ pub const FuncGen = struct { |
| 5311 | } | 5191 | } |
| 5312 | } | 5192 | } |
| 5313 | | 5193 | |
| 5314 | const abi_ret_ty = try lowerFnRetTy(o, fn_info); | 5194 | const abi_ret_ty = (try lowerFnRetTy(o, fn_info)).toLlvm(&o.builder); |
| 5315 | | 5195 | |
| 5316 | if (abi_ret_ty != llvm_ret_ty) { | 5196 | if (abi_ret_ty != llvm_ret_ty) { |
| 5317 | // In this case the function return type is honoring the calling convention by having | 5197 | // In this case the function return type is honoring the calling convention by having |
| ... | @@ -5374,7 +5254,7 @@ pub const FuncGen = struct { | ... | @@ -5374,7 +5254,7 @@ pub const FuncGen = struct { |
| 5374 | const fn_info = mod.typeToFunc(panic_decl.ty).?; | 5254 | const fn_info = mod.typeToFunc(panic_decl.ty).?; |
| 5375 | const panic_global = try o.resolveLlvmFunction(panic_func.owner_decl); | 5255 | const panic_global = try o.resolveLlvmFunction(panic_func.owner_decl); |
| 5376 | _ = fg.builder.buildCall( | 5256 | _ = fg.builder.buildCall( |
| 5377 | try o.lowerLlvmType(panic_decl.ty), | 5257 | (try o.lowerType(panic_decl.ty)).toLlvm(&o.builder), |
| 5378 | panic_global.toLlvm(&o.builder), | 5258 | panic_global.toLlvm(&o.builder), |
| 5379 | &args, | 5259 | &args, |
| 5380 | args.len, | 5260 | args.len, |
| ... | @@ -5403,7 +5283,7 @@ pub const FuncGen = struct { | ... | @@ -5403,7 +5283,7 @@ pub const FuncGen = struct { |
| 5403 | // Functions with an empty error set are emitted with an error code | 5283 | // Functions with an empty error set are emitted with an error code |
| 5404 | // return type and return zero so they can be function pointers coerced | 5284 | // return type and return zero so they can be function pointers coerced |
| 5405 | // to functions that return anyerror. | 5285 | // to functions that return anyerror. |
| 5406 | const err_int = try o.lowerLlvmType(Type.anyerror); | 5286 | const err_int = (try o.lowerType(Type.anyerror)).toLlvm(&o.builder); |
| 5407 | _ = self.builder.buildRet(err_int.constInt(0, .False)); | 5287 | _ = self.builder.buildRet(err_int.constInt(0, .False)); |
| 5408 | } else { | 5288 | } else { |
| 5409 | _ = self.builder.buildRetVoid(); | 5289 | _ = self.builder.buildRetVoid(); |
| ... | @@ -5411,7 +5291,7 @@ pub const FuncGen = struct { | ... | @@ -5411,7 +5291,7 @@ pub const FuncGen = struct { |
| 5411 | return null; | 5291 | return null; |
| 5412 | } | 5292 | } |
| 5413 | | 5293 | |
| 5414 | const abi_ret_ty = try lowerFnRetTy(o, fn_info); | 5294 | const abi_ret_ty = (try lowerFnRetTy(o, fn_info)).toLlvm(&o.builder); |
| 5415 | const operand = try self.resolveInst(un_op); | 5295 | const operand = try self.resolveInst(un_op); |
| 5416 | const alignment = ret_ty.abiAlignment(mod); | 5296 | const alignment = ret_ty.abiAlignment(mod); |
| 5417 | | 5297 | |
| ... | @@ -5451,7 +5331,7 @@ pub const FuncGen = struct { | ... | @@ -5451,7 +5331,7 @@ pub const FuncGen = struct { |
| 5451 | // Functions with an empty error set are emitted with an error code | 5331 | // Functions with an empty error set are emitted with an error code |
| 5452 | // return type and return zero so they can be function pointers coerced | 5332 | // return type and return zero so they can be function pointers coerced |
| 5453 | // to functions that return anyerror. | 5333 | // to functions that return anyerror. |
| 5454 | const err_int = try o.lowerLlvmType(Type.anyerror); | 5334 | const err_int = (try o.lowerType(Type.anyerror)).toLlvm(&o.builder); |
| 5455 | _ = self.builder.buildRet(err_int.constInt(0, .False)); | 5335 | _ = self.builder.buildRet(err_int.constInt(0, .False)); |
| 5456 | } else { | 5336 | } else { |
| 5457 | _ = self.builder.buildRetVoid(); | 5337 | _ = self.builder.buildRetVoid(); |
| ... | @@ -5463,7 +5343,7 @@ pub const FuncGen = struct { | ... | @@ -5463,7 +5343,7 @@ pub const FuncGen = struct { |
| 5463 | return null; | 5343 | return null; |
| 5464 | } | 5344 | } |
| 5465 | const ptr = try self.resolveInst(un_op); | 5345 | const ptr = try self.resolveInst(un_op); |
| 5466 | const abi_ret_ty = try lowerFnRetTy(o, fn_info); | 5346 | const abi_ret_ty = (try lowerFnRetTy(o, fn_info)).toLlvm(&o.builder); |
| 5467 | const loaded = self.builder.buildLoad(abi_ret_ty, ptr, ""); | 5347 | const loaded = self.builder.buildLoad(abi_ret_ty, ptr, ""); |
| 5468 | loaded.setAlignment(ret_ty.abiAlignment(mod)); | 5348 | loaded.setAlignment(ret_ty.abiAlignment(mod)); |
| 5469 | _ = self.builder.buildRet(loaded); | 5349 | _ = self.builder.buildRet(loaded); |
| ... | @@ -5475,7 +5355,7 @@ pub const FuncGen = struct { | ... | @@ -5475,7 +5355,7 @@ pub const FuncGen = struct { |
| 5475 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 5355 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 5476 | const list = try self.resolveInst(ty_op.operand); | 5356 | const list = try self.resolveInst(ty_op.operand); |
| 5477 | const arg_ty = self.air.getRefType(ty_op.ty); | 5357 | const arg_ty = self.air.getRefType(ty_op.ty); |
| 5478 | const llvm_arg_ty = try o.lowerLlvmType(arg_ty); | 5358 | const llvm_arg_ty = (try o.lowerType(arg_ty)).toLlvm(&o.builder); |
| 5479 | | 5359 | |
| 5480 | return self.builder.buildVAArg(list, llvm_arg_ty, ""); | 5360 | return self.builder.buildVAArg(list, llvm_arg_ty, ""); |
| 5481 | } | 5361 | } |
| ... | @@ -5485,7 +5365,7 @@ pub const FuncGen = struct { | ... | @@ -5485,7 +5365,7 @@ pub const FuncGen = struct { |
| 5485 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 5365 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 5486 | const src_list = try self.resolveInst(ty_op.operand); | 5366 | const src_list = try self.resolveInst(ty_op.operand); |
| 5487 | const va_list_ty = self.air.getRefType(ty_op.ty); | 5367 | const va_list_ty = self.air.getRefType(ty_op.ty); |
| 5488 | const llvm_va_list_ty = try o.lowerLlvmType(va_list_ty); | 5368 | const llvm_va_list_ty = (try o.lowerType(va_list_ty)).toLlvm(&o.builder); |
| 5489 | const mod = o.module; | 5369 | const mod = o.module; |
| 5490 | | 5370 | |
| 5491 | const result_alignment = va_list_ty.abiAlignment(mod); | 5371 | const result_alignment = va_list_ty.abiAlignment(mod); |
| ... | @@ -5533,7 +5413,7 @@ pub const FuncGen = struct { | ... | @@ -5533,7 +5413,7 @@ pub const FuncGen = struct { |
| 5533 | const o = self.dg.object; | 5413 | const o = self.dg.object; |
| 5534 | const mod = o.module; | 5414 | const mod = o.module; |
| 5535 | const va_list_ty = self.typeOfIndex(inst); | 5415 | const va_list_ty = self.typeOfIndex(inst); |
| 5536 | const llvm_va_list_ty = try o.lowerLlvmType(va_list_ty); | 5416 | const llvm_va_list_ty = (try o.lowerType(va_list_ty)).toLlvm(&o.builder); |
| 5537 | | 5417 | |
| 5538 | const result_alignment = va_list_ty.abiAlignment(mod); | 5418 | const result_alignment = va_list_ty.abiAlignment(mod); |
| 5539 | const list = self.buildAlloca(llvm_va_list_ty, result_alignment); | 5419 | const list = self.buildAlloca(llvm_va_list_ty, result_alignment); |
| ... | @@ -5612,7 +5492,7 @@ pub const FuncGen = struct { | ... | @@ -5612,7 +5492,7 @@ pub const FuncGen = struct { |
| 5612 | // We need to emit instructions to check for equality/inequality | 5492 | // We need to emit instructions to check for equality/inequality |
| 5613 | // of optionals that are not pointers. | 5493 | // of optionals that are not pointers. |
| 5614 | const is_by_ref = isByRef(scalar_ty, mod); | 5494 | const is_by_ref = isByRef(scalar_ty, mod); |
| 5615 | const opt_llvm_ty = try o.lowerLlvmType(scalar_ty); | 5495 | const opt_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder); |
| 5616 | const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref); | 5496 | const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref); |
| 5617 | const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref); | 5497 | const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref); |
| 5618 | const llvm_i2 = self.context.intType(2); | 5498 | const llvm_i2 = self.context.intType(2); |
| ... | @@ -5722,7 +5602,7 @@ pub const FuncGen = struct { | ... | @@ -5722,7 +5602,7 @@ pub const FuncGen = struct { |
| 5722 | const is_body = inst_ty.zigTypeTag(mod) == .Fn; | 5602 | const is_body = inst_ty.zigTypeTag(mod) == .Fn; |
| 5723 | if (!is_body and !inst_ty.hasRuntimeBitsIgnoreComptime(mod)) return null; | 5603 | if (!is_body and !inst_ty.hasRuntimeBitsIgnoreComptime(mod)) return null; |
| 5724 | | 5604 | |
| 5725 | const raw_llvm_ty = try o.lowerLlvmType(inst_ty); | 5605 | const raw_llvm_ty = (try o.lowerType(inst_ty)).toLlvm(&o.builder); |
| 5726 | | 5606 | |
| 5727 | const llvm_ty = ty: { | 5607 | const llvm_ty = ty: { |
| 5728 | // If the zig tag type is a function, this represents an actual function body; not | 5608 | // If the zig tag type is a function, this represents an actual function body; not |
| ... | @@ -5827,11 +5707,11 @@ pub const FuncGen = struct { | ... | @@ -5827,11 +5707,11 @@ pub const FuncGen = struct { |
| 5827 | const mod = o.module; | 5707 | const mod = o.module; |
| 5828 | const payload_ty = err_union_ty.errorUnionPayload(mod); | 5708 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| 5829 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod); | 5709 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod); |
| 5830 | const err_union_llvm_ty = try o.lowerLlvmType(err_union_ty); | 5710 | const err_union_llvm_ty = (try o.lowerType(err_union_ty)).toLlvm(&o.builder); |
| 5831 | | 5711 | |
| 5832 | if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { | 5712 | if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { |
| 5833 | const is_err = err: { | 5713 | const is_err = err: { |
| 5834 | const err_set_ty = try o.lowerLlvmType(Type.anyerror); | 5714 | const err_set_ty = (try o.lowerType(Type.anyerror)).toLlvm(&o.builder); |
| 5835 | const zero = err_set_ty.constNull(); | 5715 | const zero = err_set_ty.constNull(); |
| 5836 | if (!payload_has_bits) { | 5716 | if (!payload_has_bits) { |
| 5837 | // TODO add alignment to this load | 5717 | // TODO add alignment to this load |
| ... | @@ -5966,9 +5846,9 @@ pub const FuncGen = struct { | ... | @@ -5966,9 +5846,9 @@ pub const FuncGen = struct { |
| 5966 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 5846 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 5967 | const operand_ty = self.typeOf(ty_op.operand); | 5847 | const operand_ty = self.typeOf(ty_op.operand); |
| 5968 | const array_ty = operand_ty.childType(mod); | 5848 | const array_ty = operand_ty.childType(mod); |
| 5969 | const llvm_usize = try o.lowerLlvmType(Type.usize); | 5849 | const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder); |
| 5970 | const len = llvm_usize.constInt(array_ty.arrayLen(mod), .False); | 5850 | const len = llvm_usize.constInt(array_ty.arrayLen(mod), .False); |
| 5971 | const slice_llvm_ty = try o.lowerLlvmType(self.typeOfIndex(inst)); | 5851 | const slice_llvm_ty = (try o.lowerType(self.typeOfIndex(inst))).toLlvm(&o.builder); |
| 5972 | const operand = try self.resolveInst(ty_op.operand); | 5852 | const operand = try self.resolveInst(ty_op.operand); |
| 5973 | if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 5853 | if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 5974 | const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), operand, 0, ""); | 5854 | const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), operand, 0, ""); |
| ... | @@ -5977,7 +5857,7 @@ pub const FuncGen = struct { | ... | @@ -5977,7 +5857,7 @@ pub const FuncGen = struct { |
| 5977 | const indices: [2]*llvm.Value = .{ | 5857 | const indices: [2]*llvm.Value = .{ |
| 5978 | llvm_usize.constNull(), llvm_usize.constNull(), | 5858 | llvm_usize.constNull(), llvm_usize.constNull(), |
| 5979 | }; | 5859 | }; |
| 5980 | const array_llvm_ty = try o.lowerLlvmType(array_ty); | 5860 | const array_llvm_ty = (try o.lowerType(array_ty)).toLlvm(&o.builder); |
| 5981 | const ptr = self.builder.buildInBoundsGEP(array_llvm_ty, operand, &indices, indices.len, ""); | 5861 | const ptr = self.builder.buildInBoundsGEP(array_llvm_ty, operand, &indices, indices.len, ""); |
| 5982 | const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, ""); | 5862 | const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, ""); |
| 5983 | return self.builder.buildInsertValue(partial, len, 1, ""); | 5863 | return self.builder.buildInsertValue(partial, len, 1, ""); |
| ... | @@ -5994,7 +5874,7 @@ pub const FuncGen = struct { | ... | @@ -5994,7 +5874,7 @@ pub const FuncGen = struct { |
| 5994 | | 5874 | |
| 5995 | const dest_ty = self.typeOfIndex(inst); | 5875 | const dest_ty = self.typeOfIndex(inst); |
| 5996 | const dest_scalar_ty = dest_ty.scalarType(mod); | 5876 | const dest_scalar_ty = dest_ty.scalarType(mod); |
| 5997 | const dest_llvm_ty = try o.lowerLlvmType(dest_ty); | 5877 | const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder); |
| 5998 | const target = mod.getTarget(); | 5878 | const target = mod.getTarget(); |
| 5999 | | 5879 | |
| 6000 | if (intrinsicsAllowed(dest_scalar_ty, target)) { | 5880 | if (intrinsicsAllowed(dest_scalar_ty, target)) { |
| ... | @@ -6055,7 +5935,7 @@ pub const FuncGen = struct { | ... | @@ -6055,7 +5935,7 @@ pub const FuncGen = struct { |
| 6055 | | 5935 | |
| 6056 | const dest_ty = self.typeOfIndex(inst); | 5936 | const dest_ty = self.typeOfIndex(inst); |
| 6057 | const dest_scalar_ty = dest_ty.scalarType(mod); | 5937 | const dest_scalar_ty = dest_ty.scalarType(mod); |
| 6058 | const dest_llvm_ty = try o.lowerLlvmType(dest_ty); | 5938 | const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder); |
| 6059 | | 5939 | |
| 6060 | if (intrinsicsAllowed(operand_scalar_ty, target)) { | 5940 | if (intrinsicsAllowed(operand_scalar_ty, target)) { |
| 6061 | // TODO set fast math flag | 5941 | // TODO set fast math flag |
| ... | @@ -6087,7 +5967,7 @@ pub const FuncGen = struct { | ... | @@ -6087,7 +5967,7 @@ pub const FuncGen = struct { |
| 6087 | compiler_rt_dest_abbrev, | 5967 | compiler_rt_dest_abbrev, |
| 6088 | }) catch unreachable; | 5968 | }) catch unreachable; |
| 6089 | | 5969 | |
| 6090 | const operand_llvm_ty = try o.lowerLlvmType(operand_ty); | 5970 | const operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder); |
| 6091 | const param_types = [1]*llvm.Type{operand_llvm_ty}; | 5971 | const param_types = [1]*llvm.Type{operand_llvm_ty}; |
| 6092 | const libc_fn = try self.getLibcFunction(fn_name, &param_types, libc_ret_ty); | 5972 | const libc_fn = try self.getLibcFunction(fn_name, &param_types, libc_ret_ty); |
| 6093 | const params = [1]*llvm.Value{operand}; | 5973 | const params = [1]*llvm.Value{operand}; |
| ... | @@ -6145,7 +6025,7 @@ pub const FuncGen = struct { | ... | @@ -6145,7 +6025,7 @@ pub const FuncGen = struct { |
| 6145 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 6025 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 6146 | const slice_ptr = try self.resolveInst(ty_op.operand); | 6026 | const slice_ptr = try self.resolveInst(ty_op.operand); |
| 6147 | const slice_ptr_ty = self.typeOf(ty_op.operand); | 6027 | const slice_ptr_ty = self.typeOf(ty_op.operand); |
| 6148 | const slice_llvm_ty = try o.lowerPtrElemTy(slice_ptr_ty.childType(mod)); | 6028 | const slice_llvm_ty = (try o.lowerPtrElemTy(slice_ptr_ty.childType(mod))).toLlvm(&o.builder); |
| 6149 | | 6029 | |
| 6150 | return self.builder.buildStructGEP(slice_llvm_ty, slice_ptr, index, ""); | 6030 | return self.builder.buildStructGEP(slice_llvm_ty, slice_ptr, index, ""); |
| 6151 | } | 6031 | } |
| ... | @@ -6159,7 +6039,7 @@ pub const FuncGen = struct { | ... | @@ -6159,7 +6039,7 @@ pub const FuncGen = struct { |
| 6159 | const slice = try self.resolveInst(bin_op.lhs); | 6039 | const slice = try self.resolveInst(bin_op.lhs); |
| 6160 | const index = try self.resolveInst(bin_op.rhs); | 6040 | const index = try self.resolveInst(bin_op.rhs); |
| 6161 | const elem_ty = slice_ty.childType(mod); | 6041 | const elem_ty = slice_ty.childType(mod); |
| 6162 | const llvm_elem_ty = try o.lowerPtrElemTy(elem_ty); | 6042 | const llvm_elem_ty = (try o.lowerPtrElemTy(elem_ty)).toLlvm(&o.builder); |
| 6163 | const base_ptr = self.builder.buildExtractValue(slice, 0, ""); | 6043 | const base_ptr = self.builder.buildExtractValue(slice, 0, ""); |
| 6164 | const indices: [1]*llvm.Value = .{index}; | 6044 | const indices: [1]*llvm.Value = .{index}; |
| 6165 | const ptr = self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); | 6045 | const ptr = self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| ... | @@ -6182,7 +6062,7 @@ pub const FuncGen = struct { | ... | @@ -6182,7 +6062,7 @@ pub const FuncGen = struct { |
| 6182 | | 6062 | |
| 6183 | const slice = try self.resolveInst(bin_op.lhs); | 6063 | const slice = try self.resolveInst(bin_op.lhs); |
| 6184 | const index = try self.resolveInst(bin_op.rhs); | 6064 | const index = try self.resolveInst(bin_op.rhs); |
| 6185 | const llvm_elem_ty = try o.lowerPtrElemTy(slice_ty.childType(mod)); | 6065 | const llvm_elem_ty = (try o.lowerPtrElemTy(slice_ty.childType(mod))).toLlvm(&o.builder); |
| 6186 | const base_ptr = self.builder.buildExtractValue(slice, 0, ""); | 6066 | const base_ptr = self.builder.buildExtractValue(slice, 0, ""); |
| 6187 | const indices: [1]*llvm.Value = .{index}; | 6067 | const indices: [1]*llvm.Value = .{index}; |
| 6188 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); | 6068 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| ... | @@ -6197,7 +6077,7 @@ pub const FuncGen = struct { | ... | @@ -6197,7 +6077,7 @@ pub const FuncGen = struct { |
| 6197 | const array_ty = self.typeOf(bin_op.lhs); | 6077 | const array_ty = self.typeOf(bin_op.lhs); |
| 6198 | const array_llvm_val = try self.resolveInst(bin_op.lhs); | 6078 | const array_llvm_val = try self.resolveInst(bin_op.lhs); |
| 6199 | const rhs = try self.resolveInst(bin_op.rhs); | 6079 | const rhs = try self.resolveInst(bin_op.rhs); |
| 6200 | const array_llvm_ty = try o.lowerLlvmType(array_ty); | 6080 | const array_llvm_ty = (try o.lowerType(array_ty)).toLlvm(&o.builder); |
| 6201 | const elem_ty = array_ty.childType(mod); | 6081 | const elem_ty = array_ty.childType(mod); |
| 6202 | if (isByRef(array_ty, mod)) { | 6082 | if (isByRef(array_ty, mod)) { |
| 6203 | const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs }; | 6083 | const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs }; |
| ... | @@ -6208,7 +6088,7 @@ pub const FuncGen = struct { | ... | @@ -6208,7 +6088,7 @@ pub const FuncGen = struct { |
| 6208 | | 6088 | |
| 6209 | return self.loadByRef(elem_ptr, elem_ty, elem_ty.abiAlignment(mod), false); | 6089 | return self.loadByRef(elem_ptr, elem_ty, elem_ty.abiAlignment(mod), false); |
| 6210 | } else { | 6090 | } else { |
| 6211 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); | 6091 | const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder); |
| 6212 | if (Air.refToIndex(bin_op.lhs)) |lhs_index| { | 6092 | if (Air.refToIndex(bin_op.lhs)) |lhs_index| { |
| 6213 | if (self.air.instructions.items(.tag)[lhs_index] == .load) { | 6093 | if (self.air.instructions.items(.tag)[lhs_index] == .load) { |
| 6214 | const load_data = self.air.instructions.items(.data)[lhs_index]; | 6094 | const load_data = self.air.instructions.items(.data)[lhs_index]; |
| ... | @@ -6242,7 +6122,7 @@ pub const FuncGen = struct { | ... | @@ -6242,7 +6122,7 @@ pub const FuncGen = struct { |
| 6242 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 6122 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 6243 | const ptr_ty = self.typeOf(bin_op.lhs); | 6123 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 6244 | const elem_ty = ptr_ty.childType(mod); | 6124 | const elem_ty = ptr_ty.childType(mod); |
| 6245 | const llvm_elem_ty = try o.lowerPtrElemTy(elem_ty); | 6125 | const llvm_elem_ty = (try o.lowerPtrElemTy(elem_ty)).toLlvm(&o.builder); |
| 6246 | const base_ptr = try self.resolveInst(bin_op.lhs); | 6126 | const base_ptr = try self.resolveInst(bin_op.lhs); |
| 6247 | const rhs = try self.resolveInst(bin_op.rhs); | 6127 | const rhs = try self.resolveInst(bin_op.rhs); |
| 6248 | // TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch | 6128 | // TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch |
| ... | @@ -6279,7 +6159,7 @@ pub const FuncGen = struct { | ... | @@ -6279,7 +6159,7 @@ pub const FuncGen = struct { |
| 6279 | const elem_ptr = self.air.getRefType(ty_pl.ty); | 6159 | const elem_ptr = self.air.getRefType(ty_pl.ty); |
| 6280 | if (elem_ptr.ptrInfo(mod).flags.vector_index != .none) return base_ptr; | 6160 | if (elem_ptr.ptrInfo(mod).flags.vector_index != .none) return base_ptr; |
| 6281 | | 6161 | |
| 6282 | const llvm_elem_ty = try o.lowerPtrElemTy(elem_ty); | 6162 | const llvm_elem_ty = (try o.lowerPtrElemTy(elem_ty)).toLlvm(&o.builder); |
| 6283 | if (ptr_ty.isSinglePointer(mod)) { | 6163 | if (ptr_ty.isSinglePointer(mod)) { |
| 6284 | // If this is a single-item pointer to an array, we need another index in the GEP. | 6164 | // If this is a single-item pointer to an array, we need another index in the GEP. |
| 6285 | const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs }; | 6165 | const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs }; |
| ... | @@ -6333,7 +6213,7 @@ pub const FuncGen = struct { | ... | @@ -6333,7 +6213,7 @@ pub const FuncGen = struct { |
| 6333 | const containing_int = struct_llvm_val; | 6213 | const containing_int = struct_llvm_val; |
| 6334 | const shift_amt = containing_int.typeOf().constInt(bit_offset, .False); | 6214 | const shift_amt = containing_int.typeOf().constInt(bit_offset, .False); |
| 6335 | const shifted_value = self.builder.buildLShr(containing_int, shift_amt, ""); | 6215 | const shifted_value = self.builder.buildLShr(containing_int, shift_amt, ""); |
| 6336 | const elem_llvm_ty = try o.lowerLlvmType(field_ty); | 6216 | const elem_llvm_ty = (try o.lowerType(field_ty)).toLlvm(&o.builder); |
| 6337 | if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) { | 6217 | if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) { |
| 6338 | const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod))); | 6218 | const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod))); |
| 6339 | const same_size_int = self.context.intType(elem_bits); | 6219 | const same_size_int = self.context.intType(elem_bits); |
| ... | @@ -6355,7 +6235,7 @@ pub const FuncGen = struct { | ... | @@ -6355,7 +6235,7 @@ pub const FuncGen = struct { |
| 6355 | .Union => { | 6235 | .Union => { |
| 6356 | assert(struct_ty.containerLayout(mod) == .Packed); | 6236 | assert(struct_ty.containerLayout(mod) == .Packed); |
| 6357 | const containing_int = struct_llvm_val; | 6237 | const containing_int = struct_llvm_val; |
| 6358 | const elem_llvm_ty = try o.lowerLlvmType(field_ty); | 6238 | const elem_llvm_ty = (try o.lowerType(field_ty)).toLlvm(&o.builder); |
| 6359 | if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) { | 6239 | if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) { |
| 6360 | const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod))); | 6240 | const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod))); |
| 6361 | const same_size_int = self.context.intType(elem_bits); | 6241 | const same_size_int = self.context.intType(elem_bits); |
| ... | @@ -6377,7 +6257,7 @@ pub const FuncGen = struct { | ... | @@ -6377,7 +6257,7 @@ pub const FuncGen = struct { |
| 6377 | .Struct => { | 6257 | .Struct => { |
| 6378 | assert(struct_ty.containerLayout(mod) != .Packed); | 6258 | assert(struct_ty.containerLayout(mod) != .Packed); |
| 6379 | const llvm_field = llvmField(struct_ty, field_index, mod).?; | 6259 | const llvm_field = llvmField(struct_ty, field_index, mod).?; |
| 6380 | const struct_llvm_ty = try o.lowerLlvmType(struct_ty); | 6260 | const struct_llvm_ty = (try o.lowerType(struct_ty)).toLlvm(&o.builder); |
| 6381 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field.index, ""); | 6261 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field.index, ""); |
| 6382 | const field_ptr_ty = try mod.ptrType(.{ | 6262 | const field_ptr_ty = try mod.ptrType(.{ |
| 6383 | .child = llvm_field.ty.toIntern(), | 6263 | .child = llvm_field.ty.toIntern(), |
| ... | @@ -6396,11 +6276,11 @@ pub const FuncGen = struct { | ... | @@ -6396,11 +6276,11 @@ pub const FuncGen = struct { |
| 6396 | } | 6276 | } |
| 6397 | }, | 6277 | }, |
| 6398 | .Union => { | 6278 | .Union => { |
| 6399 | const union_llvm_ty = try o.lowerLlvmType(struct_ty); | 6279 | const union_llvm_ty = (try o.lowerType(struct_ty)).toLlvm(&o.builder); |
| 6400 | const layout = struct_ty.unionGetLayout(mod); | 6280 | const layout = struct_ty.unionGetLayout(mod); |
| 6401 | const payload_index = @intFromBool(layout.tag_align >= layout.payload_align); | 6281 | const payload_index = @intFromBool(layout.tag_align >= layout.payload_align); |
| 6402 | const field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, ""); | 6282 | const field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, ""); |
| 6403 | const llvm_field_ty = try o.lowerLlvmType(field_ty); | 6283 | const llvm_field_ty = (try o.lowerType(field_ty)).toLlvm(&o.builder); |
| 6404 | if (isByRef(field_ty, mod)) { | 6284 | if (isByRef(field_ty, mod)) { |
| 6405 | if (canElideLoad(self, body_tail)) | 6285 | if (canElideLoad(self, body_tail)) |
| 6406 | return field_ptr; | 6286 | return field_ptr; |
| ... | @@ -6426,7 +6306,7 @@ pub const FuncGen = struct { | ... | @@ -6426,7 +6306,7 @@ pub const FuncGen = struct { |
| 6426 | const parent_ty = self.air.getRefType(ty_pl.ty).childType(mod); | 6306 | const parent_ty = self.air.getRefType(ty_pl.ty).childType(mod); |
| 6427 | const field_offset = parent_ty.structFieldOffset(extra.field_index, mod); | 6307 | const field_offset = parent_ty.structFieldOffset(extra.field_index, mod); |
| 6428 | | 6308 | |
| 6429 | const res_ty = try o.lowerLlvmType(self.air.getRefType(ty_pl.ty)); | 6309 | const res_ty = (try o.lowerType(self.air.getRefType(ty_pl.ty))).toLlvm(&o.builder); |
| 6430 | if (field_offset == 0) { | 6310 | if (field_offset == 0) { |
| 6431 | return field_ptr; | 6311 | return field_ptr; |
| 6432 | } | 6312 | } |
| ... | @@ -6691,7 +6571,7 @@ pub const FuncGen = struct { | ... | @@ -6691,7 +6571,7 @@ pub const FuncGen = struct { |
| 6691 | const output_inst = try self.resolveInst(output); | 6571 | const output_inst = try self.resolveInst(output); |
| 6692 | const output_ty = self.typeOf(output); | 6572 | const output_ty = self.typeOf(output); |
| 6693 | assert(output_ty.zigTypeTag(mod) == .Pointer); | 6573 | assert(output_ty.zigTypeTag(mod) == .Pointer); |
| 6694 | const elem_llvm_ty = try o.lowerPtrElemTy(output_ty.childType(mod)); | 6574 | const elem_llvm_ty = (try o.lowerPtrElemTy(output_ty.childType(mod))).toLlvm(&o.builder); |
| 6695 | | 6575 | |
| 6696 | if (llvm_ret_indirect[i]) { | 6576 | if (llvm_ret_indirect[i]) { |
| 6697 | // Pass the result by reference as an indirect output (e.g. "=*m") | 6577 | // Pass the result by reference as an indirect output (e.g. "=*m") |
| ... | @@ -6708,7 +6588,7 @@ pub const FuncGen = struct { | ... | @@ -6708,7 +6588,7 @@ pub const FuncGen = struct { |
| 6708 | } | 6588 | } |
| 6709 | } else { | 6589 | } else { |
| 6710 | const ret_ty = self.typeOfIndex(inst); | 6590 | const ret_ty = self.typeOfIndex(inst); |
| 6711 | llvm_ret_types[llvm_ret_i] = try o.lowerLlvmType(ret_ty); | 6591 | llvm_ret_types[llvm_ret_i] = (try o.lowerType(ret_ty)).toLlvm(&o.builder); |
| 6712 | llvm_ret_i += 1; | 6592 | llvm_ret_i += 1; |
| 6713 | } | 6593 | } |
| 6714 | | 6594 | |
| ... | @@ -6745,13 +6625,13 @@ pub const FuncGen = struct { | ... | @@ -6745,13 +6625,13 @@ pub const FuncGen = struct { |
| 6745 | const arg_ty = self.typeOf(input); | 6625 | const arg_ty = self.typeOf(input); |
| 6746 | var llvm_elem_ty: ?*llvm.Type = null; | 6626 | var llvm_elem_ty: ?*llvm.Type = null; |
| 6747 | if (isByRef(arg_ty, mod)) { | 6627 | if (isByRef(arg_ty, mod)) { |
| 6748 | llvm_elem_ty = try o.lowerPtrElemTy(arg_ty); | 6628 | llvm_elem_ty = (try o.lowerPtrElemTy(arg_ty)).toLlvm(&o.builder); |
| 6749 | if (constraintAllowsMemory(constraint)) { | 6629 | if (constraintAllowsMemory(constraint)) { |
| 6750 | llvm_param_values[llvm_param_i] = arg_llvm_value; | 6630 | llvm_param_values[llvm_param_i] = arg_llvm_value; |
| 6751 | llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf(); | 6631 | llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf(); |
| 6752 | } else { | 6632 | } else { |
| 6753 | const alignment = arg_ty.abiAlignment(mod); | 6633 | const alignment = arg_ty.abiAlignment(mod); |
| 6754 | const arg_llvm_ty = try o.lowerLlvmType(arg_ty); | 6634 | const arg_llvm_ty = (try o.lowerType(arg_ty)).toLlvm(&o.builder); |
| 6755 | const load_inst = self.builder.buildLoad(arg_llvm_ty, arg_llvm_value, ""); | 6635 | const load_inst = self.builder.buildLoad(arg_llvm_ty, arg_llvm_value, ""); |
| 6756 | load_inst.setAlignment(alignment); | 6636 | load_inst.setAlignment(alignment); |
| 6757 | llvm_param_values[llvm_param_i] = load_inst; | 6637 | llvm_param_values[llvm_param_i] = load_inst; |
| ... | @@ -6792,7 +6672,7 @@ pub const FuncGen = struct { | ... | @@ -6792,7 +6672,7 @@ pub const FuncGen = struct { |
| 6792 | // an elementtype(<ty>) attribute. | 6672 | // an elementtype(<ty>) attribute. |
| 6793 | if (constraint[0] == '*') { | 6673 | if (constraint[0] == '*') { |
| 6794 | llvm_param_attrs[llvm_param_i] = llvm_elem_ty orelse | 6674 | llvm_param_attrs[llvm_param_i] = llvm_elem_ty orelse |
| 6795 | try o.lowerPtrElemTy(arg_ty.childType(mod)); | 6675 | (try o.lowerPtrElemTy(arg_ty.childType(mod))).toLlvm(&o.builder); |
| 6796 | } else { | 6676 | } else { |
| 6797 | llvm_param_attrs[llvm_param_i] = null; | 6677 | llvm_param_attrs[llvm_param_i] = null; |
| 6798 | } | 6678 | } |
| ... | @@ -6989,7 +6869,7 @@ pub const FuncGen = struct { | ... | @@ -6989,7 +6869,7 @@ pub const FuncGen = struct { |
| 6989 | const operand = try self.resolveInst(un_op); | 6869 | const operand = try self.resolveInst(un_op); |
| 6990 | const operand_ty = self.typeOf(un_op); | 6870 | const operand_ty = self.typeOf(un_op); |
| 6991 | const optional_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; | 6871 | const optional_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; |
| 6992 | const optional_llvm_ty = try o.lowerLlvmType(optional_ty); | 6872 | const optional_llvm_ty = (try o.lowerType(optional_ty)).toLlvm(&o.builder); |
| 6993 | const payload_ty = optional_ty.optionalChild(mod); | 6873 | const payload_ty = optional_ty.optionalChild(mod); |
| 6994 | if (optional_ty.optionalReprIsPayload(mod)) { | 6874 | if (optional_ty.optionalReprIsPayload(mod)) { |
| 6995 | const loaded = if (operand_is_ptr) | 6875 | const loaded = if (operand_is_ptr) |
| ... | @@ -6998,7 +6878,7 @@ pub const FuncGen = struct { | ... | @@ -6998,7 +6878,7 @@ pub const FuncGen = struct { |
| 6998 | operand; | 6878 | operand; |
| 6999 | if (payload_ty.isSlice(mod)) { | 6879 | if (payload_ty.isSlice(mod)) { |
| 7000 | const slice_ptr = self.builder.buildExtractValue(loaded, 0, ""); | 6880 | const slice_ptr = self.builder.buildExtractValue(loaded, 0, ""); |
| 7001 | const ptr_ty = try o.lowerLlvmType(payload_ty.slicePtrFieldType(mod)); | 6881 | const ptr_ty = (try o.lowerType(payload_ty.slicePtrFieldType(mod))).toLlvm(&o.builder); |
| 7002 | return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), ""); | 6882 | return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), ""); |
| 7003 | } | 6883 | } |
| 7004 | return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), ""); | 6884 | return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), ""); |
| ... | @@ -7037,7 +6917,7 @@ pub const FuncGen = struct { | ... | @@ -7037,7 +6917,7 @@ pub const FuncGen = struct { |
| 7037 | const operand_ty = self.typeOf(un_op); | 6917 | const operand_ty = self.typeOf(un_op); |
| 7038 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; | 6918 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; |
| 7039 | const payload_ty = err_union_ty.errorUnionPayload(mod); | 6919 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| 7040 | const err_set_ty = try o.lowerLlvmType(Type.anyerror); | 6920 | const err_set_ty = (try o.lowerType(Type.anyerror)).toLlvm(&o.builder); |
| 7041 | const zero = err_set_ty.constNull(); | 6921 | const zero = err_set_ty.constNull(); |
| 7042 | | 6922 | |
| 7043 | if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { | 6923 | if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { |
| ... | @@ -7051,7 +6931,7 @@ pub const FuncGen = struct { | ... | @@ -7051,7 +6931,7 @@ pub const FuncGen = struct { |
| 7051 | | 6931 | |
| 7052 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 6932 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 7053 | const loaded = if (operand_is_ptr) | 6933 | const loaded = if (operand_is_ptr) |
| 7054 | self.builder.buildLoad(try o.lowerLlvmType(err_union_ty), operand, "") | 6934 | self.builder.buildLoad((try o.lowerType(err_union_ty)).toLlvm(&o.builder), operand, "") |
| 7055 | else | 6935 | else |
| 7056 | operand; | 6936 | operand; |
| 7057 | return self.builder.buildICmp(op, loaded, zero, ""); | 6937 | return self.builder.buildICmp(op, loaded, zero, ""); |
| ... | @@ -7060,7 +6940,7 @@ pub const FuncGen = struct { | ... | @@ -7060,7 +6940,7 @@ pub const FuncGen = struct { |
| 7060 | const err_field_index = errUnionErrorOffset(payload_ty, mod); | 6940 | const err_field_index = errUnionErrorOffset(payload_ty, mod); |
| 7061 | | 6941 | |
| 7062 | if (operand_is_ptr or isByRef(err_union_ty, mod)) { | 6942 | if (operand_is_ptr or isByRef(err_union_ty, mod)) { |
| 7063 | const err_union_llvm_ty = try o.lowerLlvmType(err_union_ty); | 6943 | const err_union_llvm_ty = (try o.lowerType(err_union_ty)).toLlvm(&o.builder); |
| 7064 | const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, err_field_index, ""); | 6944 | const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, err_field_index, ""); |
| 7065 | const loaded = self.builder.buildLoad(err_set_ty, err_field_ptr, ""); | 6945 | const loaded = self.builder.buildLoad(err_set_ty, err_field_ptr, ""); |
| 7066 | return self.builder.buildICmp(op, loaded, zero, ""); | 6946 | return self.builder.buildICmp(op, loaded, zero, ""); |
| ... | @@ -7086,7 +6966,7 @@ pub const FuncGen = struct { | ... | @@ -7086,7 +6966,7 @@ pub const FuncGen = struct { |
| 7086 | // The payload and the optional are the same value. | 6966 | // The payload and the optional are the same value. |
| 7087 | return operand; | 6967 | return operand; |
| 7088 | } | 6968 | } |
| 7089 | const optional_llvm_ty = try o.lowerLlvmType(optional_ty); | 6969 | const optional_llvm_ty = (try o.lowerType(optional_ty)).toLlvm(&o.builder); |
| 7090 | return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, ""); | 6970 | return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, ""); |
| 7091 | } | 6971 | } |
| 7092 | | 6972 | |
| ... | @@ -7112,7 +6992,7 @@ pub const FuncGen = struct { | ... | @@ -7112,7 +6992,7 @@ pub const FuncGen = struct { |
| 7112 | } | 6992 | } |
| 7113 | | 6993 | |
| 7114 | // First set the non-null bit. | 6994 | // First set the non-null bit. |
| 7115 | const optional_llvm_ty = try o.lowerLlvmType(optional_ty); | 6995 | const optional_llvm_ty = (try o.lowerType(optional_ty)).toLlvm(&o.builder); |
| 7116 | const non_null_ptr = self.builder.buildStructGEP(optional_llvm_ty, operand, 1, ""); | 6996 | const non_null_ptr = self.builder.buildStructGEP(optional_llvm_ty, operand, 1, ""); |
| 7117 | // TODO set alignment on this store | 6997 | // TODO set alignment on this store |
| 7118 | _ = self.builder.buildStore(non_null_bit, non_null_ptr); | 6998 | _ = self.builder.buildStore(non_null_bit, non_null_ptr); |
| ... | @@ -7139,7 +7019,7 @@ pub const FuncGen = struct { | ... | @@ -7139,7 +7019,7 @@ pub const FuncGen = struct { |
| 7139 | return operand; | 7019 | return operand; |
| 7140 | } | 7020 | } |
| 7141 | | 7021 | |
| 7142 | const opt_llvm_ty = try o.lowerLlvmType(optional_ty); | 7022 | const opt_llvm_ty = (try o.lowerType(optional_ty)).toLlvm(&o.builder); |
| 7143 | const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false; | 7023 | const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false; |
| 7144 | return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load); | 7024 | return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load); |
| 7145 | } | 7025 | } |
| ... | @@ -7163,7 +7043,7 @@ pub const FuncGen = struct { | ... | @@ -7163,7 +7043,7 @@ pub const FuncGen = struct { |
| 7163 | return if (operand_is_ptr) operand else null; | 7043 | return if (operand_is_ptr) operand else null; |
| 7164 | } | 7044 | } |
| 7165 | const offset = errUnionPayloadOffset(payload_ty, mod); | 7045 | const offset = errUnionPayloadOffset(payload_ty, mod); |
| 7166 | const err_union_llvm_ty = try o.lowerLlvmType(err_union_ty); | 7046 | const err_union_llvm_ty = (try o.lowerType(err_union_ty)).toLlvm(&o.builder); |
| 7167 | if (operand_is_ptr) { | 7047 | if (operand_is_ptr) { |
| 7168 | return self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, ""); | 7048 | return self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, ""); |
| 7169 | } else if (isByRef(err_union_ty, mod)) { | 7049 | } else if (isByRef(err_union_ty, mod)) { |
| ... | @@ -7193,7 +7073,7 @@ pub const FuncGen = struct { | ... | @@ -7193,7 +7073,7 @@ pub const FuncGen = struct { |
| 7193 | const operand_ty = self.typeOf(ty_op.operand); | 7073 | const operand_ty = self.typeOf(ty_op.operand); |
| 7194 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; | 7074 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; |
| 7195 | if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { | 7075 | if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { |
| 7196 | const err_llvm_ty = try o.lowerLlvmType(Type.anyerror); | 7076 | const err_llvm_ty = (try o.lowerType(Type.anyerror)).toLlvm(&o.builder); |
| 7197 | if (operand_is_ptr) { | 7077 | if (operand_is_ptr) { |
| 7198 | return operand; | 7078 | return operand; |
| 7199 | } else { | 7079 | } else { |
| ... | @@ -7201,7 +7081,7 @@ pub const FuncGen = struct { | ... | @@ -7201,7 +7081,7 @@ pub const FuncGen = struct { |
| 7201 | } | 7081 | } |
| 7202 | } | 7082 | } |
| 7203 | | 7083 | |
| 7204 | const err_set_llvm_ty = try o.lowerLlvmType(Type.anyerror); | 7084 | const err_set_llvm_ty = (try o.lowerType(Type.anyerror)).toLlvm(&o.builder); |
| 7205 | | 7085 | |
| 7206 | const payload_ty = err_union_ty.errorUnionPayload(mod); | 7086 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| 7207 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 7087 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| ... | @@ -7212,7 +7092,7 @@ pub const FuncGen = struct { | ... | @@ -7212,7 +7092,7 @@ pub const FuncGen = struct { |
| 7212 | const offset = errUnionErrorOffset(payload_ty, mod); | 7092 | const offset = errUnionErrorOffset(payload_ty, mod); |
| 7213 | | 7093 | |
| 7214 | if (operand_is_ptr or isByRef(err_union_ty, mod)) { | 7094 | if (operand_is_ptr or isByRef(err_union_ty, mod)) { |
| 7215 | const err_union_llvm_ty = try o.lowerLlvmType(err_union_ty); | 7095 | const err_union_llvm_ty = (try o.lowerType(err_union_ty)).toLlvm(&o.builder); |
| 7216 | const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, ""); | 7096 | const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, ""); |
| 7217 | return self.builder.buildLoad(err_set_llvm_ty, err_field_ptr, ""); | 7097 | return self.builder.buildLoad(err_set_llvm_ty, err_field_ptr, ""); |
| 7218 | } | 7098 | } |
| ... | @@ -7233,7 +7113,7 @@ pub const FuncGen = struct { | ... | @@ -7233,7 +7113,7 @@ pub const FuncGen = struct { |
| 7233 | _ = self.builder.buildStore(non_error_val, operand); | 7113 | _ = self.builder.buildStore(non_error_val, operand); |
| 7234 | return operand; | 7114 | return operand; |
| 7235 | } | 7115 | } |
| 7236 | const err_union_llvm_ty = try o.lowerLlvmType(err_union_ty); | 7116 | const err_union_llvm_ty = (try o.lowerType(err_union_ty)).toLlvm(&o.builder); |
| 7237 | { | 7117 | { |
| 7238 | const error_offset = errUnionErrorOffset(payload_ty, mod); | 7118 | const error_offset = errUnionErrorOffset(payload_ty, mod); |
| 7239 | // First set the non-error value. | 7119 | // First set the non-error value. |
| ... | @@ -7269,7 +7149,7 @@ pub const FuncGen = struct { | ... | @@ -7269,7 +7149,7 @@ pub const FuncGen = struct { |
| 7269 | | 7149 | |
| 7270 | const mod = o.module; | 7150 | const mod = o.module; |
| 7271 | const llvm_field = llvmField(struct_ty, field_index, mod).?; | 7151 | const llvm_field = llvmField(struct_ty, field_index, mod).?; |
| 7272 | const struct_llvm_ty = try o.lowerLlvmType(struct_ty); | 7152 | const struct_llvm_ty = (try o.lowerType(struct_ty)).toLlvm(&o.builder); |
| 7273 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field.index, ""); | 7153 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field.index, ""); |
| 7274 | const field_ptr_ty = try mod.ptrType(.{ | 7154 | const field_ptr_ty = try mod.ptrType(.{ |
| 7275 | .child = llvm_field.ty.toIntern(), | 7155 | .child = llvm_field.ty.toIntern(), |
| ... | @@ -7293,7 +7173,7 @@ pub const FuncGen = struct { | ... | @@ -7293,7 +7173,7 @@ pub const FuncGen = struct { |
| 7293 | if (optional_ty.optionalReprIsPayload(mod)) { | 7173 | if (optional_ty.optionalReprIsPayload(mod)) { |
| 7294 | return operand; | 7174 | return operand; |
| 7295 | } | 7175 | } |
| 7296 | const llvm_optional_ty = try o.lowerLlvmType(optional_ty); | 7176 | const llvm_optional_ty = (try o.lowerType(optional_ty)).toLlvm(&o.builder); |
| 7297 | if (isByRef(optional_ty, mod)) { | 7177 | if (isByRef(optional_ty, mod)) { |
| 7298 | const optional_ptr = self.buildAlloca(llvm_optional_ty, optional_ty.abiAlignment(mod)); | 7178 | const optional_ptr = self.buildAlloca(llvm_optional_ty, optional_ty.abiAlignment(mod)); |
| 7299 | const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, ""); | 7179 | const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, ""); |
| ... | @@ -7317,8 +7197,8 @@ pub const FuncGen = struct { | ... | @@ -7317,8 +7197,8 @@ pub const FuncGen = struct { |
| 7317 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 7197 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 7318 | return operand; | 7198 | return operand; |
| 7319 | } | 7199 | } |
| 7320 | const ok_err_code = (try o.lowerLlvmType(Type.anyerror)).constNull(); | 7200 | const ok_err_code = (try o.lowerType(Type.anyerror)).toLlvm(&o.builder).constNull(); |
| 7321 | const err_un_llvm_ty = try o.lowerLlvmType(err_un_ty); | 7201 | const err_un_llvm_ty = (try o.lowerType(err_un_ty)).toLlvm(&o.builder); |
| 7322 | | 7202 | |
| 7323 | const payload_offset = errUnionPayloadOffset(payload_ty, mod); | 7203 | const payload_offset = errUnionPayloadOffset(payload_ty, mod); |
| 7324 | const error_offset = errUnionErrorOffset(payload_ty, mod); | 7204 | const error_offset = errUnionErrorOffset(payload_ty, mod); |
| ... | @@ -7347,7 +7227,7 @@ pub const FuncGen = struct { | ... | @@ -7347,7 +7227,7 @@ pub const FuncGen = struct { |
| 7347 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 7227 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 7348 | return operand; | 7228 | return operand; |
| 7349 | } | 7229 | } |
| 7350 | const err_un_llvm_ty = try o.lowerLlvmType(err_un_ty); | 7230 | const err_un_llvm_ty = (try o.lowerType(err_un_ty)).toLlvm(&o.builder); |
| 7351 | | 7231 | |
| 7352 | const payload_offset = errUnionPayloadOffset(payload_ty, mod); | 7232 | const payload_offset = errUnionPayloadOffset(payload_ty, mod); |
| 7353 | const error_offset = errUnionErrorOffset(payload_ty, mod); | 7233 | const error_offset = errUnionErrorOffset(payload_ty, mod); |
| ... | @@ -7403,7 +7283,7 @@ pub const FuncGen = struct { | ... | @@ -7403,7 +7283,7 @@ pub const FuncGen = struct { |
| 7403 | const operand = try self.resolveInst(extra.rhs); | 7283 | const operand = try self.resolveInst(extra.rhs); |
| 7404 | | 7284 | |
| 7405 | const loaded_vector = blk: { | 7285 | const loaded_vector = blk: { |
| 7406 | const elem_llvm_ty = try o.lowerLlvmType(vector_ptr_ty.childType(mod)); | 7286 | const elem_llvm_ty = (try o.lowerType(vector_ptr_ty.childType(mod))).toLlvm(&o.builder); |
| 7407 | const load_inst = self.builder.buildLoad(elem_llvm_ty, vector_ptr, ""); | 7287 | const load_inst = self.builder.buildLoad(elem_llvm_ty, vector_ptr, ""); |
| 7408 | load_inst.setAlignment(vector_ptr_ty.ptrAlignment(mod)); | 7288 | load_inst.setAlignment(vector_ptr_ty.ptrAlignment(mod)); |
| 7409 | load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr(mod))); | 7289 | load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr(mod))); |
| ... | @@ -7447,7 +7327,7 @@ pub const FuncGen = struct { | ... | @@ -7447,7 +7327,7 @@ pub const FuncGen = struct { |
| 7447 | const ptr = try self.resolveInst(bin_op.lhs); | 7327 | const ptr = try self.resolveInst(bin_op.lhs); |
| 7448 | const len = try self.resolveInst(bin_op.rhs); | 7328 | const len = try self.resolveInst(bin_op.rhs); |
| 7449 | const inst_ty = self.typeOfIndex(inst); | 7329 | const inst_ty = self.typeOfIndex(inst); |
| 7450 | const llvm_slice_ty = try o.lowerLlvmType(inst_ty); | 7330 | const llvm_slice_ty = (try o.lowerType(inst_ty)).toLlvm(&o.builder); |
| 7451 | | 7331 | |
| 7452 | // In case of slicing a global, the result type looks something like `{ i8*, i64 }` | 7332 | // In case of slicing a global, the result type looks something like `{ i8*, i64 }` |
| 7453 | // but `ptr` is pointing to the global directly. | 7333 | // but `ptr` is pointing to the global directly. |
| ... | @@ -7491,7 +7371,7 @@ pub const FuncGen = struct { | ... | @@ -7491,7 +7371,7 @@ pub const FuncGen = struct { |
| 7491 | true => signed_intrinsic, | 7371 | true => signed_intrinsic, |
| 7492 | false => unsigned_intrinsic, | 7372 | false => unsigned_intrinsic, |
| 7493 | }; | 7373 | }; |
| 7494 | const llvm_inst_ty = try o.lowerLlvmType(inst_ty); | 7374 | const llvm_inst_ty = (try o.lowerType(inst_ty)).toLlvm(&o.builder); |
| 7495 | const llvm_fn = fg.getIntrinsic(intrinsic_name, &.{llvm_inst_ty}); | 7375 | const llvm_fn = fg.getIntrinsic(intrinsic_name, &.{llvm_inst_ty}); |
| 7496 | const result_struct = fg.builder.buildCall( | 7376 | const result_struct = fg.builder.buildCall( |
| 7497 | llvm_fn.globalGetValueType(), | 7377 | llvm_fn.globalGetValueType(), |
| ... | @@ -7664,11 +7544,11 @@ pub const FuncGen = struct { | ... | @@ -7664,11 +7544,11 @@ pub const FuncGen = struct { |
| 7664 | return self.buildFloatOp(.floor, inst_ty, 1, .{result}); | 7544 | return self.buildFloatOp(.floor, inst_ty, 1, .{result}); |
| 7665 | } | 7545 | } |
| 7666 | if (scalar_ty.isSignedInt(mod)) { | 7546 | if (scalar_ty.isSignedInt(mod)) { |
| 7667 | const inst_llvm_ty = try o.lowerLlvmType(inst_ty); | 7547 | const inst_llvm_ty = (try o.lowerType(inst_ty)).toLlvm(&o.builder); |
| 7668 | const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1; | 7548 | const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1; |
| 7669 | const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: { | 7549 | const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: { |
| 7670 | const vec_len = inst_ty.vectorLen(mod); | 7550 | const vec_len = inst_ty.vectorLen(mod); |
| 7671 | const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty); | 7551 | const scalar_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder); |
| 7672 | | 7552 | |
| 7673 | const shifts = try self.gpa.alloc(*llvm.Value, vec_len); | 7553 | const shifts = try self.gpa.alloc(*llvm.Value, vec_len); |
| 7674 | defer self.gpa.free(shifts); | 7554 | defer self.gpa.free(shifts); |
| ... | @@ -7730,7 +7610,7 @@ pub const FuncGen = struct { | ... | @@ -7730,7 +7610,7 @@ pub const FuncGen = struct { |
| 7730 | const lhs = try self.resolveInst(bin_op.lhs); | 7610 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7731 | const rhs = try self.resolveInst(bin_op.rhs); | 7611 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7732 | const inst_ty = self.typeOfIndex(inst); | 7612 | const inst_ty = self.typeOfIndex(inst); |
| 7733 | const inst_llvm_ty = try o.lowerLlvmType(inst_ty); | 7613 | const inst_llvm_ty = (try o.lowerType(inst_ty)).toLlvm(&o.builder); |
| 7734 | const scalar_ty = inst_ty.scalarType(mod); | 7614 | const scalar_ty = inst_ty.scalarType(mod); |
| 7735 | | 7615 | |
| 7736 | if (scalar_ty.isRuntimeFloat()) { | 7616 | if (scalar_ty.isRuntimeFloat()) { |
| ... | @@ -7745,7 +7625,7 @@ pub const FuncGen = struct { | ... | @@ -7745,7 +7625,7 @@ pub const FuncGen = struct { |
| 7745 | const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1; | 7625 | const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1; |
| 7746 | const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: { | 7626 | const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: { |
| 7747 | const vec_len = inst_ty.vectorLen(mod); | 7627 | const vec_len = inst_ty.vectorLen(mod); |
| 7748 | const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty); | 7628 | const scalar_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder); |
| 7749 | | 7629 | |
| 7750 | const shifts = try self.gpa.alloc(*llvm.Value, vec_len); | 7630 | const shifts = try self.gpa.alloc(*llvm.Value, vec_len); |
| 7751 | defer self.gpa.free(shifts); | 7631 | defer self.gpa.free(shifts); |
| ... | @@ -7774,7 +7654,7 @@ pub const FuncGen = struct { | ... | @@ -7774,7 +7654,7 @@ pub const FuncGen = struct { |
| 7774 | const ptr = try self.resolveInst(bin_op.lhs); | 7654 | const ptr = try self.resolveInst(bin_op.lhs); |
| 7775 | const offset = try self.resolveInst(bin_op.rhs); | 7655 | const offset = try self.resolveInst(bin_op.rhs); |
| 7776 | const ptr_ty = self.typeOf(bin_op.lhs); | 7656 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 7777 | const llvm_elem_ty = try o.lowerPtrElemTy(ptr_ty.childType(mod)); | 7657 | const llvm_elem_ty = (try o.lowerPtrElemTy(ptr_ty.childType(mod))).toLlvm(&o.builder); |
| 7778 | switch (ptr_ty.ptrSize(mod)) { | 7658 | switch (ptr_ty.ptrSize(mod)) { |
| 7779 | .One => { | 7659 | .One => { |
| 7780 | // It's a pointer to an array, so according to LLVM we need an extra GEP index. | 7660 | // It's a pointer to an array, so according to LLVM we need an extra GEP index. |
| ... | @@ -7802,7 +7682,7 @@ pub const FuncGen = struct { | ... | @@ -7802,7 +7682,7 @@ pub const FuncGen = struct { |
| 7802 | const offset = try self.resolveInst(bin_op.rhs); | 7682 | const offset = try self.resolveInst(bin_op.rhs); |
| 7803 | const negative_offset = self.builder.buildNeg(offset, ""); | 7683 | const negative_offset = self.builder.buildNeg(offset, ""); |
| 7804 | const ptr_ty = self.typeOf(bin_op.lhs); | 7684 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 7805 | const llvm_elem_ty = try o.lowerPtrElemTy(ptr_ty.childType(mod)); | 7685 | const llvm_elem_ty = (try o.lowerPtrElemTy(ptr_ty.childType(mod))).toLlvm(&o.builder); |
| 7806 | switch (ptr_ty.ptrSize(mod)) { | 7686 | switch (ptr_ty.ptrSize(mod)) { |
| 7807 | .One => { | 7687 | .One => { |
| 7808 | // It's a pointer to an array, so according to LLVM we need an extra GEP index. | 7688 | // It's a pointer to an array, so according to LLVM we need an extra GEP index. |
| ... | @@ -7843,8 +7723,8 @@ pub const FuncGen = struct { | ... | @@ -7843,8 +7723,8 @@ pub const FuncGen = struct { |
| 7843 | | 7723 | |
| 7844 | const intrinsic_name = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic; | 7724 | const intrinsic_name = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic; |
| 7845 | | 7725 | |
| 7846 | const llvm_lhs_ty = try o.lowerLlvmType(lhs_ty); | 7726 | const llvm_lhs_ty = (try o.lowerType(lhs_ty)).toLlvm(&o.builder); |
| 7847 | const llvm_dest_ty = try o.lowerLlvmType(dest_ty); | 7727 | const llvm_dest_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder); |
| 7848 | | 7728 | |
| 7849 | const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty}); | 7729 | const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty}); |
| 7850 | const result_struct = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &[_]*llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, ""); | 7730 | const result_struct = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &[_]*llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, ""); |
| ... | @@ -7920,7 +7800,7 @@ pub const FuncGen = struct { | ... | @@ -7920,7 +7800,7 @@ pub const FuncGen = struct { |
| 7920 | const f = o.llvm_module.addFunction(name.toSlice(&o.builder).?, fn_type); | 7800 | const f = o.llvm_module.addFunction(name.toSlice(&o.builder).?, fn_type); |
| 7921 | | 7801 | |
| 7922 | var global = Builder.Global{ | 7802 | var global = Builder.Global{ |
| 7923 | .type = .void, | 7803 | .type = try o.builder.fnType(.void, &.{}, .normal), |
| 7924 | .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) }, | 7804 | .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) }, |
| 7925 | }; | 7805 | }; |
| 7926 | var function = Builder.Function{ | 7806 | var function = Builder.Function{ |
| ... | @@ -7947,7 +7827,7 @@ pub const FuncGen = struct { | ... | @@ -7947,7 +7827,7 @@ pub const FuncGen = struct { |
| 7947 | const mod = o.module; | 7827 | const mod = o.module; |
| 7948 | const target = o.module.getTarget(); | 7828 | const target = o.module.getTarget(); |
| 7949 | const scalar_ty = ty.scalarType(mod); | 7829 | const scalar_ty = ty.scalarType(mod); |
| 7950 | const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty); | 7830 | const scalar_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder); |
| 7951 | | 7831 | |
| 7952 | if (intrinsicsAllowed(scalar_ty, target)) { | 7832 | if (intrinsicsAllowed(scalar_ty, target)) { |
| 7953 | const llvm_predicate: llvm.RealPredicate = switch (pred) { | 7833 | const llvm_predicate: llvm.RealPredicate = switch (pred) { |
| ... | @@ -8050,8 +7930,8 @@ pub const FuncGen = struct { | ... | @@ -8050,8 +7930,8 @@ pub const FuncGen = struct { |
| 8050 | const mod = o.module; | 7930 | const mod = o.module; |
| 8051 | const target = mod.getTarget(); | 7931 | const target = mod.getTarget(); |
| 8052 | const scalar_ty = ty.scalarType(mod); | 7932 | const scalar_ty = ty.scalarType(mod); |
| 8053 | const llvm_ty = try o.lowerLlvmType(ty); | 7933 | const llvm_ty = (try o.lowerType(ty)).toLlvm(&o.builder); |
| 8054 | const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty); | 7934 | const scalar_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder); |
| 8055 | | 7935 | |
| 8056 | const intrinsics_allowed = op != .tan and intrinsicsAllowed(scalar_ty, target); | 7936 | const intrinsics_allowed = op != .tan and intrinsicsAllowed(scalar_ty, target); |
| 8057 | var fn_name_buf: [64]u8 = undefined; | 7937 | var fn_name_buf: [64]u8 = undefined; |
| ... | @@ -8161,10 +8041,10 @@ pub const FuncGen = struct { | ... | @@ -8161,10 +8041,10 @@ pub const FuncGen = struct { |
| 8161 | const rhs_scalar_ty = rhs_ty.scalarType(mod); | 8041 | const rhs_scalar_ty = rhs_ty.scalarType(mod); |
| 8162 | | 8042 | |
| 8163 | const dest_ty = self.typeOfIndex(inst); | 8043 | const dest_ty = self.typeOfIndex(inst); |
| 8164 | const llvm_dest_ty = try o.lowerLlvmType(dest_ty); | 8044 | const llvm_dest_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder); |
| 8165 | | 8045 | |
| 8166 | const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod)) | 8046 | const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod)) |
| 8167 | self.builder.buildZExt(rhs, try o.lowerLlvmType(lhs_ty), "") | 8047 | self.builder.buildZExt(rhs, (try o.lowerType(lhs_ty)).toLlvm(&o.builder), "") |
| 8168 | else | 8048 | else |
| 8169 | rhs; | 8049 | rhs; |
| 8170 | | 8050 | |
| ... | @@ -8235,7 +8115,7 @@ pub const FuncGen = struct { | ... | @@ -8235,7 +8115,7 @@ pub const FuncGen = struct { |
| 8235 | const rhs_scalar_ty = rhs_ty.scalarType(mod); | 8115 | const rhs_scalar_ty = rhs_ty.scalarType(mod); |
| 8236 | | 8116 | |
| 8237 | const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod)) | 8117 | const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod)) |
| 8238 | self.builder.buildZExt(rhs, try o.lowerLlvmType(lhs_ty), "") | 8118 | self.builder.buildZExt(rhs, (try o.lowerType(lhs_ty)).toLlvm(&o.builder), "") |
| 8239 | else | 8119 | else |
| 8240 | rhs; | 8120 | rhs; |
| 8241 | if (lhs_scalar_ty.isSignedInt(mod)) return self.builder.buildNSWShl(lhs, casted_rhs, ""); | 8121 | if (lhs_scalar_ty.isSignedInt(mod)) return self.builder.buildNSWShl(lhs, casted_rhs, ""); |
| ... | @@ -8256,7 +8136,7 @@ pub const FuncGen = struct { | ... | @@ -8256,7 +8136,7 @@ pub const FuncGen = struct { |
| 8256 | const rhs_scalar_ty = rhs_type.scalarType(mod); | 8136 | const rhs_scalar_ty = rhs_type.scalarType(mod); |
| 8257 | | 8137 | |
| 8258 | const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod)) | 8138 | const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod)) |
| 8259 | self.builder.buildZExt(rhs, try o.lowerLlvmType(lhs_type), "") | 8139 | self.builder.buildZExt(rhs, (try o.lowerType(lhs_type)).toLlvm(&o.builder), "") |
| 8260 | else | 8140 | else |
| 8261 | rhs; | 8141 | rhs; |
| 8262 | return self.builder.buildShl(lhs, casted_rhs, ""); | 8142 | return self.builder.buildShl(lhs, casted_rhs, ""); |
| ... | @@ -8291,7 +8171,7 @@ pub const FuncGen = struct { | ... | @@ -8291,7 +8171,7 @@ pub const FuncGen = struct { |
| 8291 | // poison value." | 8171 | // poison value." |
| 8292 | // However Zig semantics says that saturating shift left can never produce | 8172 | // However Zig semantics says that saturating shift left can never produce |
| 8293 | // undefined; instead it saturates. | 8173 | // undefined; instead it saturates. |
| 8294 | const lhs_scalar_llvm_ty = try o.lowerLlvmType(lhs_scalar_ty); | 8174 | const lhs_scalar_llvm_ty = (try o.lowerType(lhs_scalar_ty)).toLlvm(&o.builder); |
| 8295 | const bits = lhs_scalar_llvm_ty.constInt(lhs_bits, .False); | 8175 | const bits = lhs_scalar_llvm_ty.constInt(lhs_bits, .False); |
| 8296 | const lhs_max = lhs_scalar_llvm_ty.constAllOnes(); | 8176 | const lhs_max = lhs_scalar_llvm_ty.constAllOnes(); |
| 8297 | if (rhs_ty.zigTypeTag(mod) == .Vector) { | 8177 | if (rhs_ty.zigTypeTag(mod) == .Vector) { |
| ... | @@ -8320,7 +8200,7 @@ pub const FuncGen = struct { | ... | @@ -8320,7 +8200,7 @@ pub const FuncGen = struct { |
| 8320 | const rhs_scalar_ty = rhs_ty.scalarType(mod); | 8200 | const rhs_scalar_ty = rhs_ty.scalarType(mod); |
| 8321 | | 8201 | |
| 8322 | const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod)) | 8202 | const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod)) |
| 8323 | self.builder.buildZExt(rhs, try o.lowerLlvmType(lhs_ty), "") | 8203 | self.builder.buildZExt(rhs, (try o.lowerType(lhs_ty)).toLlvm(&o.builder), "") |
| 8324 | else | 8204 | else |
| 8325 | rhs; | 8205 | rhs; |
| 8326 | const is_signed_int = lhs_scalar_ty.isSignedInt(mod); | 8206 | const is_signed_int = lhs_scalar_ty.isSignedInt(mod); |
| ... | @@ -8346,7 +8226,7 @@ pub const FuncGen = struct { | ... | @@ -8346,7 +8226,7 @@ pub const FuncGen = struct { |
| 8346 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 8226 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 8347 | const dest_ty = self.typeOfIndex(inst); | 8227 | const dest_ty = self.typeOfIndex(inst); |
| 8348 | const dest_info = dest_ty.intInfo(mod); | 8228 | const dest_info = dest_ty.intInfo(mod); |
| 8349 | const dest_llvm_ty = try o.lowerLlvmType(dest_ty); | 8229 | const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder); |
| 8350 | const operand = try self.resolveInst(ty_op.operand); | 8230 | const operand = try self.resolveInst(ty_op.operand); |
| 8351 | const operand_ty = self.typeOf(ty_op.operand); | 8231 | const operand_ty = self.typeOf(ty_op.operand); |
| 8352 | const operand_info = operand_ty.intInfo(mod); | 8232 | const operand_info = operand_ty.intInfo(mod); |
| ... | @@ -8367,7 +8247,7 @@ pub const FuncGen = struct { | ... | @@ -8367,7 +8247,7 @@ pub const FuncGen = struct { |
| 8367 | const o = self.dg.object; | 8247 | const o = self.dg.object; |
| 8368 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 8248 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 8369 | const operand = try self.resolveInst(ty_op.operand); | 8249 | const operand = try self.resolveInst(ty_op.operand); |
| 8370 | const dest_llvm_ty = try o.lowerLlvmType(self.typeOfIndex(inst)); | 8250 | const dest_llvm_ty = (try o.lowerType(self.typeOfIndex(inst))).toLlvm(&o.builder); |
| 8371 | return self.builder.buildTrunc(operand, dest_llvm_ty, ""); | 8251 | return self.builder.buildTrunc(operand, dest_llvm_ty, ""); |
| 8372 | } | 8252 | } |
| 8373 | | 8253 | |
| ... | @@ -8383,11 +8263,11 @@ pub const FuncGen = struct { | ... | @@ -8383,11 +8263,11 @@ pub const FuncGen = struct { |
| 8383 | const src_bits = operand_ty.floatBits(target); | 8263 | const src_bits = operand_ty.floatBits(target); |
| 8384 | | 8264 | |
| 8385 | if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) { | 8265 | if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) { |
| 8386 | const dest_llvm_ty = try o.lowerLlvmType(dest_ty); | 8266 | const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder); |
| 8387 | return self.builder.buildFPTrunc(operand, dest_llvm_ty, ""); | 8267 | return self.builder.buildFPTrunc(operand, dest_llvm_ty, ""); |
| 8388 | } else { | 8268 | } else { |
| 8389 | const operand_llvm_ty = try o.lowerLlvmType(operand_ty); | 8269 | const operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder); |
| 8390 | const dest_llvm_ty = try o.lowerLlvmType(dest_ty); | 8270 | const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder); |
| 8391 | | 8271 | |
| 8392 | var fn_name_buf: [64]u8 = undefined; | 8272 | var fn_name_buf: [64]u8 = undefined; |
| 8393 | const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__trunc{s}f{s}f2", .{ | 8273 | const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__trunc{s}f{s}f2", .{ |
| ... | @@ -8414,11 +8294,11 @@ pub const FuncGen = struct { | ... | @@ -8414,11 +8294,11 @@ pub const FuncGen = struct { |
| 8414 | const src_bits = operand_ty.floatBits(target); | 8294 | const src_bits = operand_ty.floatBits(target); |
| 8415 | | 8295 | |
| 8416 | if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) { | 8296 | if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) { |
| 8417 | const dest_llvm_ty = try o.lowerLlvmType(dest_ty); | 8297 | const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder); |
| 8418 | return self.builder.buildFPExt(operand, dest_llvm_ty, ""); | 8298 | return self.builder.buildFPExt(operand, dest_llvm_ty, ""); |
| 8419 | } else { | 8299 | } else { |
| 8420 | const operand_llvm_ty = try o.lowerLlvmType(operand_ty); | 8300 | const operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder); |
| 8421 | const dest_llvm_ty = try o.lowerLlvmType(dest_ty); | 8301 | const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder); |
| 8422 | | 8302 | |
| 8423 | var fn_name_buf: [64]u8 = undefined; | 8303 | var fn_name_buf: [64]u8 = undefined; |
| 8424 | const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__extend{s}f{s}f2", .{ | 8304 | const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__extend{s}f{s}f2", .{ |
| ... | @@ -8439,7 +8319,7 @@ pub const FuncGen = struct { | ... | @@ -8439,7 +8319,7 @@ pub const FuncGen = struct { |
| 8439 | const operand = try self.resolveInst(un_op); | 8319 | const operand = try self.resolveInst(un_op); |
| 8440 | const ptr_ty = self.typeOf(un_op); | 8320 | const ptr_ty = self.typeOf(un_op); |
| 8441 | const operand_ptr = self.sliceOrArrayPtr(operand, ptr_ty); | 8321 | const operand_ptr = self.sliceOrArrayPtr(operand, ptr_ty); |
| 8442 | const dest_llvm_ty = try o.lowerLlvmType(self.typeOfIndex(inst)); | 8322 | const dest_llvm_ty = (try o.lowerType(self.typeOfIndex(inst))).toLlvm(&o.builder); |
| 8443 | return self.builder.buildPtrToInt(operand_ptr, dest_llvm_ty, ""); | 8323 | return self.builder.buildPtrToInt(operand_ptr, dest_llvm_ty, ""); |
| 8444 | } | 8324 | } |
| 8445 | | 8325 | |
| ... | @@ -8456,7 +8336,7 @@ pub const FuncGen = struct { | ... | @@ -8456,7 +8336,7 @@ pub const FuncGen = struct { |
| 8456 | const mod = o.module; | 8336 | const mod = o.module; |
| 8457 | const operand_is_ref = isByRef(operand_ty, mod); | 8337 | const operand_is_ref = isByRef(operand_ty, mod); |
| 8458 | const result_is_ref = isByRef(inst_ty, mod); | 8338 | const result_is_ref = isByRef(inst_ty, mod); |
| 8459 | const llvm_dest_ty = try o.lowerLlvmType(inst_ty); | 8339 | const llvm_dest_ty = (try o.lowerType(inst_ty)).toLlvm(&o.builder); |
| 8460 | | 8340 | |
| 8461 | if (operand_is_ref and result_is_ref) { | 8341 | if (operand_is_ref and result_is_ref) { |
| 8462 | // They are both pointers, so just return the same opaque pointer :) | 8342 | // They are both pointers, so just return the same opaque pointer :) |
| ... | @@ -8486,7 +8366,7 @@ pub const FuncGen = struct { | ... | @@ -8486,7 +8366,7 @@ pub const FuncGen = struct { |
| 8486 | } else { | 8366 | } else { |
| 8487 | // If the ABI size of the element type is not evenly divisible by size in bits; | 8367 | // If the ABI size of the element type is not evenly divisible by size in bits; |
| 8488 | // a simple bitcast will not work, and we fall back to extractelement. | 8368 | // a simple bitcast will not work, and we fall back to extractelement. |
| 8489 | const llvm_usize = try o.lowerLlvmType(Type.usize); | 8369 | const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder); |
| 8490 | const llvm_u32 = self.context.intType(32); | 8370 | const llvm_u32 = self.context.intType(32); |
| 8491 | const zero = llvm_usize.constNull(); | 8371 | const zero = llvm_usize.constNull(); |
| 8492 | const vector_len = operand_ty.arrayLen(mod); | 8372 | const vector_len = operand_ty.arrayLen(mod); |
| ... | @@ -8503,7 +8383,7 @@ pub const FuncGen = struct { | ... | @@ -8503,7 +8383,7 @@ pub const FuncGen = struct { |
| 8503 | return array_ptr; | 8383 | return array_ptr; |
| 8504 | } else if (operand_ty.zigTypeTag(mod) == .Array and inst_ty.zigTypeTag(mod) == .Vector) { | 8384 | } else if (operand_ty.zigTypeTag(mod) == .Array and inst_ty.zigTypeTag(mod) == .Vector) { |
| 8505 | const elem_ty = operand_ty.childType(mod); | 8385 | const elem_ty = operand_ty.childType(mod); |
| 8506 | const llvm_vector_ty = try o.lowerLlvmType(inst_ty); | 8386 | const llvm_vector_ty = (try o.lowerType(inst_ty)).toLlvm(&o.builder); |
| 8507 | if (!operand_is_ref) { | 8387 | if (!operand_is_ref) { |
| 8508 | return self.dg.todo("implement bitcast non-ref array to vector", .{}); | 8388 | return self.dg.todo("implement bitcast non-ref array to vector", .{}); |
| 8509 | } | 8389 | } |
| ... | @@ -8518,9 +8398,9 @@ pub const FuncGen = struct { | ... | @@ -8518,9 +8398,9 @@ pub const FuncGen = struct { |
| 8518 | } else { | 8398 | } else { |
| 8519 | // If the ABI size of the element type is not evenly divisible by size in bits; | 8399 | // If the ABI size of the element type is not evenly divisible by size in bits; |
| 8520 | // a simple bitcast will not work, and we fall back to extractelement. | 8400 | // a simple bitcast will not work, and we fall back to extractelement. |
| 8521 | const array_llvm_ty = try o.lowerLlvmType(operand_ty); | 8401 | const array_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder); |
| 8522 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); | 8402 | const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder); |
| 8523 | const llvm_usize = try o.lowerLlvmType(Type.usize); | 8403 | const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder); |
| 8524 | const llvm_u32 = self.context.intType(32); | 8404 | const llvm_u32 = self.context.intType(32); |
| 8525 | const zero = llvm_usize.constNull(); | 8405 | const zero = llvm_usize.constNull(); |
| 8526 | const vector_len = operand_ty.arrayLen(mod); | 8406 | const vector_len = operand_ty.arrayLen(mod); |
| ... | @@ -8629,7 +8509,7 @@ pub const FuncGen = struct { | ... | @@ -8629,7 +8509,7 @@ pub const FuncGen = struct { |
| 8629 | if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) | 8509 | if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) |
| 8630 | return o.lowerPtrToVoid(ptr_ty); | 8510 | return o.lowerPtrToVoid(ptr_ty); |
| 8631 | | 8511 | |
| 8632 | const pointee_llvm_ty = try o.lowerLlvmType(pointee_type); | 8512 | const pointee_llvm_ty = (try o.lowerType(pointee_type)).toLlvm(&o.builder); |
| 8633 | const alignment = ptr_ty.ptrAlignment(mod); | 8513 | const alignment = ptr_ty.ptrAlignment(mod); |
| 8634 | return self.buildAlloca(pointee_llvm_ty, alignment); | 8514 | return self.buildAlloca(pointee_llvm_ty, alignment); |
| 8635 | } | 8515 | } |
| ... | @@ -8641,7 +8521,7 @@ pub const FuncGen = struct { | ... | @@ -8641,7 +8521,7 @@ pub const FuncGen = struct { |
| 8641 | const ret_ty = ptr_ty.childType(mod); | 8521 | const ret_ty = ptr_ty.childType(mod); |
| 8642 | if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return o.lowerPtrToVoid(ptr_ty); | 8522 | if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return o.lowerPtrToVoid(ptr_ty); |
| 8643 | if (self.ret_ptr) |ret_ptr| return ret_ptr; | 8523 | if (self.ret_ptr) |ret_ptr| return ret_ptr; |
| 8644 | const ret_llvm_ty = try o.lowerLlvmType(ret_ty); | 8524 | const ret_llvm_ty = (try o.lowerType(ret_ty)).toLlvm(&o.builder); |
| 8645 | return self.buildAlloca(ret_llvm_ty, ptr_ty.ptrAlignment(mod)); | 8525 | return self.buildAlloca(ret_llvm_ty, ptr_ty.ptrAlignment(mod)); |
| 8646 | } | 8526 | } |
| 8647 | | 8527 | |
| ... | @@ -8673,7 +8553,7 @@ pub const FuncGen = struct { | ... | @@ -8673,7 +8553,7 @@ pub const FuncGen = struct { |
| 8673 | else | 8553 | else |
| 8674 | u8_llvm_ty.getUndef(); | 8554 | u8_llvm_ty.getUndef(); |
| 8675 | const operand_size = operand_ty.abiSize(mod); | 8555 | const operand_size = operand_ty.abiSize(mod); |
| 8676 | const usize_llvm_ty = try o.lowerLlvmType(Type.usize); | 8556 | const usize_llvm_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder); |
| 8677 | const len = usize_llvm_ty.constInt(operand_size, .False); | 8557 | const len = usize_llvm_ty.constInt(operand_size, .False); |
| 8678 | const dest_ptr_align = ptr_ty.ptrAlignment(mod); | 8558 | const dest_ptr_align = ptr_ty.ptrAlignment(mod); |
| 8679 | _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr(mod)); | 8559 | _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr(mod)); |
| ... | @@ -8746,7 +8626,7 @@ pub const FuncGen = struct { | ... | @@ -8746,7 +8626,7 @@ pub const FuncGen = struct { |
| 8746 | _ = inst; | 8626 | _ = inst; |
| 8747 | const o = self.dg.object; | 8627 | const o = self.dg.object; |
| 8748 | const mod = o.module; | 8628 | const mod = o.module; |
| 8749 | const llvm_usize = try o.lowerLlvmType(Type.usize); | 8629 | const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder); |
| 8750 | const target = mod.getTarget(); | 8630 | const target = mod.getTarget(); |
| 8751 | if (!target_util.supportsReturnAddress(target)) { | 8631 | if (!target_util.supportsReturnAddress(target)) { |
| 8752 | // https://github.com/ziglang/zig/issues/11946 | 8632 | // https://github.com/ziglang/zig/issues/11946 |
| ... | @@ -8774,7 +8654,7 @@ pub const FuncGen = struct { | ... | @@ -8774,7 +8654,7 @@ pub const FuncGen = struct { |
| 8774 | | 8654 | |
| 8775 | const params = [_]*llvm.Value{llvm_i32.constNull()}; | 8655 | const params = [_]*llvm.Value{llvm_i32.constNull()}; |
| 8776 | const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, ""); | 8656 | const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, ""); |
| 8777 | const llvm_usize = try o.lowerLlvmType(Type.usize); | 8657 | const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder); |
| 8778 | return self.builder.buildPtrToInt(ptr_val, llvm_usize, ""); | 8658 | return self.builder.buildPtrToInt(ptr_val, llvm_usize, ""); |
| 8779 | } | 8659 | } |
| 8780 | | 8660 | |
| ... | @@ -8795,15 +8675,16 @@ pub const FuncGen = struct { | ... | @@ -8795,15 +8675,16 @@ pub const FuncGen = struct { |
| 8795 | var expected_value = try self.resolveInst(extra.expected_value); | 8675 | var expected_value = try self.resolveInst(extra.expected_value); |
| 8796 | var new_value = try self.resolveInst(extra.new_value); | 8676 | var new_value = try self.resolveInst(extra.new_value); |
| 8797 | const operand_ty = self.typeOf(extra.ptr).childType(mod); | 8677 | const operand_ty = self.typeOf(extra.ptr).childType(mod); |
| 8798 | const opt_abi_ty = o.getAtomicAbiType(operand_ty, false); | 8678 | const abi_ty = try o.getAtomicAbiType(operand_ty, false); |
| 8799 | if (opt_abi_ty) |abi_ty| { | 8679 | if (abi_ty != .none) { |
| | 8680 | const llvm_abi_ty = abi_ty.toLlvm(&o.builder); |
| 8800 | // operand needs widening and truncating | 8681 | // operand needs widening and truncating |
| 8801 | if (operand_ty.isSignedInt(mod)) { | 8682 | if (operand_ty.isSignedInt(mod)) { |
| 8802 | expected_value = self.builder.buildSExt(expected_value, abi_ty, ""); | 8683 | expected_value = self.builder.buildSExt(expected_value, llvm_abi_ty, ""); |
| 8803 | new_value = self.builder.buildSExt(new_value, abi_ty, ""); | 8684 | new_value = self.builder.buildSExt(new_value, llvm_abi_ty, ""); |
| 8804 | } else { | 8685 | } else { |
| 8805 | expected_value = self.builder.buildZExt(expected_value, abi_ty, ""); | 8686 | expected_value = self.builder.buildZExt(expected_value, llvm_abi_ty, ""); |
| 8806 | new_value = self.builder.buildZExt(new_value, abi_ty, ""); | 8687 | new_value = self.builder.buildZExt(new_value, llvm_abi_ty, ""); |
| 8807 | } | 8688 | } |
| 8808 | } | 8689 | } |
| 8809 | const result = self.builder.buildAtomicCmpXchg( | 8690 | const result = self.builder.buildAtomicCmpXchg( |
| ... | @@ -8819,8 +8700,8 @@ pub const FuncGen = struct { | ... | @@ -8819,8 +8700,8 @@ pub const FuncGen = struct { |
| 8819 | const optional_ty = self.typeOfIndex(inst); | 8700 | const optional_ty = self.typeOfIndex(inst); |
| 8820 | | 8701 | |
| 8821 | var payload = self.builder.buildExtractValue(result, 0, ""); | 8702 | var payload = self.builder.buildExtractValue(result, 0, ""); |
| 8822 | if (opt_abi_ty != null) { | 8703 | if (abi_ty != .none) { |
| 8823 | payload = self.builder.buildTrunc(payload, try o.lowerLlvmType(operand_ty), ""); | 8704 | payload = self.builder.buildTrunc(payload, (try o.lowerType(operand_ty)).toLlvm(&o.builder), ""); |
| 8824 | } | 8705 | } |
| 8825 | const success_bit = self.builder.buildExtractValue(result, 1, ""); | 8706 | const success_bit = self.builder.buildExtractValue(result, 1, ""); |
| 8826 | | 8707 | |
| ... | @@ -8848,15 +8729,16 @@ pub const FuncGen = struct { | ... | @@ -8848,15 +8729,16 @@ pub const FuncGen = struct { |
| 8848 | const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float); | 8729 | const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float); |
| 8849 | const ordering = toLlvmAtomicOrdering(extra.ordering()); | 8730 | const ordering = toLlvmAtomicOrdering(extra.ordering()); |
| 8850 | const single_threaded = llvm.Bool.fromBool(self.single_threaded); | 8731 | const single_threaded = llvm.Bool.fromBool(self.single_threaded); |
| 8851 | const opt_abi_ty = o.getAtomicAbiType(operand_ty, op == .Xchg); | 8732 | const abi_ty = try o.getAtomicAbiType(operand_ty, op == .Xchg); |
| 8852 | if (opt_abi_ty) |abi_ty| { | 8733 | if (abi_ty != .none) { |
| | 8734 | const llvm_abi_ty = abi_ty.toLlvm(&o.builder); |
| 8853 | // operand needs widening and truncating or bitcasting. | 8735 | // operand needs widening and truncating or bitcasting. |
| 8854 | const casted_operand = if (is_float) | 8736 | const casted_operand = if (is_float) |
| 8855 | self.builder.buildBitCast(operand, abi_ty, "") | 8737 | self.builder.buildBitCast(operand, llvm_abi_ty, "") |
| 8856 | else if (is_signed_int) | 8738 | else if (is_signed_int) |
| 8857 | self.builder.buildSExt(operand, abi_ty, "") | 8739 | self.builder.buildSExt(operand, llvm_abi_ty, "") |
| 8858 | else | 8740 | else |
| 8859 | self.builder.buildZExt(operand, abi_ty, ""); | 8741 | self.builder.buildZExt(operand, llvm_abi_ty, ""); |
| 8860 | | 8742 | |
| 8861 | const uncasted_result = self.builder.buildAtomicRmw( | 8743 | const uncasted_result = self.builder.buildAtomicRmw( |
| 8862 | op, | 8744 | op, |
| ... | @@ -8865,7 +8747,7 @@ pub const FuncGen = struct { | ... | @@ -8865,7 +8747,7 @@ pub const FuncGen = struct { |
| 8865 | ordering, | 8747 | ordering, |
| 8866 | single_threaded, | 8748 | single_threaded, |
| 8867 | ); | 8749 | ); |
| 8868 | const operand_llvm_ty = try o.lowerLlvmType(operand_ty); | 8750 | const operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder); |
| 8869 | if (is_float) { | 8751 | if (is_float) { |
| 8870 | return self.builder.buildBitCast(uncasted_result, operand_llvm_ty, ""); | 8752 | return self.builder.buildBitCast(uncasted_result, operand_llvm_ty, ""); |
| 8871 | } else { | 8753 | } else { |
| ... | @@ -8878,7 +8760,7 @@ pub const FuncGen = struct { | ... | @@ -8878,7 +8760,7 @@ pub const FuncGen = struct { |
| 8878 | } | 8760 | } |
| 8879 | | 8761 | |
| 8880 | // It's a pointer but we need to treat it as an int. | 8762 | // It's a pointer but we need to treat it as an int. |
| 8881 | const usize_llvm_ty = try o.lowerLlvmType(Type.usize); | 8763 | const usize_llvm_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder); |
| 8882 | const casted_operand = self.builder.buildPtrToInt(operand, usize_llvm_ty, ""); | 8764 | const casted_operand = self.builder.buildPtrToInt(operand, usize_llvm_ty, ""); |
| 8883 | const uncasted_result = self.builder.buildAtomicRmw( | 8765 | const uncasted_result = self.builder.buildAtomicRmw( |
| 8884 | op, | 8766 | op, |
| ... | @@ -8887,7 +8769,7 @@ pub const FuncGen = struct { | ... | @@ -8887,7 +8769,7 @@ pub const FuncGen = struct { |
| 8887 | ordering, | 8769 | ordering, |
| 8888 | single_threaded, | 8770 | single_threaded, |
| 8889 | ); | 8771 | ); |
| 8890 | const operand_llvm_ty = try o.lowerLlvmType(operand_ty); | 8772 | const operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder); |
| 8891 | return self.builder.buildIntToPtr(uncasted_result, operand_llvm_ty, ""); | 8773 | return self.builder.buildIntToPtr(uncasted_result, operand_llvm_ty, ""); |
| 8892 | } | 8774 | } |
| 8893 | | 8775 | |
| ... | @@ -8902,15 +8784,16 @@ pub const FuncGen = struct { | ... | @@ -8902,15 +8784,16 @@ pub const FuncGen = struct { |
| 8902 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) | 8784 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) |
| 8903 | return null; | 8785 | return null; |
| 8904 | const ordering = toLlvmAtomicOrdering(atomic_load.order); | 8786 | const ordering = toLlvmAtomicOrdering(atomic_load.order); |
| 8905 | const opt_abi_llvm_ty = o.getAtomicAbiType(elem_ty, false); | 8787 | const abi_ty = try o.getAtomicAbiType(elem_ty, false); |
| 8906 | const ptr_alignment = @as(u32, @intCast(ptr_info.flags.alignment.toByteUnitsOptional() orelse | 8788 | const ptr_alignment = @as(u32, @intCast(ptr_info.flags.alignment.toByteUnitsOptional() orelse |
| 8907 | ptr_info.child.toType().abiAlignment(mod))); | 8789 | ptr_info.child.toType().abiAlignment(mod))); |
| 8908 | const ptr_volatile = llvm.Bool.fromBool(ptr_info.flags.is_volatile); | 8790 | const ptr_volatile = llvm.Bool.fromBool(ptr_info.flags.is_volatile); |
| 8909 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); | 8791 | const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder); |
| 8910 | | 8792 | |
| 8911 | if (opt_abi_llvm_ty) |abi_llvm_ty| { | 8793 | if (abi_ty != .none) { |
| | 8794 | const llvm_abi_ty = abi_ty.toLlvm(&o.builder); |
| 8912 | // operand needs widening and truncating | 8795 | // operand needs widening and truncating |
| 8913 | const load_inst = self.builder.buildLoad(abi_llvm_ty, ptr, ""); | 8796 | const load_inst = self.builder.buildLoad(llvm_abi_ty, ptr, ""); |
| 8914 | load_inst.setAlignment(ptr_alignment); | 8797 | load_inst.setAlignment(ptr_alignment); |
| 8915 | load_inst.setVolatile(ptr_volatile); | 8798 | load_inst.setVolatile(ptr_volatile); |
| 8916 | load_inst.setOrdering(ordering); | 8799 | load_inst.setOrdering(ordering); |
| ... | @@ -8936,14 +8819,15 @@ pub const FuncGen = struct { | ... | @@ -8936,14 +8819,15 @@ pub const FuncGen = struct { |
| 8936 | if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return null; | 8819 | if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return null; |
| 8937 | const ptr = try self.resolveInst(bin_op.lhs); | 8820 | const ptr = try self.resolveInst(bin_op.lhs); |
| 8938 | var element = try self.resolveInst(bin_op.rhs); | 8821 | var element = try self.resolveInst(bin_op.rhs); |
| 8939 | const opt_abi_ty = o.getAtomicAbiType(operand_ty, false); | 8822 | const abi_ty = try o.getAtomicAbiType(operand_ty, false); |
| 8940 | | 8823 | |
| 8941 | if (opt_abi_ty) |abi_ty| { | 8824 | if (abi_ty != .none) { |
| | 8825 | const llvm_abi_ty = abi_ty.toLlvm(&o.builder); |
| 8942 | // operand needs widening | 8826 | // operand needs widening |
| 8943 | if (operand_ty.isSignedInt(mod)) { | 8827 | if (operand_ty.isSignedInt(mod)) { |
| 8944 | element = self.builder.buildSExt(element, abi_ty, ""); | 8828 | element = self.builder.buildSExt(element, llvm_abi_ty, ""); |
| 8945 | } else { | 8829 | } else { |
| 8946 | element = self.builder.buildZExt(element, abi_ty, ""); | 8830 | element = self.builder.buildZExt(element, llvm_abi_ty, ""); |
| 8947 | } | 8831 | } |
| 8948 | } | 8832 | } |
| 8949 | try self.store(ptr, ptr_ty, element, ordering); | 8833 | try self.store(ptr, ptr_ty, element, ordering); |
| ... | @@ -9056,7 +8940,7 @@ pub const FuncGen = struct { | ... | @@ -9056,7 +8940,7 @@ pub const FuncGen = struct { |
| 9056 | .One => llvm_usize_ty.constInt(ptr_ty.childType(mod).arrayLen(mod), .False), | 8940 | .One => llvm_usize_ty.constInt(ptr_ty.childType(mod).arrayLen(mod), .False), |
| 9057 | .Many, .C => unreachable, | 8941 | .Many, .C => unreachable, |
| 9058 | }; | 8942 | }; |
| 9059 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); | 8943 | const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder); |
| 9060 | const len_gep = [_]*llvm.Value{len}; | 8944 | const len_gep = [_]*llvm.Value{len}; |
| 9061 | const end_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, dest_ptr, &len_gep, len_gep.len, ""); | 8945 | const end_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, dest_ptr, &len_gep, len_gep.len, ""); |
| 9062 | _ = self.builder.buildBr(loop_block); | 8946 | _ = self.builder.buildBr(loop_block); |
| ... | @@ -9181,7 +9065,7 @@ pub const FuncGen = struct { | ... | @@ -9181,7 +9065,7 @@ pub const FuncGen = struct { |
| 9181 | _ = self.builder.buildStore(new_tag, union_ptr); | 9065 | _ = self.builder.buildStore(new_tag, union_ptr); |
| 9182 | return null; | 9066 | return null; |
| 9183 | } | 9067 | } |
| 9184 | const un_llvm_ty = try o.lowerLlvmType(un_ty); | 9068 | const un_llvm_ty = (try o.lowerType(un_ty)).toLlvm(&o.builder); |
| 9185 | const tag_index = @intFromBool(layout.tag_align < layout.payload_align); | 9069 | const tag_index = @intFromBool(layout.tag_align < layout.payload_align); |
| 9186 | const tag_field_ptr = self.builder.buildStructGEP(un_llvm_ty, union_ptr, tag_index, ""); | 9070 | const tag_field_ptr = self.builder.buildStructGEP(un_llvm_ty, union_ptr, tag_index, ""); |
| 9187 | // TODO alignment on this store | 9071 | // TODO alignment on this store |
| ... | @@ -9198,7 +9082,7 @@ pub const FuncGen = struct { | ... | @@ -9198,7 +9082,7 @@ pub const FuncGen = struct { |
| 9198 | if (layout.tag_size == 0) return null; | 9082 | if (layout.tag_size == 0) return null; |
| 9199 | const union_handle = try self.resolveInst(ty_op.operand); | 9083 | const union_handle = try self.resolveInst(ty_op.operand); |
| 9200 | if (isByRef(un_ty, mod)) { | 9084 | if (isByRef(un_ty, mod)) { |
| 9201 | const llvm_un_ty = try o.lowerLlvmType(un_ty); | 9085 | const llvm_un_ty = (try o.lowerType(un_ty)).toLlvm(&o.builder); |
| 9202 | if (layout.payload_size == 0) { | 9086 | if (layout.payload_size == 0) { |
| 9203 | return self.builder.buildLoad(llvm_un_ty, union_handle, ""); | 9087 | return self.builder.buildLoad(llvm_un_ty, union_handle, ""); |
| 9204 | } | 9088 | } |
| ... | @@ -9240,13 +9124,13 @@ pub const FuncGen = struct { | ... | @@ -9240,13 +9124,13 @@ pub const FuncGen = struct { |
| 9240 | const operand = try self.resolveInst(ty_op.operand); | 9124 | const operand = try self.resolveInst(ty_op.operand); |
| 9241 | | 9125 | |
| 9242 | const llvm_i1 = self.context.intType(1); | 9126 | const llvm_i1 = self.context.intType(1); |
| 9243 | const operand_llvm_ty = try o.lowerLlvmType(operand_ty); | 9127 | const operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder); |
| 9244 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); | 9128 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); |
| 9245 | | 9129 | |
| 9246 | const params = [_]*llvm.Value{ operand, llvm_i1.constNull() }; | 9130 | const params = [_]*llvm.Value{ operand, llvm_i1.constNull() }; |
| 9247 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); | 9131 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); |
| 9248 | const result_ty = self.typeOfIndex(inst); | 9132 | const result_ty = self.typeOfIndex(inst); |
| 9249 | const result_llvm_ty = try o.lowerLlvmType(result_ty); | 9133 | const result_llvm_ty = (try o.lowerType(result_ty)).toLlvm(&o.builder); |
| 9250 | | 9134 | |
| 9251 | const bits = operand_ty.intInfo(mod).bits; | 9135 | const bits = operand_ty.intInfo(mod).bits; |
| 9252 | const result_bits = result_ty.intInfo(mod).bits; | 9136 | const result_bits = result_ty.intInfo(mod).bits; |
| ... | @@ -9267,12 +9151,12 @@ pub const FuncGen = struct { | ... | @@ -9267,12 +9151,12 @@ pub const FuncGen = struct { |
| 9267 | const operand = try self.resolveInst(ty_op.operand); | 9151 | const operand = try self.resolveInst(ty_op.operand); |
| 9268 | | 9152 | |
| 9269 | const params = [_]*llvm.Value{operand}; | 9153 | const params = [_]*llvm.Value{operand}; |
| 9270 | const operand_llvm_ty = try o.lowerLlvmType(operand_ty); | 9154 | const operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder); |
| 9271 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); | 9155 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); |
| 9272 | | 9156 | |
| 9273 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); | 9157 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); |
| 9274 | const result_ty = self.typeOfIndex(inst); | 9158 | const result_ty = self.typeOfIndex(inst); |
| 9275 | const result_llvm_ty = try o.lowerLlvmType(result_ty); | 9159 | const result_llvm_ty = (try o.lowerType(result_ty)).toLlvm(&o.builder); |
| 9276 | | 9160 | |
| 9277 | const bits = operand_ty.intInfo(mod).bits; | 9161 | const bits = operand_ty.intInfo(mod).bits; |
| 9278 | const result_bits = result_ty.intInfo(mod).bits; | 9162 | const result_bits = result_ty.intInfo(mod).bits; |
| ... | @@ -9294,7 +9178,7 @@ pub const FuncGen = struct { | ... | @@ -9294,7 +9178,7 @@ pub const FuncGen = struct { |
| 9294 | assert(bits % 8 == 0); | 9178 | assert(bits % 8 == 0); |
| 9295 | | 9179 | |
| 9296 | var operand = try self.resolveInst(ty_op.operand); | 9180 | var operand = try self.resolveInst(ty_op.operand); |
| 9297 | var operand_llvm_ty = try o.lowerLlvmType(operand_ty); | 9181 | var operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder); |
| 9298 | | 9182 | |
| 9299 | if (bits % 16 == 8) { | 9183 | if (bits % 16 == 8) { |
| 9300 | // If not an even byte-multiple, we need zero-extend + shift-left 1 byte | 9184 | // If not an even byte-multiple, we need zero-extend + shift-left 1 byte |
| ... | @@ -9328,7 +9212,7 @@ pub const FuncGen = struct { | ... | @@ -9328,7 +9212,7 @@ pub const FuncGen = struct { |
| 9328 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); | 9212 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); |
| 9329 | | 9213 | |
| 9330 | const result_ty = self.typeOfIndex(inst); | 9214 | const result_ty = self.typeOfIndex(inst); |
| 9331 | const result_llvm_ty = try o.lowerLlvmType(result_ty); | 9215 | const result_llvm_ty = (try o.lowerType(result_ty)).toLlvm(&o.builder); |
| 9332 | const result_bits = result_ty.intInfo(mod).bits; | 9216 | const result_bits = result_ty.intInfo(mod).bits; |
| 9333 | if (bits > result_bits) { | 9217 | if (bits > result_bits) { |
| 9334 | return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, ""); | 9218 | return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, ""); |
| ... | @@ -9407,9 +9291,9 @@ pub const FuncGen = struct { | ... | @@ -9407,9 +9291,9 @@ pub const FuncGen = struct { |
| 9407 | const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod); | 9291 | const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod); |
| 9408 | const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{}", .{fqn.fmt(&mod.intern_pool)}); | 9292 | const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{}", .{fqn.fmt(&mod.intern_pool)}); |
| 9409 | | 9293 | |
| 9410 | const param_types = [_]*llvm.Type{try o.lowerLlvmType(enum_type.tag_ty.toType())}; | 9294 | const param_types = [_]*llvm.Type{(try o.lowerType(enum_type.tag_ty.toType())).toLlvm(&o.builder)}; |
| 9411 | | 9295 | |
| 9412 | const llvm_ret_ty = try o.lowerLlvmType(Type.bool); | 9296 | const llvm_ret_ty = (try o.lowerType(Type.bool)).toLlvm(&o.builder); |
| 9413 | const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False); | 9297 | const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False); |
| 9414 | const fn_val = o.llvm_module.addFunction(llvm_fn_name, fn_type); | 9298 | const fn_val = o.llvm_module.addFunction(llvm_fn_name, fn_type); |
| 9415 | fn_val.setLinkage(.Internal); | 9299 | fn_val.setLinkage(.Internal); |
| ... | @@ -9477,11 +9361,11 @@ pub const FuncGen = struct { | ... | @@ -9477,11 +9361,11 @@ pub const FuncGen = struct { |
| 9477 | const llvm_fn_name = try o.builder.fmt("__zig_tag_name_{}", .{fqn.fmt(&mod.intern_pool)}); | 9361 | const llvm_fn_name = try o.builder.fmt("__zig_tag_name_{}", .{fqn.fmt(&mod.intern_pool)}); |
| 9478 | | 9362 | |
| 9479 | const slice_ty = Type.slice_const_u8_sentinel_0; | 9363 | const slice_ty = Type.slice_const_u8_sentinel_0; |
| 9480 | const llvm_ret_ty = try o.lowerLlvmType(slice_ty); | 9364 | const llvm_ret_ty = (try o.lowerType(slice_ty)).toLlvm(&o.builder); |
| 9481 | const usize_llvm_ty = try o.lowerLlvmType(Type.usize); | 9365 | const usize_llvm_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder); |
| 9482 | const slice_alignment = slice_ty.abiAlignment(mod); | 9366 | const slice_alignment = slice_ty.abiAlignment(mod); |
| 9483 | | 9367 | |
| 9484 | const param_types = [_]*llvm.Type{try o.lowerLlvmType(enum_type.tag_ty.toType())}; | 9368 | const param_types = [_]*llvm.Type{(try o.lowerType(enum_type.tag_ty.toType())).toLlvm(&o.builder)}; |
| 9485 | | 9369 | |
| 9486 | const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False); | 9370 | const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False); |
| 9487 | const fn_val = o.llvm_module.addFunction(llvm_fn_name.toSlice(&o.builder).?, fn_type); | 9371 | const fn_val = o.llvm_module.addFunction(llvm_fn_name.toSlice(&o.builder).?, fn_type); |
| ... | @@ -9490,7 +9374,7 @@ pub const FuncGen = struct { | ... | @@ -9490,7 +9374,7 @@ pub const FuncGen = struct { |
| 9490 | o.addCommonFnAttributes(fn_val); | 9374 | o.addCommonFnAttributes(fn_val); |
| 9491 | | 9375 | |
| 9492 | var global = Builder.Global{ | 9376 | var global = Builder.Global{ |
| 9493 | .type = .void, | 9377 | .type = try o.builder.fnType(.void, &.{}, .normal), |
| 9494 | .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) }, | 9378 | .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) }, |
| 9495 | }; | 9379 | }; |
| 9496 | var function = Builder.Function{ | 9380 | var function = Builder.Function{ |
| ... | @@ -9573,8 +9457,8 @@ pub const FuncGen = struct { | ... | @@ -9573,8 +9457,8 @@ pub const FuncGen = struct { |
| 9573 | | 9457 | |
| 9574 | // Function signature: fn (anyerror) bool | 9458 | // Function signature: fn (anyerror) bool |
| 9575 | | 9459 | |
| 9576 | const ret_llvm_ty = try o.lowerLlvmType(Type.bool); | 9460 | const ret_llvm_ty = (try o.lowerType(Type.bool)).toLlvm(&o.builder); |
| 9577 | const anyerror_llvm_ty = try o.lowerLlvmType(Type.anyerror); | 9461 | const anyerror_llvm_ty = (try o.lowerType(Type.anyerror)).toLlvm(&o.builder); |
| 9578 | const param_types = [_]*llvm.Type{anyerror_llvm_ty}; | 9462 | const param_types = [_]*llvm.Type{anyerror_llvm_ty}; |
| 9579 | | 9463 | |
| 9580 | const fn_type = llvm.functionType(ret_llvm_ty, &param_types, param_types.len, .False); | 9464 | const fn_type = llvm.functionType(ret_llvm_ty, &param_types, param_types.len, .False); |
| ... | @@ -9590,7 +9474,7 @@ pub const FuncGen = struct { | ... | @@ -9590,7 +9474,7 @@ pub const FuncGen = struct { |
| 9590 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 9474 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 9591 | const operand = try self.resolveInst(un_op); | 9475 | const operand = try self.resolveInst(un_op); |
| 9592 | const slice_ty = self.typeOfIndex(inst); | 9476 | const slice_ty = self.typeOfIndex(inst); |
| 9593 | const slice_llvm_ty = try o.lowerLlvmType(slice_ty); | 9477 | const slice_llvm_ty = (try o.lowerType(slice_ty)).toLlvm(&o.builder); |
| 9594 | | 9478 | |
| 9595 | const error_name_table_ptr = try self.getErrorNameTable(); | 9479 | const error_name_table_ptr = try self.getErrorNameTable(); |
| 9596 | const ptr_slice_llvm_ty = self.context.pointerType(0); | 9480 | const ptr_slice_llvm_ty = self.context.pointerType(0); |
| ... | @@ -9676,7 +9560,7 @@ pub const FuncGen = struct { | ... | @@ -9676,7 +9560,7 @@ pub const FuncGen = struct { |
| 9676 | accum_init: *llvm.Value, | 9560 | accum_init: *llvm.Value, |
| 9677 | ) !*llvm.Value { | 9561 | ) !*llvm.Value { |
| 9678 | const o = self.dg.object; | 9562 | const o = self.dg.object; |
| 9679 | const llvm_usize_ty = try o.lowerLlvmType(Type.usize); | 9563 | const llvm_usize_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder); |
| 9680 | const llvm_vector_len = llvm_usize_ty.constInt(vector_len, .False); | 9564 | const llvm_vector_len = llvm_usize_ty.constInt(vector_len, .False); |
| 9681 | const llvm_result_ty = accum_init.typeOf(); | 9565 | const llvm_result_ty = accum_init.typeOf(); |
| 9682 | | 9566 | |
| ... | @@ -9753,7 +9637,7 @@ pub const FuncGen = struct { | ... | @@ -9753,7 +9637,7 @@ pub const FuncGen = struct { |
| 9753 | .Add => switch (scalar_ty.zigTypeTag(mod)) { | 9637 | .Add => switch (scalar_ty.zigTypeTag(mod)) { |
| 9754 | .Int => return self.builder.buildAddReduce(operand), | 9638 | .Int => return self.builder.buildAddReduce(operand), |
| 9755 | .Float => if (intrinsicsAllowed(scalar_ty, target)) { | 9639 | .Float => if (intrinsicsAllowed(scalar_ty, target)) { |
| 9756 | const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty); | 9640 | const scalar_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder); |
| 9757 | const neutral_value = scalar_llvm_ty.constReal(-0.0); | 9641 | const neutral_value = scalar_llvm_ty.constReal(-0.0); |
| 9758 | return self.builder.buildFPAddReduce(neutral_value, operand); | 9642 | return self.builder.buildFPAddReduce(neutral_value, operand); |
| 9759 | }, | 9643 | }, |
| ... | @@ -9762,7 +9646,7 @@ pub const FuncGen = struct { | ... | @@ -9762,7 +9646,7 @@ pub const FuncGen = struct { |
| 9762 | .Mul => switch (scalar_ty.zigTypeTag(mod)) { | 9646 | .Mul => switch (scalar_ty.zigTypeTag(mod)) { |
| 9763 | .Int => return self.builder.buildMulReduce(operand), | 9647 | .Int => return self.builder.buildMulReduce(operand), |
| 9764 | .Float => if (intrinsicsAllowed(scalar_ty, target)) { | 9648 | .Float => if (intrinsicsAllowed(scalar_ty, target)) { |
| 9765 | const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty); | 9649 | const scalar_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder); |
| 9766 | const neutral_value = scalar_llvm_ty.constReal(1.0); | 9650 | const neutral_value = scalar_llvm_ty.constReal(1.0); |
| 9767 | return self.builder.buildFPMulReduce(neutral_value, operand); | 9651 | return self.builder.buildFPMulReduce(neutral_value, operand); |
| 9768 | }, | 9652 | }, |
| ... | @@ -9790,7 +9674,7 @@ pub const FuncGen = struct { | ... | @@ -9790,7 +9674,7 @@ pub const FuncGen = struct { |
| 9790 | else => unreachable, | 9674 | else => unreachable, |
| 9791 | }; | 9675 | }; |
| 9792 | | 9676 | |
| 9793 | const param_llvm_ty = try o.lowerLlvmType(scalar_ty); | 9677 | const param_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder); |
| 9794 | const param_types = [2]*llvm.Type{ param_llvm_ty, param_llvm_ty }; | 9678 | const param_types = [2]*llvm.Type{ param_llvm_ty, param_llvm_ty }; |
| 9795 | const libc_fn = try self.getLibcFunction(fn_name, &param_types, param_llvm_ty); | 9679 | const libc_fn = try self.getLibcFunction(fn_name, &param_types, param_llvm_ty); |
| 9796 | const init_value = try o.lowerValue(.{ | 9680 | const init_value = try o.lowerValue(.{ |
| ... | @@ -9813,7 +9697,7 @@ pub const FuncGen = struct { | ... | @@ -9813,7 +9697,7 @@ pub const FuncGen = struct { |
| 9813 | const result_ty = self.typeOfIndex(inst); | 9697 | const result_ty = self.typeOfIndex(inst); |
| 9814 | const len = @as(usize, @intCast(result_ty.arrayLen(mod))); | 9698 | const len = @as(usize, @intCast(result_ty.arrayLen(mod))); |
| 9815 | const elements = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[ty_pl.payload..][0..len])); | 9699 | const elements = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[ty_pl.payload..][0..len])); |
| 9816 | const llvm_result_ty = try o.lowerLlvmType(result_ty); | 9700 | const llvm_result_ty = (try o.lowerType(result_ty)).toLlvm(&o.builder); |
| 9817 | | 9701 | |
| 9818 | switch (result_ty.zigTypeTag(mod)) { | 9702 | switch (result_ty.zigTypeTag(mod)) { |
| 9819 | .Vector => { | 9703 | .Vector => { |
| ... | @@ -9901,7 +9785,7 @@ pub const FuncGen = struct { | ... | @@ -9901,7 +9785,7 @@ pub const FuncGen = struct { |
| 9901 | .Array => { | 9785 | .Array => { |
| 9902 | assert(isByRef(result_ty, mod)); | 9786 | assert(isByRef(result_ty, mod)); |
| 9903 | | 9787 | |
| 9904 | const llvm_usize = try o.lowerLlvmType(Type.usize); | 9788 | const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder); |
| 9905 | const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod)); | 9789 | const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod)); |
| 9906 | | 9790 | |
| 9907 | const array_info = result_ty.arrayInfo(mod); | 9791 | const array_info = result_ty.arrayInfo(mod); |
| ... | @@ -9944,7 +9828,7 @@ pub const FuncGen = struct { | ... | @@ -9944,7 +9828,7 @@ pub const FuncGen = struct { |
| 9944 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 9828 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 9945 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; | 9829 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| 9946 | const union_ty = self.typeOfIndex(inst); | 9830 | const union_ty = self.typeOfIndex(inst); |
| 9947 | const union_llvm_ty = try o.lowerLlvmType(union_ty); | 9831 | const union_llvm_ty = (try o.lowerType(union_ty)).toLlvm(&o.builder); |
| 9948 | const layout = union_ty.unionGetLayout(mod); | 9832 | const layout = union_ty.unionGetLayout(mod); |
| 9949 | const union_obj = mod.typeToUnion(union_ty).?; | 9833 | const union_obj = mod.typeToUnion(union_ty).?; |
| 9950 | | 9834 | |
| ... | @@ -9986,7 +9870,7 @@ pub const FuncGen = struct { | ... | @@ -9986,7 +9870,7 @@ pub const FuncGen = struct { |
| 9986 | const llvm_payload = try self.resolveInst(extra.init); | 9870 | const llvm_payload = try self.resolveInst(extra.init); |
| 9987 | assert(union_obj.haveFieldTypes()); | 9871 | assert(union_obj.haveFieldTypes()); |
| 9988 | const field = union_obj.fields.values()[extra.field_index]; | 9872 | const field = union_obj.fields.values()[extra.field_index]; |
| 9989 | const field_llvm_ty = try o.lowerLlvmType(field.ty); | 9873 | const field_llvm_ty = (try o.lowerType(field.ty)).toLlvm(&o.builder); |
| 9990 | const field_size = field.ty.abiSize(mod); | 9874 | const field_size = field.ty.abiSize(mod); |
| 9991 | const field_align = field.normalAlignment(mod); | 9875 | const field_align = field.normalAlignment(mod); |
| 9992 | | 9876 | |
| ... | @@ -10009,7 +9893,7 @@ pub const FuncGen = struct { | ... | @@ -10009,7 +9893,7 @@ pub const FuncGen = struct { |
| 10009 | const fields: [1]*llvm.Type = .{payload}; | 9893 | const fields: [1]*llvm.Type = .{payload}; |
| 10010 | break :t self.context.structType(&fields, fields.len, .False); | 9894 | break :t self.context.structType(&fields, fields.len, .False); |
| 10011 | } | 9895 | } |
| 10012 | const tag_llvm_ty = try o.lowerLlvmType(union_obj.tag_ty); | 9896 | const tag_llvm_ty = (try o.lowerType(union_obj.tag_ty)).toLlvm(&o.builder); |
| 10013 | var fields: [3]*llvm.Type = undefined; | 9897 | var fields: [3]*llvm.Type = undefined; |
| 10014 | var fields_len: c_uint = 2; | 9898 | var fields_len: c_uint = 2; |
| 10015 | if (layout.tag_align >= layout.payload_align) { | 9899 | if (layout.tag_align >= layout.payload_align) { |
| ... | @@ -10062,7 +9946,7 @@ pub const FuncGen = struct { | ... | @@ -10062,7 +9946,7 @@ pub const FuncGen = struct { |
| 10062 | index_type.constInt(@intFromBool(layout.tag_align < layout.payload_align), .False), | 9946 | index_type.constInt(@intFromBool(layout.tag_align < layout.payload_align), .False), |
| 10063 | }; | 9947 | }; |
| 10064 | const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, indices.len, ""); | 9948 | const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, indices.len, ""); |
| 10065 | const tag_llvm_ty = try o.lowerLlvmType(union_obj.tag_ty); | 9949 | const tag_llvm_ty = (try o.lowerType(union_obj.tag_ty)).toLlvm(&o.builder); |
| 10066 | const llvm_tag = tag_llvm_ty.constInt(tag_int, .False); | 9950 | const llvm_tag = tag_llvm_ty.constInt(tag_int, .False); |
| 10067 | const store_inst = self.builder.buildStore(llvm_tag, field_ptr); | 9951 | const store_inst = self.builder.buildStore(llvm_tag, field_ptr); |
| 10068 | store_inst.setAlignment(union_obj.tag_ty.abiAlignment(mod)); | 9952 | store_inst.setAlignment(union_obj.tag_ty.abiAlignment(mod)); |
| ... | @@ -10144,7 +10028,7 @@ pub const FuncGen = struct { | ... | @@ -10144,7 +10028,7 @@ pub const FuncGen = struct { |
| 10144 | const inst_ty = self.typeOfIndex(inst); | 10028 | const inst_ty = self.typeOfIndex(inst); |
| 10145 | const operand = try self.resolveInst(ty_op.operand); | 10029 | const operand = try self.resolveInst(ty_op.operand); |
| 10146 | | 10030 | |
| 10147 | const llvm_dest_ty = try o.lowerLlvmType(inst_ty); | 10031 | const llvm_dest_ty = (try o.lowerType(inst_ty)).toLlvm(&o.builder); |
| 10148 | return self.builder.buildAddrSpaceCast(operand, llvm_dest_ty, ""); | 10032 | return self.builder.buildAddrSpaceCast(operand, llvm_dest_ty, ""); |
| 10149 | } | 10033 | } |
| 10150 | | 10034 | |
| ... | @@ -10278,7 +10162,7 @@ pub const FuncGen = struct { | ... | @@ -10278,7 +10162,7 @@ pub const FuncGen = struct { |
| 10278 | | 10162 | |
| 10279 | return fg.loadByRef(payload_ptr, payload_ty, payload_alignment, false); | 10163 | return fg.loadByRef(payload_ptr, payload_ty, payload_alignment, false); |
| 10280 | } | 10164 | } |
| 10281 | const payload_llvm_ty = try o.lowerLlvmType(payload_ty); | 10165 | const payload_llvm_ty = (try o.lowerType(payload_ty)).toLlvm(&o.builder); |
| 10282 | const load_inst = fg.builder.buildLoad(payload_llvm_ty, payload_ptr, ""); | 10166 | const load_inst = fg.builder.buildLoad(payload_llvm_ty, payload_ptr, ""); |
| 10283 | load_inst.setAlignment(payload_alignment); | 10167 | load_inst.setAlignment(payload_alignment); |
| 10284 | return load_inst; | 10168 | return load_inst; |
| ... | @@ -10295,7 +10179,7 @@ pub const FuncGen = struct { | ... | @@ -10295,7 +10179,7 @@ pub const FuncGen = struct { |
| 10295 | non_null_bit: *llvm.Value, | 10179 | non_null_bit: *llvm.Value, |
| 10296 | ) !?*llvm.Value { | 10180 | ) !?*llvm.Value { |
| 10297 | const o = self.dg.object; | 10181 | const o = self.dg.object; |
| 10298 | const optional_llvm_ty = try o.lowerLlvmType(optional_ty); | 10182 | const optional_llvm_ty = (try o.lowerType(optional_ty)).toLlvm(&o.builder); |
| 10299 | const non_null_field = self.builder.buildZExt(non_null_bit, self.context.intType(8), ""); | 10183 | const non_null_field = self.builder.buildZExt(non_null_bit, self.context.intType(8), ""); |
| 10300 | const mod = o.module; | 10184 | const mod = o.module; |
| 10301 | | 10185 | |
| ... | @@ -10350,13 +10234,13 @@ pub const FuncGen = struct { | ... | @@ -10350,13 +10234,13 @@ pub const FuncGen = struct { |
| 10350 | const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, mod); | 10234 | const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, mod); |
| 10351 | if (byte_offset == 0) return struct_ptr; | 10235 | if (byte_offset == 0) return struct_ptr; |
| 10352 | const byte_llvm_ty = self.context.intType(8); | 10236 | const byte_llvm_ty = self.context.intType(8); |
| 10353 | const llvm_usize = try o.lowerLlvmType(Type.usize); | 10237 | const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder); |
| 10354 | const llvm_index = llvm_usize.constInt(byte_offset, .False); | 10238 | const llvm_index = llvm_usize.constInt(byte_offset, .False); |
| 10355 | const indices: [1]*llvm.Value = .{llvm_index}; | 10239 | const indices: [1]*llvm.Value = .{llvm_index}; |
| 10356 | return self.builder.buildInBoundsGEP(byte_llvm_ty, struct_ptr, &indices, indices.len, ""); | 10240 | return self.builder.buildInBoundsGEP(byte_llvm_ty, struct_ptr, &indices, indices.len, ""); |
| 10357 | }, | 10241 | }, |
| 10358 | else => { | 10242 | else => { |
| 10359 | const struct_llvm_ty = try o.lowerPtrElemTy(struct_ty); | 10243 | const struct_llvm_ty = (try o.lowerPtrElemTy(struct_ty)).toLlvm(&o.builder); |
| 10360 | | 10244 | |
| 10361 | if (llvmField(struct_ty, field_index, mod)) |llvm_field| { | 10245 | if (llvmField(struct_ty, field_index, mod)) |llvm_field| { |
| 10362 | return self.builder.buildStructGEP(struct_llvm_ty, struct_ptr, llvm_field.index, ""); | 10246 | return self.builder.buildStructGEP(struct_llvm_ty, struct_ptr, llvm_field.index, ""); |
| ... | @@ -10376,7 +10260,7 @@ pub const FuncGen = struct { | ... | @@ -10376,7 +10260,7 @@ pub const FuncGen = struct { |
| 10376 | const layout = struct_ty.unionGetLayout(mod); | 10260 | const layout = struct_ty.unionGetLayout(mod); |
| 10377 | if (layout.payload_size == 0 or struct_ty.containerLayout(mod) == .Packed) return struct_ptr; | 10261 | if (layout.payload_size == 0 or struct_ty.containerLayout(mod) == .Packed) return struct_ptr; |
| 10378 | const payload_index = @intFromBool(layout.tag_align >= layout.payload_align); | 10262 | const payload_index = @intFromBool(layout.tag_align >= layout.payload_align); |
| 10379 | const union_llvm_ty = try o.lowerLlvmType(struct_ty); | 10263 | const union_llvm_ty = (try o.lowerType(struct_ty)).toLlvm(&o.builder); |
| 10380 | const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_ptr, payload_index, ""); | 10264 | const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_ptr, payload_index, ""); |
| 10381 | return union_field_ptr; | 10265 | return union_field_ptr; |
| 10382 | }, | 10266 | }, |
| ... | @@ -10401,7 +10285,7 @@ pub const FuncGen = struct { | ... | @@ -10401,7 +10285,7 @@ pub const FuncGen = struct { |
| 10401 | ) !*llvm.Value { | 10285 | ) !*llvm.Value { |
| 10402 | const o = fg.dg.object; | 10286 | const o = fg.dg.object; |
| 10403 | const mod = o.module; | 10287 | const mod = o.module; |
| 10404 | const pointee_llvm_ty = try o.lowerLlvmType(pointee_type); | 10288 | const pointee_llvm_ty = (try o.lowerType(pointee_type)).toLlvm(&o.builder); |
| 10405 | const result_align = @max(ptr_alignment, pointee_type.abiAlignment(mod)); | 10289 | const result_align = @max(ptr_alignment, pointee_type.abiAlignment(mod)); |
| 10406 | const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align); | 10290 | const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align); |
| 10407 | const llvm_usize = fg.context.intType(Type.usize.intInfo(mod).bits); | 10291 | const llvm_usize = fg.context.intType(Type.usize.intInfo(mod).bits); |
| ... | @@ -10434,7 +10318,7 @@ pub const FuncGen = struct { | ... | @@ -10434,7 +10318,7 @@ pub const FuncGen = struct { |
| 10434 | assert(info.flags.vector_index != .runtime); | 10318 | assert(info.flags.vector_index != .runtime); |
| 10435 | if (info.flags.vector_index != .none) { | 10319 | if (info.flags.vector_index != .none) { |
| 10436 | const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False); | 10320 | const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False); |
| 10437 | const vec_elem_ty = try o.lowerLlvmType(elem_ty); | 10321 | const vec_elem_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder); |
| 10438 | const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size); | 10322 | const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size); |
| 10439 | | 10323 | |
| 10440 | const loaded_vector = self.builder.buildLoad(vec_ty, ptr, ""); | 10324 | const loaded_vector = self.builder.buildLoad(vec_ty, ptr, ""); |
| ... | @@ -10448,7 +10332,7 @@ pub const FuncGen = struct { | ... | @@ -10448,7 +10332,7 @@ pub const FuncGen = struct { |
| 10448 | if (isByRef(elem_ty, mod)) { | 10332 | if (isByRef(elem_ty, mod)) { |
| 10449 | return self.loadByRef(ptr, elem_ty, ptr_alignment, info.flags.is_volatile); | 10333 | return self.loadByRef(ptr, elem_ty, ptr_alignment, info.flags.is_volatile); |
| 10450 | } | 10334 | } |
| 10451 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); | 10335 | const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder); |
| 10452 | const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, ""); | 10336 | const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, ""); |
| 10453 | llvm_inst.setAlignment(ptr_alignment); | 10337 | llvm_inst.setAlignment(ptr_alignment); |
| 10454 | llvm_inst.setVolatile(ptr_volatile); | 10338 | llvm_inst.setVolatile(ptr_volatile); |
| ... | @@ -10463,7 +10347,7 @@ pub const FuncGen = struct { | ... | @@ -10463,7 +10347,7 @@ pub const FuncGen = struct { |
| 10463 | const elem_bits = @as(c_uint, @intCast(ptr_ty.childType(mod).bitSize(mod))); | 10347 | const elem_bits = @as(c_uint, @intCast(ptr_ty.childType(mod).bitSize(mod))); |
| 10464 | const shift_amt = containing_int.typeOf().constInt(info.packed_offset.bit_offset, .False); | 10348 | const shift_amt = containing_int.typeOf().constInt(info.packed_offset.bit_offset, .False); |
| 10465 | const shifted_value = self.builder.buildLShr(containing_int, shift_amt, ""); | 10349 | const shifted_value = self.builder.buildLShr(containing_int, shift_amt, ""); |
| 10466 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); | 10350 | const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder); |
| 10467 | | 10351 | |
| 10468 | if (isByRef(elem_ty, mod)) { | 10352 | if (isByRef(elem_ty, mod)) { |
| 10469 | const result_align = elem_ty.abiAlignment(mod); | 10353 | const result_align = elem_ty.abiAlignment(mod); |
| ... | @@ -10511,7 +10395,7 @@ pub const FuncGen = struct { | ... | @@ -10511,7 +10395,7 @@ pub const FuncGen = struct { |
| 10511 | assert(info.flags.vector_index != .runtime); | 10395 | assert(info.flags.vector_index != .runtime); |
| 10512 | if (info.flags.vector_index != .none) { | 10396 | if (info.flags.vector_index != .none) { |
| 10513 | const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False); | 10397 | const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False); |
| 10514 | const vec_elem_ty = try o.lowerLlvmType(elem_ty); | 10398 | const vec_elem_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder); |
| 10515 | const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size); | 10399 | const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size); |
| 10516 | | 10400 | |
| 10517 | const loaded_vector = self.builder.buildLoad(vec_ty, ptr, ""); | 10401 | const loaded_vector = self.builder.buildLoad(vec_ty, ptr, ""); |
| ... | @@ -10951,14 +10835,14 @@ fn toLlvmCallConv(cc: std.builtin.CallingConvention, target: std.Target) llvm.Ca | ... | @@ -10951,14 +10835,14 @@ fn toLlvmCallConv(cc: std.builtin.CallingConvention, target: std.Target) llvm.Ca |
| 10951 | } | 10835 | } |
| 10952 | | 10836 | |
| 10953 | /// Convert a zig-address space to an llvm address space. | 10837 | /// Convert a zig-address space to an llvm address space. |
| 10954 | fn toLlvmAddressSpace(address_space: std.builtin.AddressSpace, target: std.Target) c_uint { | 10838 | fn toLlvmAddressSpace(address_space: std.builtin.AddressSpace, target: std.Target) Builder.AddrSpace { |
| 10955 | for (llvmAddressSpaceInfo(target)) |info| if (info.zig == address_space) return info.llvm; | 10839 | for (llvmAddrSpaceInfo(target)) |info| if (info.zig == address_space) return info.llvm; |
| 10956 | unreachable; | 10840 | unreachable; |
| 10957 | } | 10841 | } |
| 10958 | | 10842 | |
| 10959 | const AddressSpaceInfo = struct { | 10843 | const AddrSpaceInfo = struct { |
| 10960 | zig: ?std.builtin.AddressSpace, | 10844 | zig: ?std.builtin.AddressSpace, |
| 10961 | llvm: c_uint, | 10845 | llvm: Builder.AddrSpace, |
| 10962 | non_integral: bool = false, | 10846 | non_integral: bool = false, |
| 10963 | size: ?u16 = null, | 10847 | size: ?u16 = null, |
| 10964 | abi: ?u16 = null, | 10848 | abi: ?u16 = null, |
| ... | @@ -10966,49 +10850,49 @@ const AddressSpaceInfo = struct { | ... | @@ -10966,49 +10850,49 @@ const AddressSpaceInfo = struct { |
| 10966 | idx: ?u16 = null, | 10850 | idx: ?u16 = null, |
| 10967 | force_in_data_layout: bool = false, | 10851 | force_in_data_layout: bool = false, |
| 10968 | }; | 10852 | }; |
| 10969 | fn llvmAddressSpaceInfo(target: std.Target) []const AddressSpaceInfo { | 10853 | fn llvmAddrSpaceInfo(target: std.Target) []const AddrSpaceInfo { |
| 10970 | return switch (target.cpu.arch) { | 10854 | return switch (target.cpu.arch) { |
| 10971 | .x86, .x86_64 => &.{ | 10855 | .x86, .x86_64 => &.{ |
| 10972 | .{ .zig = .generic, .llvm = llvm.address_space.default }, | 10856 | .{ .zig = .generic, .llvm = .default }, |
| 10973 | .{ .zig = .gs, .llvm = llvm.address_space.x86.gs }, | 10857 | .{ .zig = .gs, .llvm = Builder.AddrSpace.x86.gs }, |
| 10974 | .{ .zig = .fs, .llvm = llvm.address_space.x86.fs }, | 10858 | .{ .zig = .fs, .llvm = Builder.AddrSpace.x86.fs }, |
| 10975 | .{ .zig = .ss, .llvm = llvm.address_space.x86.ss }, | 10859 | .{ .zig = .ss, .llvm = Builder.AddrSpace.x86.ss }, |
| 10976 | .{ .zig = null, .llvm = llvm.address_space.x86.ptr32_sptr, .size = 32, .abi = 32, .force_in_data_layout = true }, | 10860 | .{ .zig = null, .llvm = Builder.AddrSpace.x86.ptr32_sptr, .size = 32, .abi = 32, .force_in_data_layout = true }, |
| 10977 | .{ .zig = null, .llvm = llvm.address_space.x86.ptr32_uptr, .size = 32, .abi = 32, .force_in_data_layout = true }, | 10861 | .{ .zig = null, .llvm = Builder.AddrSpace.x86.ptr32_uptr, .size = 32, .abi = 32, .force_in_data_layout = true }, |
| 10978 | .{ .zig = null, .llvm = llvm.address_space.x86.ptr64, .size = 64, .abi = 64, .force_in_data_layout = true }, | 10862 | .{ .zig = null, .llvm = Builder.AddrSpace.x86.ptr64, .size = 64, .abi = 64, .force_in_data_layout = true }, |
| 10979 | }, | 10863 | }, |
| 10980 | .nvptx, .nvptx64 => &.{ | 10864 | .nvptx, .nvptx64 => &.{ |
| 10981 | .{ .zig = .generic, .llvm = llvm.address_space.default }, | 10865 | .{ .zig = .generic, .llvm = .default }, |
| 10982 | .{ .zig = .global, .llvm = llvm.address_space.nvptx.global }, | 10866 | .{ .zig = .global, .llvm = Builder.AddrSpace.nvptx.global }, |
| 10983 | .{ .zig = .constant, .llvm = llvm.address_space.nvptx.constant }, | 10867 | .{ .zig = .constant, .llvm = Builder.AddrSpace.nvptx.constant }, |
| 10984 | .{ .zig = .param, .llvm = llvm.address_space.nvptx.param }, | 10868 | .{ .zig = .param, .llvm = Builder.AddrSpace.nvptx.param }, |
| 10985 | .{ .zig = .shared, .llvm = llvm.address_space.nvptx.shared }, | 10869 | .{ .zig = .shared, .llvm = Builder.AddrSpace.nvptx.shared }, |
| 10986 | .{ .zig = .local, .llvm = llvm.address_space.nvptx.local }, | 10870 | .{ .zig = .local, .llvm = Builder.AddrSpace.nvptx.local }, |
| 10987 | }, | 10871 | }, |
| 10988 | .amdgcn => &.{ | 10872 | .amdgcn => &.{ |
| 10989 | .{ .zig = .generic, .llvm = llvm.address_space.amdgpu.flat }, | 10873 | .{ .zig = .generic, .llvm = Builder.AddrSpace.amdgpu.flat }, |
| 10990 | .{ .zig = .global, .llvm = llvm.address_space.amdgpu.global }, | 10874 | .{ .zig = .global, .llvm = Builder.AddrSpace.amdgpu.global }, |
| 10991 | .{ .zig = .constant, .llvm = llvm.address_space.amdgpu.constant }, | 10875 | .{ .zig = .constant, .llvm = Builder.AddrSpace.amdgpu.constant }, |
| 10992 | .{ .zig = .shared, .llvm = llvm.address_space.amdgpu.local }, | 10876 | .{ .zig = .shared, .llvm = Builder.AddrSpace.amdgpu.local }, |
| 10993 | .{ .zig = .local, .llvm = llvm.address_space.amdgpu.private }, | 10877 | .{ .zig = .local, .llvm = Builder.AddrSpace.amdgpu.private }, |
| 10994 | }, | 10878 | }, |
| 10995 | .avr => &.{ | 10879 | .avr => &.{ |
| 10996 | .{ .zig = .generic, .llvm = llvm.address_space.default }, | 10880 | .{ .zig = .generic, .llvm = .default }, |
| 10997 | .{ .zig = .flash, .llvm = llvm.address_space.avr.flash }, | 10881 | .{ .zig = .flash, .llvm = Builder.AddrSpace.avr.flash }, |
| 10998 | .{ .zig = .flash1, .llvm = llvm.address_space.avr.flash1 }, | 10882 | .{ .zig = .flash1, .llvm = Builder.AddrSpace.avr.flash1 }, |
| 10999 | .{ .zig = .flash2, .llvm = llvm.address_space.avr.flash2 }, | 10883 | .{ .zig = .flash2, .llvm = Builder.AddrSpace.avr.flash2 }, |
| 11000 | .{ .zig = .flash3, .llvm = llvm.address_space.avr.flash3 }, | 10884 | .{ .zig = .flash3, .llvm = Builder.AddrSpace.avr.flash3 }, |
| 11001 | .{ .zig = .flash4, .llvm = llvm.address_space.avr.flash4 }, | 10885 | .{ .zig = .flash4, .llvm = Builder.AddrSpace.avr.flash4 }, |
| 11002 | .{ .zig = .flash5, .llvm = llvm.address_space.avr.flash5 }, | 10886 | .{ .zig = .flash5, .llvm = Builder.AddrSpace.avr.flash5 }, |
| 11003 | }, | 10887 | }, |
| 11004 | .wasm32, .wasm64 => &.{ | 10888 | .wasm32, .wasm64 => &.{ |
| 11005 | .{ .zig = .generic, .llvm = llvm.address_space.default }, | 10889 | .{ .zig = .generic, .llvm = .default }, |
| 11006 | .{ .zig = null, .llvm = llvm.address_space.wasm.variable, .non_integral = true }, | 10890 | .{ .zig = null, .llvm = Builder.AddrSpace.wasm.variable, .non_integral = true }, |
| 11007 | .{ .zig = null, .llvm = llvm.address_space.wasm.externref, .non_integral = true, .size = 8, .abi = 8 }, | 10891 | .{ .zig = null, .llvm = Builder.AddrSpace.wasm.externref, .non_integral = true, .size = 8, .abi = 8 }, |
| 11008 | .{ .zig = null, .llvm = llvm.address_space.wasm.funcref, .non_integral = true, .size = 8, .abi = 8 }, | 10892 | .{ .zig = null, .llvm = Builder.AddrSpace.wasm.funcref, .non_integral = true, .size = 8, .abi = 8 }, |
| 11009 | }, | 10893 | }, |
| 11010 | else => &.{ | 10894 | else => &.{ |
| 11011 | .{ .zig = .generic, .llvm = llvm.address_space.default }, | 10895 | .{ .zig = .generic, .llvm = .default }, |
| 11012 | }, | 10896 | }, |
| 11013 | }; | 10897 | }; |
| 11014 | } | 10898 | } |
| ... | @@ -11017,30 +10901,30 @@ fn llvmAddressSpaceInfo(target: std.Target) []const AddressSpaceInfo { | ... | @@ -11017,30 +10901,30 @@ fn llvmAddressSpaceInfo(target: std.Target) []const AddressSpaceInfo { |
| 11017 | /// different address, space and then cast back to the generic address space. | 10901 | /// different address, space and then cast back to the generic address space. |
| 11018 | /// For example, on GPUs local variable declarations must be generated into the local address space. | 10902 | /// For example, on GPUs local variable declarations must be generated into the local address space. |
| 11019 | /// This function returns the address space local values should be generated into. | 10903 | /// This function returns the address space local values should be generated into. |
| 11020 | fn llvmAllocaAddressSpace(target: std.Target) c_uint { | 10904 | fn llvmAllocaAddressSpace(target: std.Target) Builder.AddrSpace { |
| 11021 | return switch (target.cpu.arch) { | 10905 | return switch (target.cpu.arch) { |
| 11022 | // On amdgcn, locals should be generated into the private address space. | 10906 | // On amdgcn, locals should be generated into the private address space. |
| 11023 | // To make Zig not impossible to use, these are then converted to addresses in the | 10907 | // To make Zig not impossible to use, these are then converted to addresses in the |
| 11024 | // generic address space and treates as regular pointers. This is the way that HIP also does it. | 10908 | // generic address space and treates as regular pointers. This is the way that HIP also does it. |
| 11025 | .amdgcn => llvm.address_space.amdgpu.private, | 10909 | .amdgcn => Builder.AddrSpace.amdgpu.private, |
| 11026 | else => llvm.address_space.default, | 10910 | else => .default, |
| 11027 | }; | 10911 | }; |
| 11028 | } | 10912 | } |
| 11029 | | 10913 | |
| 11030 | /// On some targets, global values that are in the generic address space must be generated into a | 10914 | /// On some targets, global values that are in the generic address space must be generated into a |
| 11031 | /// different address space, and then cast back to the generic address space. | 10915 | /// different address space, and then cast back to the generic address space. |
| 11032 | fn llvmDefaultGlobalAddressSpace(target: std.Target) c_uint { | 10916 | fn llvmDefaultGlobalAddressSpace(target: std.Target) Builder.AddrSpace { |
| 11033 | return switch (target.cpu.arch) { | 10917 | return switch (target.cpu.arch) { |
| 11034 | // On amdgcn, globals must be explicitly allocated and uploaded so that the program can access | 10918 | // On amdgcn, globals must be explicitly allocated and uploaded so that the program can access |
| 11035 | // them. | 10919 | // them. |
| 11036 | .amdgcn => llvm.address_space.amdgpu.global, | 10920 | .amdgcn => Builder.AddrSpace.amdgpu.global, |
| 11037 | else => llvm.address_space.default, | 10921 | else => .default, |
| 11038 | }; | 10922 | }; |
| 11039 | } | 10923 | } |
| 11040 | | 10924 | |
| 11041 | /// Return the actual address space that a value should be stored in if its a global address space. | 10925 | /// Return the actual address space that a value should be stored in if its a global address space. |
| 11042 | /// When a value is placed in the resulting address space, it needs to be cast back into wanted_address_space. | 10926 | /// When a value is placed in the resulting address space, it needs to be cast back into wanted_address_space. |
| 11043 | fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, target: std.Target) c_uint { | 10927 | fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, target: std.Target) Builder.AddrSpace { |
| 11044 | return switch (wanted_address_space) { | 10928 | return switch (wanted_address_space) { |
| 11045 | .generic => llvmDefaultGlobalAddressSpace(target), | 10929 | .generic => llvmDefaultGlobalAddressSpace(target), |
| 11046 | else => |as| toLlvmAddressSpace(as, target), | 10930 | else => |as| toLlvmAddressSpace(as, target), |
| ... | @@ -11170,161 +11054,129 @@ fn firstParamSRetSystemV(ty: Type, mod: *Module) bool { | ... | @@ -11170,161 +11054,129 @@ fn firstParamSRetSystemV(ty: Type, mod: *Module) bool { |
| 11170 | /// In order to support the C calling convention, some return types need to be lowered | 11054 | /// In order to support the C calling convention, some return types need to be lowered |
| 11171 | /// completely differently in the function prototype to honor the C ABI, and then | 11055 | /// completely differently in the function prototype to honor the C ABI, and then |
| 11172 | /// be effectively bitcasted to the actual return type. | 11056 | /// be effectively bitcasted to the actual return type. |
| 11173 | fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { | 11057 | fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { |
| 11174 | const mod = o.module; | 11058 | const mod = o.module; |
| 11175 | const return_type = fn_info.return_type.toType(); | 11059 | const return_type = fn_info.return_type.toType(); |
| 11176 | if (!return_type.hasRuntimeBitsIgnoreComptime(mod)) { | 11060 | if (!return_type.hasRuntimeBitsIgnoreComptime(mod)) { |
| 11177 | // If the return type is an error set or an error union, then we make this | 11061 | // If the return type is an error set or an error union, then we make this |
| 11178 | // anyerror return type instead, so that it can be coerced into a function | 11062 | // anyerror return type instead, so that it can be coerced into a function |
| 11179 | // pointer type which has anyerror as the return type. | 11063 | // pointer type which has anyerror as the return type. |
| 11180 | if (return_type.isError(mod)) { | 11064 | return if (return_type.isError(mod)) Builder.Type.err_int else .void; |
| 11181 | return o.lowerLlvmType(Type.anyerror); | | |
| 11182 | } else { | | |
| 11183 | return o.context.voidType(); | | |
| 11184 | } | | |
| 11185 | } | 11065 | } |
| 11186 | const target = mod.getTarget(); | 11066 | const target = mod.getTarget(); |
| 11187 | switch (fn_info.cc) { | 11067 | switch (fn_info.cc) { |
| 11188 | .Unspecified, .Inline => { | 11068 | .Unspecified, |
| 11189 | if (isByRef(return_type, mod)) { | 11069 | .Inline, |
| 11190 | return o.context.voidType(); | 11070 | => return if (isByRef(return_type, mod)) .void else o.lowerType(return_type), |
| 11191 | } else { | | |
| 11192 | return o.lowerLlvmType(return_type); | | |
| 11193 | } | | |
| 11194 | }, | | |
| 11195 | .C => { | 11071 | .C => { |
| 11196 | switch (target.cpu.arch) { | 11072 | switch (target.cpu.arch) { |
| 11197 | .mips, .mipsel => return o.lowerLlvmType(return_type), | 11073 | .mips, .mipsel => return o.lowerType(return_type), |
| 11198 | .x86_64 => switch (target.os.tag) { | 11074 | .x86_64 => switch (target.os.tag) { |
| 11199 | .windows => return lowerWin64FnRetTy(o, fn_info), | 11075 | .windows => return lowerWin64FnRetTy(o, fn_info), |
| 11200 | else => return lowerSystemVFnRetTy(o, fn_info), | 11076 | else => return lowerSystemVFnRetTy(o, fn_info), |
| 11201 | }, | 11077 | }, |
| 11202 | .wasm32 => { | 11078 | .wasm32 => { |
| 11203 | if (isScalar(mod, return_type)) { | 11079 | if (isScalar(mod, return_type)) { |
| 11204 | return o.lowerLlvmType(return_type); | 11080 | return o.lowerType(return_type); |
| 11205 | } | 11081 | } |
| 11206 | const classes = wasm_c_abi.classifyType(return_type, mod); | 11082 | const classes = wasm_c_abi.classifyType(return_type, mod); |
| 11207 | if (classes[0] == .indirect or classes[0] == .none) { | 11083 | if (classes[0] == .indirect or classes[0] == .none) { |
| 11208 | return o.context.voidType(); | 11084 | return .void; |
| 11209 | } | 11085 | } |
| 11210 | | 11086 | |
| 11211 | assert(classes[0] == .direct and classes[1] == .none); | 11087 | assert(classes[0] == .direct and classes[1] == .none); |
| 11212 | const scalar_type = wasm_c_abi.scalarType(return_type, mod); | 11088 | const scalar_type = wasm_c_abi.scalarType(return_type, mod); |
| 11213 | const abi_size = scalar_type.abiSize(mod); | 11089 | return o.builder.intType(@intCast(scalar_type.abiSize(mod) * 8)); |
| 11214 | return o.context.intType(@as(c_uint, @intCast(abi_size * 8))); | | |
| 11215 | }, | 11090 | }, |
| 11216 | .aarch64, .aarch64_be => { | 11091 | .aarch64, .aarch64_be => { |
| 11217 | switch (aarch64_c_abi.classifyType(return_type, mod)) { | 11092 | switch (aarch64_c_abi.classifyType(return_type, mod)) { |
| 11218 | .memory => return o.context.voidType(), | 11093 | .memory => return .void, |
| 11219 | .float_array => return o.lowerLlvmType(return_type), | 11094 | .float_array => return o.lowerType(return_type), |
| 11220 | .byval => return o.lowerLlvmType(return_type), | 11095 | .byval => return o.lowerType(return_type), |
| 11221 | .integer => { | 11096 | .integer => return o.builder.intType(@intCast(return_type.bitSize(mod))), |
| 11222 | const bit_size = return_type.bitSize(mod); | 11097 | .double_integer => return o.builder.arrayType(2, .i64), |
| 11223 | return o.context.intType(@as(c_uint, @intCast(bit_size))); | | |
| 11224 | }, | | |
| 11225 | .double_integer => return o.context.intType(64).arrayType(2), | | |
| 11226 | } | 11098 | } |
| 11227 | }, | 11099 | }, |
| 11228 | .arm, .armeb => { | 11100 | .arm, .armeb => { |
| 11229 | switch (arm_c_abi.classifyType(return_type, mod, .ret)) { | 11101 | switch (arm_c_abi.classifyType(return_type, mod, .ret)) { |
| 11230 | .memory, .i64_array => return o.context.voidType(), | 11102 | .memory, .i64_array => return .void, |
| 11231 | .i32_array => |len| if (len == 1) { | 11103 | .i32_array => |len| return if (len == 1) .i32 else .void, |
| 11232 | return o.context.intType(32); | 11104 | .byval => return o.lowerType(return_type), |
| 11233 | } else { | | |
| 11234 | return o.context.voidType(); | | |
| 11235 | }, | | |
| 11236 | .byval => return o.lowerLlvmType(return_type), | | |
| 11237 | } | 11105 | } |
| 11238 | }, | 11106 | }, |
| 11239 | .riscv32, .riscv64 => { | 11107 | .riscv32, .riscv64 => { |
| 11240 | switch (riscv_c_abi.classifyType(return_type, mod)) { | 11108 | switch (riscv_c_abi.classifyType(return_type, mod)) { |
| 11241 | .memory => return o.context.voidType(), | 11109 | .memory => return .void, |
| 11242 | .integer => { | 11110 | .integer => { |
| 11243 | const bit_size = return_type.bitSize(mod); | 11111 | return o.builder.intType(@intCast(return_type.bitSize(mod))); |
| 11244 | return o.context.intType(@as(c_uint, @intCast(bit_size))); | | |
| 11245 | }, | 11112 | }, |
| 11246 | .double_integer => { | 11113 | .double_integer => { |
| 11247 | var llvm_types_buffer: [2]*llvm.Type = .{ | 11114 | return o.builder.structType(.normal, &.{ .i64, .i64 }); |
| 11248 | o.context.intType(64), | | |
| 11249 | o.context.intType(64), | | |
| 11250 | }; | | |
| 11251 | return o.context.structType(&llvm_types_buffer, 2, .False); | | |
| 11252 | }, | 11115 | }, |
| 11253 | .byval => return o.lowerLlvmType(return_type), | 11116 | .byval => return o.lowerType(return_type), |
| 11254 | } | 11117 | } |
| 11255 | }, | 11118 | }, |
| 11256 | // TODO investigate C ABI for other architectures | 11119 | // TODO investigate C ABI for other architectures |
| 11257 | else => return o.lowerLlvmType(return_type), | 11120 | else => return o.lowerType(return_type), |
| 11258 | } | 11121 | } |
| 11259 | }, | 11122 | }, |
| 11260 | .Win64 => return lowerWin64FnRetTy(o, fn_info), | 11123 | .Win64 => return lowerWin64FnRetTy(o, fn_info), |
| 11261 | .SysV => return lowerSystemVFnRetTy(o, fn_info), | 11124 | .SysV => return lowerSystemVFnRetTy(o, fn_info), |
| 11262 | .Stdcall => { | 11125 | .Stdcall => return if (isScalar(mod, return_type)) o.lowerType(return_type) else .void, |
| 11263 | if (isScalar(mod, return_type)) { | 11126 | else => return o.lowerType(return_type), |
| 11264 | return o.lowerLlvmType(return_type); | | |
| 11265 | } else { | | |
| 11266 | return o.context.voidType(); | | |
| 11267 | } | | |
| 11268 | }, | | |
| 11269 | else => return o.lowerLlvmType(return_type), | | |
| 11270 | } | 11127 | } |
| 11271 | } | 11128 | } |
| 11272 | | 11129 | |
| 11273 | fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { | 11130 | fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { |
| 11274 | const mod = o.module; | 11131 | const mod = o.module; |
| 11275 | const return_type = fn_info.return_type.toType(); | 11132 | const return_type = fn_info.return_type.toType(); |
| 11276 | switch (x86_64_abi.classifyWindows(return_type, mod)) { | 11133 | switch (x86_64_abi.classifyWindows(return_type, mod)) { |
| 11277 | .integer => { | 11134 | .integer => { |
| 11278 | if (isScalar(mod, return_type)) { | 11135 | if (isScalar(mod, return_type)) { |
| 11279 | return o.lowerLlvmType(return_type); | 11136 | return o.lowerType(return_type); |
| 11280 | } else { | 11137 | } else { |
| 11281 | const abi_size = return_type.abiSize(mod); | 11138 | return o.builder.intType(@intCast(return_type.abiSize(mod) * 8)); |
| 11282 | return o.context.intType(@as(c_uint, @intCast(abi_size * 8))); | | |
| 11283 | } | 11139 | } |
| 11284 | }, | 11140 | }, |
| 11285 | .win_i128 => return o.context.intType(64).vectorType(2), | 11141 | .win_i128 => return o.builder.vectorType(.normal, 2, .i64), |
| 11286 | .memory => return o.context.voidType(), | 11142 | .memory => return .void, |
| 11287 | .sse => return o.lowerLlvmType(return_type), | 11143 | .sse => return o.lowerType(return_type), |
| 11288 | else => unreachable, | 11144 | else => unreachable, |
| 11289 | } | 11145 | } |
| 11290 | } | 11146 | } |
| 11291 | | 11147 | |
| 11292 | fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { | 11148 | fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { |
| 11293 | const mod = o.module; | 11149 | const mod = o.module; |
| 11294 | const return_type = fn_info.return_type.toType(); | 11150 | const return_type = fn_info.return_type.toType(); |
| 11295 | if (isScalar(mod, return_type)) { | 11151 | if (isScalar(mod, return_type)) { |
| 11296 | return o.lowerLlvmType(return_type); | 11152 | return o.lowerType(return_type); |
| 11297 | } | 11153 | } |
| 11298 | const classes = x86_64_abi.classifySystemV(return_type, mod, .ret); | 11154 | const classes = x86_64_abi.classifySystemV(return_type, mod, .ret); |
| 11299 | if (classes[0] == .memory) { | 11155 | if (classes[0] == .memory) return .void; |
| 11300 | return o.context.voidType(); | 11156 | var types_index: u32 = 0; |
| 11301 | } | 11157 | var types_buffer: [8]Builder.Type = undefined; |
| 11302 | var llvm_types_buffer: [8]*llvm.Type = undefined; | | |
| 11303 | var llvm_types_index: u32 = 0; | | |
| 11304 | for (classes) |class| { | 11158 | for (classes) |class| { |
| 11305 | switch (class) { | 11159 | switch (class) { |
| 11306 | .integer => { | 11160 | .integer => { |
| 11307 | llvm_types_buffer[llvm_types_index] = o.context.intType(64); | 11161 | types_buffer[types_index] = .i64; |
| 11308 | llvm_types_index += 1; | 11162 | types_index += 1; |
| 11309 | }, | 11163 | }, |
| 11310 | .sse, .sseup => { | 11164 | .sse, .sseup => { |
| 11311 | llvm_types_buffer[llvm_types_index] = o.context.doubleType(); | 11165 | types_buffer[types_index] = .double; |
| 11312 | llvm_types_index += 1; | 11166 | types_index += 1; |
| 11313 | }, | 11167 | }, |
| 11314 | .float => { | 11168 | .float => { |
| 11315 | llvm_types_buffer[llvm_types_index] = o.context.floatType(); | 11169 | types_buffer[types_index] = .float; |
| 11316 | llvm_types_index += 1; | 11170 | types_index += 1; |
| 11317 | }, | 11171 | }, |
| 11318 | .float_combine => { | 11172 | .float_combine => { |
| 11319 | llvm_types_buffer[llvm_types_index] = o.context.floatType().vectorType(2); | 11173 | types_buffer[types_index] = try o.builder.vectorType(.normal, 2, .float); |
| 11320 | llvm_types_index += 1; | 11174 | types_index += 1; |
| 11321 | }, | 11175 | }, |
| 11322 | .x87 => { | 11176 | .x87 => { |
| 11323 | if (llvm_types_index != 0 or classes[2] != .none) { | 11177 | if (types_index != 0 or classes[2] != .none) return .void; |
| 11324 | return o.context.voidType(); | 11178 | types_buffer[types_index] = .x86_fp80; |
| 11325 | } | 11179 | types_index += 1; |
| 11326 | llvm_types_buffer[llvm_types_index] = o.context.x86_fp80Type(); | | |
| 11327 | llvm_types_index += 1; | | |
| 11328 | }, | 11180 | }, |
| 11329 | .x87up => continue, | 11181 | .x87up => continue, |
| 11330 | .complex_x87 => { | 11182 | .complex_x87 => { |
| ... | @@ -11336,10 +11188,9 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type | ... | @@ -11336,10 +11188,9 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type |
| 11336 | } | 11188 | } |
| 11337 | } | 11189 | } |
| 11338 | if (classes[0] == .integer and classes[1] == .none) { | 11190 | if (classes[0] == .integer and classes[1] == .none) { |
| 11339 | const abi_size = return_type.abiSize(mod); | 11191 | return o.builder.intType(@intCast(return_type.abiSize(mod) * 8)); |
| 11340 | return o.context.intType(@as(c_uint, @intCast(abi_size * 8))); | | |
| 11341 | } | 11192 | } |
| 11342 | return o.context.structType(&llvm_types_buffer, llvm_types_index, .False); | 11193 | return o.builder.structType(.normal, types_buffer[0..types_index]); |
| 11343 | } | 11194 | } |
| 11344 | | 11195 | |
| 11345 | const ParamTypeIterator = struct { | 11196 | const ParamTypeIterator = struct { |
| ... | @@ -11347,7 +11198,8 @@ const ParamTypeIterator = struct { | ... | @@ -11347,7 +11198,8 @@ const ParamTypeIterator = struct { |
| 11347 | fn_info: InternPool.Key.FuncType, | 11198 | fn_info: InternPool.Key.FuncType, |
| 11348 | zig_index: u32, | 11199 | zig_index: u32, |
| 11349 | llvm_index: u32, | 11200 | llvm_index: u32, |
| 11350 | llvm_types_len: u32, | 11201 | types_len: u32, |
| | 11202 | types_buffer: [8]Builder.Type, |
| 11351 | llvm_types_buffer: [8]*llvm.Type, | 11203 | llvm_types_buffer: [8]*llvm.Type, |
| 11352 | byval_attr: bool, | 11204 | byval_attr: bool, |
| 11353 | | 11205 | |
| ... | @@ -11365,7 +11217,7 @@ const ParamTypeIterator = struct { | ... | @@ -11365,7 +11217,7 @@ const ParamTypeIterator = struct { |
| 11365 | i64_array: u8, | 11217 | i64_array: u8, |
| 11366 | }; | 11218 | }; |
| 11367 | | 11219 | |
| 11368 | pub fn next(it: *ParamTypeIterator) ?Lowering { | 11220 | pub fn next(it: *ParamTypeIterator) Allocator.Error!?Lowering { |
| 11369 | if (it.zig_index >= it.fn_info.param_types.len) return null; | 11221 | if (it.zig_index >= it.fn_info.param_types.len) return null; |
| 11370 | const mod = it.object.module; | 11222 | const mod = it.object.module; |
| 11371 | const ip = &mod.intern_pool; | 11223 | const ip = &mod.intern_pool; |
| ... | @@ -11375,7 +11227,7 @@ const ParamTypeIterator = struct { | ... | @@ -11375,7 +11227,7 @@ const ParamTypeIterator = struct { |
| 11375 | } | 11227 | } |
| 11376 | | 11228 | |
| 11377 | /// `airCall` uses this instead of `next` so that it can take into account variadic functions. | 11229 | /// `airCall` uses this instead of `next` so that it can take into account variadic functions. |
| 11378 | pub fn nextCall(it: *ParamTypeIterator, fg: *FuncGen, args: []const Air.Inst.Ref) ?Lowering { | 11230 | pub fn nextCall(it: *ParamTypeIterator, fg: *FuncGen, args: []const Air.Inst.Ref) Allocator.Error!?Lowering { |
| 11379 | const mod = it.object.module; | 11231 | const mod = it.object.module; |
| 11380 | const ip = &mod.intern_pool; | 11232 | const ip = &mod.intern_pool; |
| 11381 | if (it.zig_index >= it.fn_info.param_types.len) { | 11233 | if (it.zig_index >= it.fn_info.param_types.len) { |
| ... | @@ -11389,7 +11241,7 @@ const ParamTypeIterator = struct { | ... | @@ -11389,7 +11241,7 @@ const ParamTypeIterator = struct { |
| 11389 | } | 11241 | } |
| 11390 | } | 11242 | } |
| 11391 | | 11243 | |
| 11392 | fn nextInner(it: *ParamTypeIterator, ty: Type) ?Lowering { | 11244 | fn nextInner(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering { |
| 11393 | const mod = it.object.module; | 11245 | const mod = it.object.module; |
| 11394 | const target = mod.getTarget(); | 11246 | const target = mod.getTarget(); |
| 11395 | | 11247 | |
| ... | @@ -11444,8 +11296,9 @@ const ParamTypeIterator = struct { | ... | @@ -11444,8 +11296,9 @@ const ParamTypeIterator = struct { |
| 11444 | .float_array => |len| return Lowering{ .float_array = len }, | 11296 | .float_array => |len| return Lowering{ .float_array = len }, |
| 11445 | .byval => return .byval, | 11297 | .byval => return .byval, |
| 11446 | .integer => { | 11298 | .integer => { |
| 11447 | it.llvm_types_len = 1; | 11299 | it.types_len = 1; |
| 11448 | it.llvm_types_buffer[0] = it.object.context.intType(64); | 11300 | it.types_buffer[0] = .i64; |
| | 11301 | it.llvm_types_buffer[0] = it.types_buffer[0].toLlvm(&it.object.builder); |
| 11449 | return .multiple_llvm_types; | 11302 | return .multiple_llvm_types; |
| 11450 | }, | 11303 | }, |
| 11451 | .double_integer => return Lowering{ .i64_array = 2 }, | 11304 | .double_integer => return Lowering{ .i64_array = 2 }, |
| ... | @@ -11539,7 +11392,7 @@ const ParamTypeIterator = struct { | ... | @@ -11539,7 +11392,7 @@ const ParamTypeIterator = struct { |
| 11539 | } | 11392 | } |
| 11540 | } | 11393 | } |
| 11541 | | 11394 | |
| 11542 | fn nextSystemV(it: *ParamTypeIterator, ty: Type) ?Lowering { | 11395 | fn nextSystemV(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering { |
| 11543 | const mod = it.object.module; | 11396 | const mod = it.object.module; |
| 11544 | const classes = x86_64_abi.classifySystemV(ty, mod, .arg); | 11397 | const classes = x86_64_abi.classifySystemV(ty, mod, .arg); |
| 11545 | if (classes[0] == .memory) { | 11398 | if (classes[0] == .memory) { |
| ... | @@ -11553,25 +11406,34 @@ const ParamTypeIterator = struct { | ... | @@ -11553,25 +11406,34 @@ const ParamTypeIterator = struct { |
| 11553 | it.llvm_index += 1; | 11406 | it.llvm_index += 1; |
| 11554 | return .byval; | 11407 | return .byval; |
| 11555 | } | 11408 | } |
| | 11409 | var types_index: u32 = 0; |
| | 11410 | var types_buffer: [8]Builder.Type = undefined; |
| 11556 | var llvm_types_buffer: [8]*llvm.Type = undefined; | 11411 | var llvm_types_buffer: [8]*llvm.Type = undefined; |
| 11557 | var llvm_types_index: u32 = 0; | | |
| 11558 | for (classes) |class| { | 11412 | for (classes) |class| { |
| 11559 | switch (class) { | 11413 | switch (class) { |
| 11560 | .integer => { | 11414 | .integer => { |
| 11561 | llvm_types_buffer[llvm_types_index] = it.object.context.intType(64); | 11415 | types_buffer[types_index] = .i64; |
| 11562 | llvm_types_index += 1; | 11416 | llvm_types_buffer[types_index] = |
| | 11417 | types_buffer[types_index].toLlvm(&it.object.builder); |
| | 11418 | types_index += 1; |
| 11563 | }, | 11419 | }, |
| 11564 | .sse, .sseup => { | 11420 | .sse, .sseup => { |
| 11565 | llvm_types_buffer[llvm_types_index] = it.object.context.doubleType(); | 11421 | types_buffer[types_index] = .double; |
| 11566 | llvm_types_index += 1; | 11422 | llvm_types_buffer[types_index] = |
| | 11423 | types_buffer[types_index].toLlvm(&it.object.builder); |
| | 11424 | types_index += 1; |
| 11567 | }, | 11425 | }, |
| 11568 | .float => { | 11426 | .float => { |
| 11569 | llvm_types_buffer[llvm_types_index] = it.object.context.floatType(); | 11427 | types_buffer[types_index] = .float; |
| 11570 | llvm_types_index += 1; | 11428 | llvm_types_buffer[types_index] = |
| | 11429 | types_buffer[types_index].toLlvm(&it.object.builder); |
| | 11430 | types_index += 1; |
| 11571 | }, | 11431 | }, |
| 11572 | .float_combine => { | 11432 | .float_combine => { |
| 11573 | llvm_types_buffer[llvm_types_index] = it.object.context.floatType().vectorType(2); | 11433 | types_buffer[types_index] = try it.object.builder.vectorType(.normal, 2, .float); |
| 11574 | llvm_types_index += 1; | 11434 | llvm_types_buffer[types_index] = |
| | 11435 | types_buffer[types_index].toLlvm(&it.object.builder); |
| | 11436 | types_index += 1; |
| 11575 | }, | 11437 | }, |
| 11576 | .x87 => { | 11438 | .x87 => { |
| 11577 | it.zig_index += 1; | 11439 | it.zig_index += 1; |
| ... | @@ -11593,9 +11455,10 @@ const ParamTypeIterator = struct { | ... | @@ -11593,9 +11455,10 @@ const ParamTypeIterator = struct { |
| 11593 | it.llvm_index += 1; | 11455 | it.llvm_index += 1; |
| 11594 | return .abi_sized_int; | 11456 | return .abi_sized_int; |
| 11595 | } | 11457 | } |
| | 11458 | it.types_len = types_index; |
| | 11459 | it.types_buffer = types_buffer; |
| 11596 | it.llvm_types_buffer = llvm_types_buffer; | 11460 | it.llvm_types_buffer = llvm_types_buffer; |
| 11597 | it.llvm_types_len = llvm_types_index; | 11461 | it.llvm_index += types_index; |
| 11598 | it.llvm_index += llvm_types_index; | | |
| 11599 | it.zig_index += 1; | 11462 | it.zig_index += 1; |
| 11600 | return .multiple_llvm_types; | 11463 | return .multiple_llvm_types; |
| 11601 | } | 11464 | } |
| ... | @@ -11607,8 +11470,9 @@ fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) ParamTyp | ... | @@ -11607,8 +11470,9 @@ fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) ParamTyp |
| 11607 | .fn_info = fn_info, | 11470 | .fn_info = fn_info, |
| 11608 | .zig_index = 0, | 11471 | .zig_index = 0, |
| 11609 | .llvm_index = 0, | 11472 | .llvm_index = 0, |
| | 11473 | .types_len = 0, |
| | 11474 | .types_buffer = undefined, |
| 11610 | .llvm_types_buffer = undefined, | 11475 | .llvm_types_buffer = undefined, |
| 11611 | .llvm_types_len = 0, | | |
| 11612 | .byval_attr = false, | 11476 | .byval_attr = false, |
| 11613 | }; | 11477 | }; |
| 11614 | } | 11478 | } |
| ... | @@ -11905,7 +11769,7 @@ fn buildAllocaInner( | ... | @@ -11905,7 +11769,7 @@ fn buildAllocaInner( |
| 11905 | } | 11769 | } |
| 11906 | builder.clearCurrentDebugLocation(); | 11770 | builder.clearCurrentDebugLocation(); |
| 11907 | | 11771 | |
| 11908 | break :blk builder.buildAllocaInAddressSpace(llvm_ty, address_space, ""); | 11772 | break :blk builder.buildAllocaInAddressSpace(llvm_ty, @intFromEnum(address_space), ""); |
| 11909 | }; | 11773 | }; |
| 11910 | | 11774 | |
| 11911 | if (maybe_alignment) |alignment| { | 11775 | if (maybe_alignment) |alignment| { |
| ... | @@ -11914,7 +11778,7 @@ fn buildAllocaInner( | ... | @@ -11914,7 +11778,7 @@ fn buildAllocaInner( |
| 11914 | | 11778 | |
| 11915 | // The pointer returned from this function should have the generic address space, | 11779 | // The pointer returned from this function should have the generic address space, |
| 11916 | // if this isn't the case then cast it to the generic address space. | 11780 | // if this isn't the case then cast it to the generic address space. |
| 11917 | if (address_space != llvm.address_space.default) { | 11781 | if (address_space != .default) { |
| 11918 | return builder.buildAddrSpaceCast(alloca, context.pointerType(llvm.address_space.default), ""); | 11782 | return builder.buildAddrSpaceCast(alloca, context.pointerType(llvm.address_space.default), ""); |
| 11919 | } | 11783 | } |
| 11920 | | 11784 | |