| ... | ... | @@ -7,6 +7,7 @@ const math = std.math; |
| 7 | 7 | const native_endian = builtin.cpu.arch.endian(); |
| 8 | 8 | const DW = std.dwarf; |
| 9 | 9 | |
| 10 | const Builder = @import("llvm/Builder.zig"); |
| 10 | 11 | const llvm = @import("llvm/bindings.zig"); |
| 11 | 12 | const link = @import("../link.zig"); |
| 12 | 13 | const Compilation = @import("../Compilation.zig"); |
| ... | ... | @@ -338,6 +339,8 @@ fn deleteLlvmGlobal(llvm_global: *llvm.Value) void { |
| 338 | 339 | |
| 339 | 340 | pub const Object = struct { |
| 340 | 341 | gpa: Allocator, |
| 342 | builder: Builder, |
| 343 | |
| 341 | 344 | module: *Module, |
| 342 | 345 | llvm_module: *llvm.Module, |
| 343 | 346 | di_builder: ?*llvm.DIBuilder, |
| ... | ... | @@ -359,7 +362,7 @@ pub const Object = struct { |
| 359 | 362 | /// version of the name and incorrectly get function not found in the llvm module. |
| 360 | 363 | /// * it works for functions not all globals. |
| 361 | 364 | /// Therefore, this table keeps track of the mapping. |
| 362 | | decl_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *llvm.Value), |
| 365 | decl_map: std.AutoHashMapUnmanaged(Module.Decl.Index, Builder.Global.Index), |
| 363 | 366 | /// Serves the same purpose as `decl_map` but only used for the `is_named_enum_value` instruction. |
| 364 | 367 | named_enum_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *llvm.Value), |
| 365 | 368 | /// Maps Zig types to LLVM types. The table memory is backed by the GPA of |
| ... | ... | @@ -394,13 +397,19 @@ pub const Object = struct { |
| 394 | 397 | } |
| 395 | 398 | |
| 396 | 399 | pub fn init(gpa: Allocator, options: link.Options) !Object { |
| 397 | | const context = llvm.Context.create(); |
| 398 | | errdefer context.dispose(); |
| 400 | var builder = Builder{ |
| 401 | .gpa = gpa, |
| 402 | .use_lib_llvm = options.use_lib_llvm, |
| 403 | |
| 404 | .llvm_context = llvm.Context.create(), |
| 405 | .llvm_module = undefined, |
| 406 | }; |
| 407 | errdefer builder.llvm_context.dispose(); |
| 399 | 408 | |
| 400 | 409 | initializeLLVMTarget(options.target.cpu.arch); |
| 401 | 410 | |
| 402 | | const llvm_module = llvm.Module.createWithName(options.root_name.ptr, context); |
| 403 | | errdefer llvm_module.dispose(); |
| 411 | builder.llvm_module = llvm.Module.createWithName(options.root_name.ptr, builder.llvm_context); |
| 412 | errdefer builder.llvm_module.dispose(); |
| 404 | 413 | |
| 405 | 414 | const llvm_target_triple = try targetTriple(gpa, options.target); |
| 406 | 415 | defer gpa.free(llvm_target_triple); |
| ... | ... | @@ -414,7 +423,7 @@ pub const Object = struct { |
| 414 | 423 | return error.InvalidLlvmTriple; |
| 415 | 424 | } |
| 416 | 425 | |
| 417 | | llvm_module.setTarget(llvm_target_triple.ptr); |
| 426 | builder.llvm_module.setTarget(llvm_target_triple.ptr); |
| 418 | 427 | var opt_di_builder: ?*llvm.DIBuilder = null; |
| 419 | 428 | errdefer if (opt_di_builder) |di_builder| di_builder.dispose(); |
| 420 | 429 | |
| ... | ... | @@ -422,10 +431,10 @@ pub const Object = struct { |
| 422 | 431 | |
| 423 | 432 | if (!options.strip) { |
| 424 | 433 | switch (options.target.ofmt) { |
| 425 | | .coff => llvm_module.addModuleCodeViewFlag(), |
| 426 | | else => llvm_module.addModuleDebugInfoFlag(options.dwarf_format == std.dwarf.Format.@"64"), |
| 434 | .coff => builder.llvm_module.addModuleCodeViewFlag(), |
| 435 | else => builder.llvm_module.addModuleDebugInfoFlag(options.dwarf_format == std.dwarf.Format.@"64"), |
| 427 | 436 | } |
| 428 | | const di_builder = llvm_module.createDIBuilder(true); |
| 437 | const di_builder = builder.llvm_module.createDIBuilder(true); |
| 429 | 438 | opt_di_builder = di_builder; |
| 430 | 439 | |
| 431 | 440 | // Don't use the version string here; LLVM misparses it when it |
| ... | ... | @@ -508,24 +517,35 @@ pub const Object = struct { |
| 508 | 517 | const target_data = target_machine.createTargetDataLayout(); |
| 509 | 518 | errdefer target_data.dispose(); |
| 510 | 519 | |
| 511 | | llvm_module.setModuleDataLayout(target_data); |
| 520 | builder.llvm_module.setModuleDataLayout(target_data); |
| 512 | 521 | |
| 513 | | if (options.pic) llvm_module.setModulePICLevel(); |
| 514 | | if (options.pie) llvm_module.setModulePIELevel(); |
| 515 | | if (code_model != .Default) llvm_module.setModuleCodeModel(code_model); |
| 522 | if (options.pic) builder.llvm_module.setModulePICLevel(); |
| 523 | if (options.pie) builder.llvm_module.setModulePIELevel(); |
| 524 | if (code_model != .Default) builder.llvm_module.setModuleCodeModel(code_model); |
| 516 | 525 | |
| 517 | 526 | if (options.opt_bisect_limit >= 0) { |
| 518 | | context.setOptBisectLimit(std.math.lossyCast(c_int, options.opt_bisect_limit)); |
| 527 | builder.llvm_context.setOptBisectLimit(std.math.lossyCast(c_int, options.opt_bisect_limit)); |
| 519 | 528 | } |
| 520 | 529 | |
| 530 | try builder.init(); |
| 531 | errdefer builder.deinit(); |
| 532 | builder.source_filename = try builder.string(options.root_name); |
| 533 | builder.data_layout = rep: { |
| 534 | const rep = target_data.stringRep(); |
| 535 | defer llvm.disposeMessage(rep); |
| 536 | break :rep try builder.string(std.mem.span(rep)); |
| 537 | }; |
| 538 | builder.target_triple = try builder.string(llvm_target_triple); |
| 539 | |
| 521 | 540 | return Object{ |
| 522 | 541 | .gpa = gpa, |
| 542 | .builder = builder, |
| 523 | 543 | .module = options.module.?, |
| 524 | | .llvm_module = llvm_module, |
| 544 | .llvm_module = builder.llvm_module, |
| 525 | 545 | .di_map = .{}, |
| 526 | 546 | .di_builder = opt_di_builder, |
| 527 | 547 | .di_compile_unit = di_compile_unit, |
| 528 | | .context = context, |
| 548 | .context = builder.llvm_context, |
| 529 | 549 | .target_machine = target_machine, |
| 530 | 550 | .target_data = target_data, |
| 531 | 551 | .target = options.target, |
| ... | ... | @@ -553,6 +573,7 @@ pub const Object = struct { |
| 553 | 573 | self.named_enum_map.deinit(gpa); |
| 554 | 574 | self.type_map.deinit(gpa); |
| 555 | 575 | self.extern_collisions.deinit(gpa); |
| 576 | self.builder.deinit(); |
| 556 | 577 | self.* = undefined; |
| 557 | 578 | } |
| 558 | 579 | |
| ... | ... | @@ -671,34 +692,36 @@ pub const Object = struct { |
| 671 | 692 | |
| 672 | 693 | // This map has externs with incorrect symbol names. |
| 673 | 694 | for (object.extern_collisions.keys()) |decl_index| { |
| 674 | | const entry = object.decl_map.getEntry(decl_index) orelse continue; |
| 675 | | const llvm_global = entry.value_ptr.*; |
| 695 | const global = object.decl_map.get(decl_index) orelse continue; |
| 696 | const llvm_global = global.toLlvm(&object.builder); |
| 676 | 697 | // Same logic as below but for externs instead of exports. |
| 677 | | const decl = mod.declPtr(decl_index); |
| 678 | | const other_global = object.getLlvmGlobal(mod.intern_pool.stringToSlice(decl.name)) orelse continue; |
| 679 | | if (other_global == llvm_global) continue; |
| 698 | const decl_name = object.builder.stringIfExists(mod.intern_pool.stringToSlice(mod.declPtr(decl_index).name)) orelse continue; |
| 699 | const other_global = object.builder.getGlobal(decl_name) orelse continue; |
| 700 | const other_llvm_global = other_global.toLlvm(&object.builder); |
| 701 | if (other_llvm_global == llvm_global) continue; |
| 680 | 702 | |
| 681 | | llvm_global.replaceAllUsesWith(other_global); |
| 703 | llvm_global.replaceAllUsesWith(other_llvm_global); |
| 682 | 704 | deleteLlvmGlobal(llvm_global); |
| 683 | | entry.value_ptr.* = other_global; |
| 705 | object.builder.llvm_globals.items[@intFromEnum(global)] = other_llvm_global; |
| 684 | 706 | } |
| 685 | 707 | object.extern_collisions.clearRetainingCapacity(); |
| 686 | 708 | |
| 687 | | const export_keys = mod.decl_exports.keys(); |
| 688 | | for (mod.decl_exports.values(), 0..) |export_list, i| { |
| 689 | | const decl_index = export_keys[i]; |
| 690 | | const llvm_global = object.decl_map.get(decl_index) orelse continue; |
| 709 | for (mod.decl_exports.keys(), mod.decl_exports.values()) |decl_index, export_list| { |
| 710 | const global = object.decl_map.get(decl_index) orelse continue; |
| 711 | const llvm_global = global.toLlvm(&object.builder); |
| 691 | 712 | for (export_list.items) |exp| { |
| 692 | 713 | // Detect if the LLVM global has already been created as an extern. In such |
| 693 | 714 | // case, we need to replace all uses of it with this exported global. |
| 694 | | const exp_name = mod.intern_pool.stringToSlice(exp.opts.name); |
| 715 | const exp_name = object.builder.stringIfExists(mod.intern_pool.stringToSlice(exp.opts.name)) orelse continue; |
| 695 | 716 | |
| 696 | | const other_global = object.getLlvmGlobal(exp_name.ptr) orelse continue; |
| 697 | | if (other_global == llvm_global) continue; |
| 717 | const other_global = object.builder.getGlobal(exp_name) orelse continue; |
| 718 | const other_llvm_global = other_global.toLlvm(&object.builder); |
| 719 | if (other_llvm_global == llvm_global) continue; |
| 698 | 720 | |
| 699 | | other_global.replaceAllUsesWith(llvm_global); |
| 700 | | llvm_global.takeName(other_global); |
| 701 | | deleteLlvmGlobal(other_global); |
| 721 | other_llvm_global.replaceAllUsesWith(llvm_global); |
| 722 | try global.takeName(&object.builder, other_global); |
| 723 | deleteLlvmGlobal(other_llvm_global); |
| 724 | object.builder.llvm_globals.items[@intFromEnum(other_global)] = llvm_global; |
| 702 | 725 | // Problem: now we need to replace in the decl_map that |
| 703 | 726 | // the extern decl index points to this new global. However we don't |
| 704 | 727 | // know the decl index. |
| ... | ... | @@ -813,6 +836,12 @@ pub const Object = struct { |
| 813 | 836 | emit_asm_msg, emit_bin_msg, emit_llvm_ir_msg, emit_llvm_bc_msg, |
| 814 | 837 | }); |
| 815 | 838 | |
| 839 | { |
| 840 | const writer = std.io.getStdErr().writer(); |
| 841 | try writer.writeAll("\n" ++ "-" ** 200 ++ "\n\n"); |
| 842 | try self.builder.dump(writer); |
| 843 | } |
| 844 | |
| 816 | 845 | // Unfortunately, LLVM shits the bed when we ask for both binary and assembly. |
| 817 | 846 | // So we call the entire pipeline multiple times if this is requested. |
| 818 | 847 | var error_message: [*:0]const u8 = undefined; |
| ... | ... | @@ -884,7 +913,9 @@ pub const Object = struct { |
| 884 | 913 | .err_msg = null, |
| 885 | 914 | }; |
| 886 | 915 | |
| 887 | | const llvm_func = try o.resolveLlvmFunction(decl_index); |
| 916 | const function_index = try o.resolveLlvmFunction(decl_index); |
| 917 | const function = function_index.ptr(&o.builder); |
| 918 | const llvm_func = function.global.toLlvm(&o.builder); |
| 888 | 919 | |
| 889 | 920 | if (func.analysis(ip).is_noinline) { |
| 890 | 921 | o.addFnAttr(llvm_func, "noinline"); |
| ... | ... | @@ -932,6 +963,7 @@ pub const Object = struct { |
| 932 | 963 | |
| 933 | 964 | const builder = o.context.createBuilder(); |
| 934 | 965 | |
| 966 | function.body = {}; |
| 935 | 967 | const entry_block = o.context.appendBasicBlock(llvm_func, "Entry"); |
| 936 | 968 | builder.positionBuilderAtEnd(entry_block); |
| 937 | 969 | |
| ... | ... | @@ -988,7 +1020,7 @@ pub const Object = struct { |
| 988 | 1020 | }, |
| 989 | 1021 | .byref => { |
| 990 | 1022 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); |
| 991 | | const param_llvm_ty = try o.lowerType(param_ty); |
| 1023 | const param_llvm_ty = try o.lowerLlvmType(param_ty); |
| 992 | 1024 | const param = llvm_func.getParam(llvm_arg_i); |
| 993 | 1025 | const alignment = param_ty.abiAlignment(mod); |
| 994 | 1026 | |
| ... | ... | @@ -1007,7 +1039,7 @@ pub const Object = struct { |
| 1007 | 1039 | }, |
| 1008 | 1040 | .byref_mut => { |
| 1009 | 1041 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); |
| 1010 | | const param_llvm_ty = try o.lowerType(param_ty); |
| 1042 | const param_llvm_ty = try o.lowerLlvmType(param_ty); |
| 1011 | 1043 | const param = llvm_func.getParam(llvm_arg_i); |
| 1012 | 1044 | const alignment = param_ty.abiAlignment(mod); |
| 1013 | 1045 | |
| ... | ... | @@ -1030,7 +1062,7 @@ pub const Object = struct { |
| 1030 | 1062 | const param = llvm_func.getParam(llvm_arg_i); |
| 1031 | 1063 | llvm_arg_i += 1; |
| 1032 | 1064 | |
| 1033 | | const param_llvm_ty = try o.lowerType(param_ty); |
| 1065 | const param_llvm_ty = try o.lowerLlvmType(param_ty); |
| 1034 | 1066 | const abi_size = @as(c_uint, @intCast(param_ty.abiSize(mod))); |
| 1035 | 1067 | const int_llvm_ty = o.context.intType(abi_size * 8); |
| 1036 | 1068 | const alignment = @max( |
| ... | ... | @@ -1075,7 +1107,7 @@ pub const Object = struct { |
| 1075 | 1107 | const len_param = llvm_func.getParam(llvm_arg_i); |
| 1076 | 1108 | llvm_arg_i += 1; |
| 1077 | 1109 | |
| 1078 | | const slice_llvm_ty = try o.lowerType(param_ty); |
| 1110 | const slice_llvm_ty = try o.lowerLlvmType(param_ty); |
| 1079 | 1111 | const partial = builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr_param, 0, ""); |
| 1080 | 1112 | const aggregate = builder.buildInsertValue(partial, len_param, 1, ""); |
| 1081 | 1113 | try args.append(aggregate); |
| ... | ... | @@ -1084,7 +1116,7 @@ pub const Object = struct { |
| 1084 | 1116 | assert(!it.byval_attr); |
| 1085 | 1117 | const field_types = it.llvm_types_buffer[0..it.llvm_types_len]; |
| 1086 | 1118 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); |
| 1087 | | const param_llvm_ty = try o.lowerType(param_ty); |
| 1119 | const param_llvm_ty = try o.lowerLlvmType(param_ty); |
| 1088 | 1120 | const param_alignment = param_ty.abiAlignment(mod); |
| 1089 | 1121 | const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, param_alignment, target); |
| 1090 | 1122 | const llvm_ty = o.context.structType(field_types.ptr, @as(c_uint, @intCast(field_types.len)), .False); |
| ... | ... | @@ -1115,7 +1147,7 @@ pub const Object = struct { |
| 1115 | 1147 | }, |
| 1116 | 1148 | .float_array => { |
| 1117 | 1149 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); |
| 1118 | | const param_llvm_ty = try o.lowerType(param_ty); |
| 1150 | const param_llvm_ty = try o.lowerLlvmType(param_ty); |
| 1119 | 1151 | const param = llvm_func.getParam(llvm_arg_i); |
| 1120 | 1152 | llvm_arg_i += 1; |
| 1121 | 1153 | |
| ... | ... | @@ -1133,7 +1165,7 @@ pub const Object = struct { |
| 1133 | 1165 | }, |
| 1134 | 1166 | .i32_array, .i64_array => { |
| 1135 | 1167 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); |
| 1136 | | const param_llvm_ty = try o.lowerType(param_ty); |
| 1168 | const param_llvm_ty = try o.lowerLlvmType(param_ty); |
| 1137 | 1169 | const param = llvm_func.getParam(llvm_arg_i); |
| 1138 | 1170 | llvm_arg_i += 1; |
| 1139 | 1171 | |
| ... | ... | @@ -1243,14 +1275,6 @@ pub const Object = struct { |
| 1243 | 1275 | try self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index)); |
| 1244 | 1276 | } |
| 1245 | 1277 | |
| 1246 | | /// TODO replace this with a call to `Module::getNamedValue`. This will require adding |
| 1247 | | /// a new wrapper in zig_llvm.h/zig_llvm.cpp. |
| 1248 | | fn getLlvmGlobal(o: Object, name: [*:0]const u8) ?*llvm.Value { |
| 1249 | | if (o.llvm_module.getNamedFunction(name)) |x| return x; |
| 1250 | | if (o.llvm_module.getNamedGlobal(name)) |x| return x; |
| 1251 | | return null; |
| 1252 | | } |
| 1253 | | |
| 1254 | 1278 | pub fn updateDeclExports( |
| 1255 | 1279 | self: *Object, |
| 1256 | 1280 | mod: *Module, |
| ... | ... | @@ -1260,45 +1284,49 @@ pub const Object = struct { |
| 1260 | 1284 | const gpa = mod.gpa; |
| 1261 | 1285 | // If the module does not already have the function, we ignore this function call |
| 1262 | 1286 | // because we call `updateDeclExports` at the end of `updateFunc` and `updateDecl`. |
| 1263 | | const llvm_global = self.decl_map.get(decl_index) orelse return; |
| 1287 | const global_index = self.decl_map.get(decl_index) orelse return; |
| 1288 | const llvm_global = global_index.toLlvm(&self.builder); |
| 1264 | 1289 | const decl = mod.declPtr(decl_index); |
| 1265 | 1290 | if (decl.isExtern(mod)) { |
| 1266 | | var free_decl_name = false; |
| 1267 | 1291 | const decl_name = decl_name: { |
| 1268 | 1292 | const decl_name = mod.intern_pool.stringToSlice(decl.name); |
| 1269 | 1293 | |
| 1270 | 1294 | if (mod.getTarget().isWasm() and try decl.isFunction(mod)) { |
| 1271 | 1295 | if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| { |
| 1272 | 1296 | if (!std.mem.eql(u8, lib_name, "c")) { |
| 1273 | | free_decl_name = true; |
| 1274 | | break :decl_name try std.fmt.allocPrintZ(gpa, "{s}|{s}", .{ |
| 1275 | | decl_name, lib_name, |
| 1276 | | }); |
| 1297 | break :decl_name try self.builder.fmt("{s}|{s}", .{ decl_name, lib_name }); |
| 1277 | 1298 | } |
| 1278 | 1299 | } |
| 1279 | 1300 | } |
| 1280 | 1301 | |
| 1281 | | break :decl_name decl_name; |
| 1302 | break :decl_name try self.builder.string(decl_name); |
| 1282 | 1303 | }; |
| 1283 | | defer if (free_decl_name) gpa.free(decl_name); |
| 1284 | 1304 | |
| 1285 | | llvm_global.setValueName(decl_name); |
| 1286 | | if (self.getLlvmGlobal(decl_name)) |other_global| { |
| 1287 | | if (other_global != llvm_global) { |
| 1305 | if (self.builder.getGlobal(decl_name)) |other_global| { |
| 1306 | if (other_global.toLlvm(&self.builder) != llvm_global) { |
| 1288 | 1307 | try self.extern_collisions.put(gpa, decl_index, {}); |
| 1289 | 1308 | } |
| 1290 | 1309 | } |
| 1310 | |
| 1311 | try global_index.rename(&self.builder, decl_name); |
| 1312 | const decl_name_slice = decl_name.toSlice(&self.builder).?; |
| 1313 | const global = global_index.ptr(&self.builder); |
| 1314 | global.unnamed_addr = .none; |
| 1291 | 1315 | llvm_global.setUnnamedAddr(.False); |
| 1316 | global.linkage = .external; |
| 1292 | 1317 | llvm_global.setLinkage(.External); |
| 1293 | | if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.Default); |
| 1318 | if (mod.wantDllExports()) { |
| 1319 | global.dll_storage_class = .default; |
| 1320 | llvm_global.setDLLStorageClass(.Default); |
| 1321 | } |
| 1294 | 1322 | if (self.di_map.get(decl)) |di_node| { |
| 1295 | 1323 | if (try decl.isFunction(mod)) { |
| 1296 | 1324 | const di_func = @as(*llvm.DISubprogram, @ptrCast(di_node)); |
| 1297 | | const linkage_name = llvm.MDString.get(self.context, decl_name.ptr, decl_name.len); |
| 1325 | const linkage_name = llvm.MDString.get(self.context, decl_name_slice.ptr, decl_name_slice.len); |
| 1298 | 1326 | di_func.replaceLinkageName(linkage_name); |
| 1299 | 1327 | } else { |
| 1300 | 1328 | const di_global = @as(*llvm.DIGlobalVariable, @ptrCast(di_node)); |
| 1301 | | const linkage_name = llvm.MDString.get(self.context, decl_name.ptr, decl_name.len); |
| 1329 | const linkage_name = llvm.MDString.get(self.context, decl_name_slice.ptr, decl_name_slice.len); |
| 1302 | 1330 | di_global.replaceLinkageName(linkage_name); |
| 1303 | 1331 | } |
| 1304 | 1332 | } |
| ... | ... | @@ -1313,18 +1341,19 @@ pub const Object = struct { |
| 1313 | 1341 | } |
| 1314 | 1342 | } |
| 1315 | 1343 | } else if (exports.len != 0) { |
| 1316 | | const exp_name = mod.intern_pool.stringToSlice(exports[0].opts.name); |
| 1317 | | llvm_global.setValueName2(exp_name.ptr, exp_name.len); |
| 1344 | const exp_name = try self.builder.string(mod.intern_pool.stringToSlice(exports[0].opts.name)); |
| 1345 | try global_index.rename(&self.builder, exp_name); |
| 1318 | 1346 | llvm_global.setUnnamedAddr(.False); |
| 1319 | 1347 | if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.DLLExport); |
| 1320 | 1348 | if (self.di_map.get(decl)) |di_node| { |
| 1349 | const exp_name_slice = exp_name.toSlice(&self.builder).?; |
| 1321 | 1350 | if (try decl.isFunction(mod)) { |
| 1322 | 1351 | const di_func = @as(*llvm.DISubprogram, @ptrCast(di_node)); |
| 1323 | | const linkage_name = llvm.MDString.get(self.context, exp_name.ptr, exp_name.len); |
| 1352 | const linkage_name = llvm.MDString.get(self.context, exp_name_slice.ptr, exp_name_slice.len); |
| 1324 | 1353 | di_func.replaceLinkageName(linkage_name); |
| 1325 | 1354 | } else { |
| 1326 | 1355 | const di_global = @as(*llvm.DIGlobalVariable, @ptrCast(di_node)); |
| 1327 | | const linkage_name = llvm.MDString.get(self.context, exp_name.ptr, exp_name.len); |
| 1356 | const linkage_name = llvm.MDString.get(self.context, exp_name_slice.ptr, exp_name_slice.len); |
| 1328 | 1357 | di_global.replaceLinkageName(linkage_name); |
| 1329 | 1358 | } |
| 1330 | 1359 | } |
| ... | ... | @@ -1369,8 +1398,8 @@ pub const Object = struct { |
| 1369 | 1398 | } |
| 1370 | 1399 | } |
| 1371 | 1400 | } else { |
| 1372 | | const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod)); |
| 1373 | | llvm_global.setValueName2(fqn.ptr, fqn.len); |
| 1401 | const fqn = try self.builder.string(mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod))); |
| 1402 | try global_index.rename(&self.builder, fqn); |
| 1374 | 1403 | llvm_global.setLinkage(.Internal); |
| 1375 | 1404 | if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.Default); |
| 1376 | 1405 | llvm_global.setUnnamedAddr(.True); |
| ... | ... | @@ -1386,8 +1415,8 @@ pub const Object = struct { |
| 1386 | 1415 | } |
| 1387 | 1416 | |
| 1388 | 1417 | pub fn freeDecl(self: *Object, decl_index: Module.Decl.Index) void { |
| 1389 | | const llvm_value = self.decl_map.get(decl_index) orelse return; |
| 1390 | | llvm_value.deleteGlobal(); |
| 1418 | const global = self.decl_map.get(decl_index) orelse return; |
| 1419 | global.toLlvm(&self.builder).deleteGlobal(); |
| 1391 | 1420 | } |
| 1392 | 1421 | |
| 1393 | 1422 | fn getDIFile(o: *Object, gpa: Allocator, file: *const Module.File) !*llvm.DIFile { |
| ... | ... | @@ -2459,27 +2488,34 @@ pub const Object = struct { |
| 2459 | 2488 | /// If the llvm function does not exist, create it. |
| 2460 | 2489 | /// Note that this can be called before the function's semantic analysis has |
| 2461 | 2490 | /// completed, so if any attributes rely on that, they must be done in updateFunc, not here. |
| 2462 | | fn resolveLlvmFunction(o: *Object, decl_index: Module.Decl.Index) !*llvm.Value { |
| 2491 | fn resolveLlvmFunction(o: *Object, decl_index: Module.Decl.Index) !Builder.Function.Index { |
| 2463 | 2492 | const mod = o.module; |
| 2464 | 2493 | const gpa = o.gpa; |
| 2465 | 2494 | const decl = mod.declPtr(decl_index); |
| 2466 | 2495 | const zig_fn_type = decl.ty; |
| 2467 | 2496 | const gop = try o.decl_map.getOrPut(gpa, decl_index); |
| 2468 | | if (gop.found_existing) return gop.value_ptr.*; |
| 2497 | if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function; |
| 2469 | 2498 | |
| 2470 | 2499 | assert(decl.has_tv); |
| 2471 | 2500 | const fn_info = mod.typeToFunc(zig_fn_type).?; |
| 2472 | 2501 | const target = mod.getTarget(); |
| 2473 | 2502 | const sret = firstParamSRet(fn_info, mod); |
| 2474 | 2503 | |
| 2475 | | const fn_type = try o.lowerType(zig_fn_type); |
| 2504 | const fn_type = try o.lowerLlvmType(zig_fn_type); |
| 2476 | 2505 | |
| 2477 | | const fqn = try decl.getFullyQualifiedName(mod); |
| 2478 | 2506 | const ip = &mod.intern_pool; |
| 2507 | const fqn = try o.builder.string(ip.stringToSlice(try decl.getFullyQualifiedName(mod))); |
| 2479 | 2508 | |
| 2480 | 2509 | const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); |
| 2481 | | const llvm_fn = o.llvm_module.addFunctionInAddressSpace(ip.stringToSlice(fqn), fn_type, llvm_addrspace); |
| 2482 | | gop.value_ptr.* = llvm_fn; |
| 2510 | const llvm_fn = o.llvm_module.addFunctionInAddressSpace(fqn.toSlice(&o.builder).?, fn_type, llvm_addrspace); |
| 2511 | |
| 2512 | var global = Builder.Global{ |
| 2513 | .type = .void, |
| 2514 | .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) }, |
| 2515 | }; |
| 2516 | var function = Builder.Function{ |
| 2517 | .global = @enumFromInt(o.builder.globals.count()), |
| 2518 | }; |
| 2483 | 2519 | |
| 2484 | 2520 | const is_extern = decl.isExtern(mod); |
| 2485 | 2521 | if (!is_extern) { |
| ... | ... | @@ -2500,7 +2536,7 @@ pub const Object = struct { |
| 2500 | 2536 | o.addArgAttr(llvm_fn, 0, "nonnull"); // Sret pointers must not be address 0 |
| 2501 | 2537 | o.addArgAttr(llvm_fn, 0, "noalias"); |
| 2502 | 2538 | |
| 2503 | | const raw_llvm_ret_ty = try o.lowerType(fn_info.return_type.toType()); |
| 2539 | const raw_llvm_ret_ty = try o.lowerLlvmType(fn_info.return_type.toType()); |
| 2504 | 2540 | llvm_fn.addSretAttr(raw_llvm_ret_ty); |
| 2505 | 2541 | } |
| 2506 | 2542 | |
| ... | ... | @@ -2554,7 +2590,7 @@ pub const Object = struct { |
| 2554 | 2590 | }, |
| 2555 | 2591 | .byref => { |
| 2556 | 2592 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1]; |
| 2557 | | const param_llvm_ty = try o.lowerType(param_ty.toType()); |
| 2593 | const param_llvm_ty = try o.lowerLlvmType(param_ty.toType()); |
| 2558 | 2594 | const alignment = param_ty.toType().abiAlignment(mod); |
| 2559 | 2595 | o.addByRefParamAttrs(llvm_fn, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty); |
| 2560 | 2596 | }, |
| ... | ... | @@ -2576,7 +2612,10 @@ pub const Object = struct { |
| 2576 | 2612 | }; |
| 2577 | 2613 | } |
| 2578 | 2614 | |
| 2579 | | return llvm_fn; |
| 2615 | try o.builder.llvm_globals.append(o.gpa, llvm_fn); |
| 2616 | gop.value_ptr.* = try o.builder.addGlobal(fqn, global); |
| 2617 | try o.builder.functions.append(o.gpa, function); |
| 2618 | return global.kind.function; |
| 2580 | 2619 | } |
| 2581 | 2620 | |
| 2582 | 2621 | fn addCommonFnAttributes(o: *Object, llvm_fn: *llvm.Value) void { |
| ... | ... | @@ -2622,60 +2661,89 @@ pub const Object = struct { |
| 2622 | 2661 | } |
| 2623 | 2662 | } |
| 2624 | 2663 | |
| 2625 | | fn resolveGlobalDecl(o: *Object, decl_index: Module.Decl.Index) Error!*llvm.Value { |
| 2664 | fn resolveGlobalDecl(o: *Object, decl_index: Module.Decl.Index) Error!Builder.Object.Index { |
| 2626 | 2665 | const gop = try o.decl_map.getOrPut(o.gpa, decl_index); |
| 2627 | | if (gop.found_existing) return gop.value_ptr.*; |
| 2666 | if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.object; |
| 2628 | 2667 | errdefer assert(o.decl_map.remove(decl_index)); |
| 2629 | 2668 | |
| 2630 | 2669 | const mod = o.module; |
| 2631 | 2670 | const decl = mod.declPtr(decl_index); |
| 2632 | | const fqn = try decl.getFullyQualifiedName(mod); |
| 2671 | const fqn = try o.builder.string(mod.intern_pool.stringToSlice( |
| 2672 | try decl.getFullyQualifiedName(mod), |
| 2673 | )); |
| 2633 | 2674 | |
| 2634 | 2675 | const target = mod.getTarget(); |
| 2635 | 2676 | |
| 2636 | | const llvm_type = try o.lowerType(decl.ty); |
| 2677 | const llvm_type = try o.lowerLlvmType(decl.ty); |
| 2637 | 2678 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target); |
| 2638 | 2679 | |
| 2680 | var global = Builder.Global{ |
| 2681 | .type = .void, |
| 2682 | .kind = .{ .object = @enumFromInt(o.builder.objects.items.len) }, |
| 2683 | }; |
| 2684 | var object = Builder.Object{ |
| 2685 | .global = @enumFromInt(o.builder.globals.count()), |
| 2686 | }; |
| 2687 | |
| 2688 | const is_extern = decl.isExtern(mod); |
| 2689 | const name = if (is_extern) |
| 2690 | try o.builder.string(mod.intern_pool.stringToSlice(decl.name)) |
| 2691 | else |
| 2692 | fqn; |
| 2639 | 2693 | const llvm_global = o.llvm_module.addGlobalInAddressSpace( |
| 2640 | 2694 | llvm_type, |
| 2641 | | mod.intern_pool.stringToSlice(fqn), |
| 2695 | fqn.toSlice(&o.builder).?, |
| 2642 | 2696 | llvm_actual_addrspace, |
| 2643 | 2697 | ); |
| 2644 | | gop.value_ptr.* = llvm_global; |
| 2645 | 2698 | |
| 2646 | 2699 | // This is needed for declarations created by `@extern`. |
| 2647 | | if (decl.isExtern(mod)) { |
| 2648 | | llvm_global.setValueName(mod.intern_pool.stringToSlice(decl.name)); |
| 2700 | if (is_extern) { |
| 2701 | global.unnamed_addr = .none; |
| 2649 | 2702 | llvm_global.setUnnamedAddr(.False); |
| 2703 | global.linkage = .external; |
| 2650 | 2704 | llvm_global.setLinkage(.External); |
| 2651 | 2705 | if (decl.val.getVariable(mod)) |variable| { |
| 2652 | 2706 | const single_threaded = mod.comp.bin_file.options.single_threaded; |
| 2653 | 2707 | if (variable.is_threadlocal and !single_threaded) { |
| 2708 | object.thread_local = .generaldynamic; |
| 2654 | 2709 | llvm_global.setThreadLocalMode(.GeneralDynamicTLSModel); |
| 2655 | 2710 | } else { |
| 2711 | object.thread_local = .none; |
| 2656 | 2712 | llvm_global.setThreadLocalMode(.NotThreadLocal); |
| 2657 | 2713 | } |
| 2658 | | if (variable.is_weak_linkage) llvm_global.setLinkage(.ExternalWeak); |
| 2714 | if (variable.is_weak_linkage) { |
| 2715 | global.linkage = .extern_weak; |
| 2716 | llvm_global.setLinkage(.ExternalWeak); |
| 2717 | } |
| 2659 | 2718 | } |
| 2660 | 2719 | } else { |
| 2720 | global.linkage = .internal; |
| 2661 | 2721 | llvm_global.setLinkage(.Internal); |
| 2722 | global.unnamed_addr = .unnamed_addr; |
| 2662 | 2723 | llvm_global.setUnnamedAddr(.True); |
| 2663 | 2724 | } |
| 2664 | 2725 | |
| 2665 | | return llvm_global; |
| 2726 | try o.builder.llvm_globals.append(o.gpa, llvm_global); |
| 2727 | gop.value_ptr.* = try o.builder.addGlobal(name, global); |
| 2728 | try o.builder.objects.append(o.gpa, object); |
| 2729 | return global.kind.object; |
| 2666 | 2730 | } |
| 2667 | 2731 | |
| 2668 | 2732 | fn isUnnamedType(o: *Object, ty: Type, val: *llvm.Value) bool { |
| 2669 | | // Once `lowerType` succeeds, successive calls to it with the same Zig type |
| 2670 | | // are guaranteed to succeed. So if a call to `lowerType` fails here it means |
| 2733 | // Once `lowerLlvmType` succeeds, successive calls to it with the same Zig type |
| 2734 | // are guaranteed to succeed. So if a call to `lowerLlvmType` fails here it means |
| 2671 | 2735 | // it is the first time lowering the type, which means the value can't possible |
| 2672 | 2736 | // have that type. |
| 2673 | | const llvm_ty = o.lowerType(ty) catch return true; |
| 2737 | const llvm_ty = o.lowerLlvmType(ty) catch return true; |
| 2674 | 2738 | return val.typeOf() != llvm_ty; |
| 2675 | 2739 | } |
| 2676 | 2740 | |
| 2677 | | fn lowerType(o: *Object, t: Type) Allocator.Error!*llvm.Type { |
| 2678 | | const llvm_ty = try lowerTypeInner(o, t); |
| 2741 | fn lowerLlvmType(o: *Object, t: Type) Allocator.Error!*llvm.Type { |
| 2742 | const ty = try o.lowerType(t); |
| 2743 | const llvm_ty = if (ty != .none) |
| 2744 | o.builder.llvm_types.items[@intFromEnum(ty)] |
| 2745 | else |
| 2746 | try o.lowerLlvmTypeInner(t); |
| 2679 | 2747 | const mod = o.module; |
| 2680 | 2748 | if (std.debug.runtime_safety and false) check: { |
| 2681 | 2749 | if (t.zigTypeTag(mod) == .Opaque) break :check; |
| ... | ... | @@ -2693,7 +2761,7 @@ pub const Object = struct { |
| 2693 | 2761 | return llvm_ty; |
| 2694 | 2762 | } |
| 2695 | 2763 | |
| 2696 | | fn lowerTypeInner(o: *Object, t: Type) Allocator.Error!*llvm.Type { |
| 2764 | fn lowerLlvmTypeInner(o: *Object, t: Type) Allocator.Error!*llvm.Type { |
| 2697 | 2765 | const gpa = o.gpa; |
| 2698 | 2766 | const mod = o.module; |
| 2699 | 2767 | const target = mod.getTarget(); |
| ... | ... | @@ -2714,7 +2782,7 @@ pub const Object = struct { |
| 2714 | 2782 | 16 => return if (backendSupportsF16(target)) o.context.halfType() else o.context.intType(16), |
| 2715 | 2783 | 32 => return o.context.floatType(), |
| 2716 | 2784 | 64 => return o.context.doubleType(), |
| 2717 | | 80 => return if (backendSupportsF80(target)) o.context.x86FP80Type() else o.context.intType(80), |
| 2785 | 80 => return if (backendSupportsF80(target)) o.context.x86_fp80Type() else o.context.intType(80), |
| 2718 | 2786 | 128 => return o.context.fp128Type(), |
| 2719 | 2787 | else => unreachable, |
| 2720 | 2788 | }, |
| ... | ... | @@ -2724,8 +2792,8 @@ pub const Object = struct { |
| 2724 | 2792 | const ptr_type = t.slicePtrFieldType(mod); |
| 2725 | 2793 | |
| 2726 | 2794 | const fields: [2]*llvm.Type = .{ |
| 2727 | | try o.lowerType(ptr_type), |
| 2728 | | try o.lowerType(Type.usize), |
| 2795 | try o.lowerLlvmType(ptr_type), |
| 2796 | try o.lowerLlvmType(Type.usize), |
| 2729 | 2797 | }; |
| 2730 | 2798 | return o.context.structType(&fields, fields.len, .False); |
| 2731 | 2799 | } |
| ... | ... | @@ -2749,12 +2817,12 @@ pub const Object = struct { |
| 2749 | 2817 | .Array => { |
| 2750 | 2818 | const elem_ty = t.childType(mod); |
| 2751 | 2819 | if (std.debug.runtime_safety) assert((try elem_ty.onePossibleValue(mod)) == null); |
| 2752 | | const elem_llvm_ty = try o.lowerType(elem_ty); |
| 2820 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); |
| 2753 | 2821 | const total_len = t.arrayLen(mod) + @intFromBool(t.sentinel(mod) != null); |
| 2754 | 2822 | return elem_llvm_ty.arrayType(@as(c_uint, @intCast(total_len))); |
| 2755 | 2823 | }, |
| 2756 | 2824 | .Vector => { |
| 2757 | | const elem_type = try o.lowerType(t.childType(mod)); |
| 2825 | const elem_type = try o.lowerLlvmType(t.childType(mod)); |
| 2758 | 2826 | return elem_type.vectorType(t.vectorLen(mod)); |
| 2759 | 2827 | }, |
| 2760 | 2828 | .Optional => { |
| ... | ... | @@ -2762,7 +2830,7 @@ pub const Object = struct { |
| 2762 | 2830 | if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 2763 | 2831 | return o.context.intType(8); |
| 2764 | 2832 | } |
| 2765 | | const payload_llvm_ty = try o.lowerType(child_ty); |
| 2833 | const payload_llvm_ty = try o.lowerLlvmType(child_ty); |
| 2766 | 2834 | if (t.optionalReprIsPayload(mod)) { |
| 2767 | 2835 | return payload_llvm_ty; |
| 2768 | 2836 | } |
| ... | ... | @@ -2783,10 +2851,10 @@ pub const Object = struct { |
| 2783 | 2851 | .ErrorUnion => { |
| 2784 | 2852 | const payload_ty = t.errorUnionPayload(mod); |
| 2785 | 2853 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 2786 | | return try o.lowerType(Type.anyerror); |
| 2854 | return try o.lowerLlvmType(Type.anyerror); |
| 2787 | 2855 | } |
| 2788 | | const llvm_error_type = try o.lowerType(Type.anyerror); |
| 2789 | | const llvm_payload_type = try o.lowerType(payload_ty); |
| 2856 | const llvm_error_type = try o.lowerLlvmType(Type.anyerror); |
| 2857 | const llvm_payload_type = try o.lowerLlvmType(payload_ty); |
| 2790 | 2858 | |
| 2791 | 2859 | const payload_align = payload_ty.abiAlignment(mod); |
| 2792 | 2860 | const error_align = Type.anyerror.abiAlignment(mod); |
| ... | ... | @@ -2855,7 +2923,7 @@ pub const Object = struct { |
| 2855 | 2923 | const llvm_array_ty = o.context.intType(8).arrayType(@as(c_uint, @intCast(padding_len))); |
| 2856 | 2924 | try llvm_field_types.append(gpa, llvm_array_ty); |
| 2857 | 2925 | } |
| 2858 | | const field_llvm_ty = try o.lowerType(field_ty.toType()); |
| 2926 | const field_llvm_ty = try o.lowerLlvmType(field_ty.toType()); |
| 2859 | 2927 | try llvm_field_types.append(gpa, field_llvm_ty); |
| 2860 | 2928 | |
| 2861 | 2929 | offset += field_ty.toType().abiSize(mod); |
| ... | ... | @@ -2886,14 +2954,17 @@ pub const Object = struct { |
| 2886 | 2954 | |
| 2887 | 2955 | if (struct_obj.layout == .Packed) { |
| 2888 | 2956 | assert(struct_obj.haveLayout()); |
| 2889 | | const int_llvm_ty = try o.lowerType(struct_obj.backing_int_ty); |
| 2957 | const int_llvm_ty = try o.lowerLlvmType(struct_obj.backing_int_ty); |
| 2890 | 2958 | gop.value_ptr.* = int_llvm_ty; |
| 2891 | 2959 | return int_llvm_ty; |
| 2892 | 2960 | } |
| 2893 | 2961 | |
| 2894 | | const name = mod.intern_pool.stringToSlice(try struct_obj.getFullyQualifiedName(mod)); |
| 2962 | const name = try o.builder.string(mod.intern_pool.stringToSlice( |
| 2963 | try struct_obj.getFullyQualifiedName(mod), |
| 2964 | )); |
| 2965 | _ = try o.builder.opaqueType(name); |
| 2895 | 2966 | |
| 2896 | | const llvm_struct_ty = o.context.structCreateNamed(name); |
| 2967 | const llvm_struct_ty = o.context.structCreateNamed(name.toSlice(&o.builder).?); |
| 2897 | 2968 | gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls |
| 2898 | 2969 | |
| 2899 | 2970 | assert(struct_obj.haveFieldTypes()); |
| ... | ... | @@ -2924,7 +2995,7 @@ pub const Object = struct { |
| 2924 | 2995 | const llvm_array_ty = o.context.intType(8).arrayType(@as(c_uint, @intCast(padding_len))); |
| 2925 | 2996 | try llvm_field_types.append(gpa, llvm_array_ty); |
| 2926 | 2997 | } |
| 2927 | | const field_llvm_ty = try o.lowerType(field.ty); |
| 2998 | const field_llvm_ty = try o.lowerLlvmType(field.ty); |
| 2928 | 2999 | try llvm_field_types.append(gpa, field_llvm_ty); |
| 2929 | 3000 | |
| 2930 | 3001 | offset += field.ty.abiSize(mod); |
| ... | ... | @@ -2962,7 +3033,7 @@ pub const Object = struct { |
| 2962 | 3033 | } |
| 2963 | 3034 | |
| 2964 | 3035 | if (layout.payload_size == 0) { |
| 2965 | | const enum_tag_llvm_ty = try o.lowerType(union_obj.tag_ty); |
| 3036 | const enum_tag_llvm_ty = try o.lowerLlvmType(union_obj.tag_ty); |
| 2966 | 3037 | gop.value_ptr.* = enum_tag_llvm_ty; |
| 2967 | 3038 | return enum_tag_llvm_ty; |
| 2968 | 3039 | } |
| ... | ... | @@ -2973,7 +3044,7 @@ pub const Object = struct { |
| 2973 | 3044 | gop.value_ptr.* = llvm_union_ty; // must be done before any recursive calls |
| 2974 | 3045 | |
| 2975 | 3046 | const aligned_field = union_obj.fields.values()[layout.most_aligned_field]; |
| 2976 | | const llvm_aligned_field_ty = try o.lowerType(aligned_field.ty); |
| 3047 | const llvm_aligned_field_ty = try o.lowerLlvmType(aligned_field.ty); |
| 2977 | 3048 | |
| 2978 | 3049 | const llvm_payload_ty = t: { |
| 2979 | 3050 | if (layout.most_aligned_field_size == layout.payload_size) { |
| ... | ... | @@ -2995,7 +3066,7 @@ pub const Object = struct { |
| 2995 | 3066 | llvm_union_ty.structSetBody(&llvm_fields, llvm_fields.len, .False); |
| 2996 | 3067 | return llvm_union_ty; |
| 2997 | 3068 | } |
| 2998 | | const enum_tag_llvm_ty = try o.lowerType(union_obj.tag_ty); |
| 3069 | const enum_tag_llvm_ty = try o.lowerLlvmType(union_obj.tag_ty); |
| 2999 | 3070 | |
| 3000 | 3071 | // Put the tag before or after the payload depending on which one's |
| 3001 | 3072 | // alignment is greater. |
| ... | ... | @@ -3017,7 +3088,7 @@ pub const Object = struct { |
| 3017 | 3088 | llvm_union_ty.structSetBody(&llvm_fields, llvm_fields_len, .False); |
| 3018 | 3089 | return llvm_union_ty; |
| 3019 | 3090 | }, |
| 3020 | | .Fn => return lowerTypeFn(o, t), |
| 3091 | .Fn => return lowerLlvmTypeFn(o, t), |
| 3021 | 3092 | .ComptimeInt => unreachable, |
| 3022 | 3093 | .ComptimeFloat => unreachable, |
| 3023 | 3094 | .Type => unreachable, |
| ... | ... | @@ -3030,7 +3101,17 @@ pub const Object = struct { |
| 3030 | 3101 | } |
| 3031 | 3102 | } |
| 3032 | 3103 | |
| 3033 | | fn lowerTypeFn(o: *Object, fn_ty: Type) Allocator.Error!*llvm.Type { |
| 3104 | fn lowerType(o: *Object, t: Type) Allocator.Error!Builder.Type { |
| 3105 | const mod = o.module; |
| 3106 | switch (t.toIntern()) { |
| 3107 | .void_type, .noreturn_type => return .void, |
| 3108 | else => switch (mod.intern_pool.indexToKey(t.toIntern())) { |
| 3109 | else => return .none, |
| 3110 | }, |
| 3111 | } |
| 3112 | } |
| 3113 | |
| 3114 | fn lowerLlvmTypeFn(o: *Object, fn_ty: Type) Allocator.Error!*llvm.Type { |
| 3034 | 3115 | const mod = o.module; |
| 3035 | 3116 | const ip = &mod.intern_pool; |
| 3036 | 3117 | const fn_info = mod.typeToFunc(fn_ty).?; |
| ... | ... | @@ -3047,7 +3128,7 @@ pub const Object = struct { |
| 3047 | 3128 | mod.comp.bin_file.options.error_return_tracing) |
| 3048 | 3129 | { |
| 3049 | 3130 | const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType()); |
| 3050 | | try llvm_params.append(try o.lowerType(ptr_ty)); |
| 3131 | try llvm_params.append(try o.lowerLlvmType(ptr_ty)); |
| 3051 | 3132 | } |
| 3052 | 3133 | |
| 3053 | 3134 | var it = iterateParamTypes(o, fn_info); |
| ... | ... | @@ -3055,7 +3136,7 @@ pub const Object = struct { |
| 3055 | 3136 | .no_bits => continue, |
| 3056 | 3137 | .byval => { |
| 3057 | 3138 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); |
| 3058 | | try llvm_params.append(try o.lowerType(param_ty)); |
| 3139 | try llvm_params.append(try o.lowerLlvmType(param_ty)); |
| 3059 | 3140 | }, |
| 3060 | 3141 | .byref, .byref_mut => { |
| 3061 | 3142 | try llvm_params.append(o.context.pointerType(0)); |
| ... | ... | @@ -3071,8 +3152,8 @@ pub const Object = struct { |
| 3071 | 3152 | param_ty.optionalChild(mod).slicePtrFieldType(mod) |
| 3072 | 3153 | else |
| 3073 | 3154 | param_ty.slicePtrFieldType(mod); |
| 3074 | | const ptr_llvm_ty = try o.lowerType(ptr_ty); |
| 3075 | | const len_llvm_ty = try o.lowerType(Type.usize); |
| 3155 | const ptr_llvm_ty = try o.lowerLlvmType(ptr_ty); |
| 3156 | const len_llvm_ty = try o.lowerLlvmType(Type.usize); |
| 3076 | 3157 | |
| 3077 | 3158 | try llvm_params.ensureUnusedCapacity(2); |
| 3078 | 3159 | llvm_params.appendAssumeCapacity(ptr_llvm_ty); |
| ... | ... | @@ -3086,7 +3167,7 @@ pub const Object = struct { |
| 3086 | 3167 | }, |
| 3087 | 3168 | .float_array => |count| { |
| 3088 | 3169 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); |
| 3089 | | const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(param_ty, mod).?); |
| 3170 | const float_ty = try o.lowerLlvmType(aarch64_c_abi.getFloatArrayType(param_ty, mod).?); |
| 3090 | 3171 | const field_count = @as(c_uint, @intCast(count)); |
| 3091 | 3172 | const arr_ty = float_ty.arrayType(field_count); |
| 3092 | 3173 | try llvm_params.append(arr_ty); |
| ... | ... | @@ -3106,7 +3187,7 @@ pub const Object = struct { |
| 3106 | 3187 | ); |
| 3107 | 3188 | } |
| 3108 | 3189 | |
| 3109 | | /// Use this instead of lowerType when you want to handle correctly the case of elem_ty |
| 3190 | /// Use this instead of lowerLlvmType when you want to handle correctly the case of elem_ty |
| 3110 | 3191 | /// being a zero bit type, but it should still be lowered as an i8 in such case. |
| 3111 | 3192 | /// There are other similar cases handled here as well. |
| 3112 | 3193 | fn lowerPtrElemTy(o: *Object, elem_ty: Type) Allocator.Error!*llvm.Type { |
| ... | ... | @@ -3118,7 +3199,7 @@ pub const Object = struct { |
| 3118 | 3199 | else => elem_ty.hasRuntimeBitsIgnoreComptime(mod), |
| 3119 | 3200 | }; |
| 3120 | 3201 | const llvm_elem_ty = if (lower_elem_ty) |
| 3121 | | try o.lowerType(elem_ty) |
| 3202 | try o.lowerLlvmType(elem_ty) |
| 3122 | 3203 | else |
| 3123 | 3204 | o.context.intType(8); |
| 3124 | 3205 | |
| ... | ... | @@ -3135,7 +3216,7 @@ pub const Object = struct { |
| 3135 | 3216 | else => {}, |
| 3136 | 3217 | } |
| 3137 | 3218 | if (tv.val.isUndefDeep(mod)) { |
| 3138 | | const llvm_type = try o.lowerType(tv.ty); |
| 3219 | const llvm_type = try o.lowerLlvmType(tv.ty); |
| 3139 | 3220 | return llvm_type.getUndef(); |
| 3140 | 3221 | } |
| 3141 | 3222 | |
| ... | ... | @@ -3168,7 +3249,7 @@ pub const Object = struct { |
| 3168 | 3249 | .generic_poison, |
| 3169 | 3250 | => unreachable, // non-runtime values |
| 3170 | 3251 | .false, .true => { |
| 3171 | | const llvm_type = try o.lowerType(tv.ty); |
| 3252 | const llvm_type = try o.lowerLlvmType(tv.ty); |
| 3172 | 3253 | return if (tv.val.toBool()) llvm_type.constAllOnes() else llvm_type.constNull(); |
| 3173 | 3254 | }, |
| 3174 | 3255 | }, |
| ... | ... | @@ -3180,13 +3261,15 @@ pub const Object = struct { |
| 3180 | 3261 | const fn_decl_index = extern_func.decl; |
| 3181 | 3262 | const fn_decl = mod.declPtr(fn_decl_index); |
| 3182 | 3263 | try mod.markDeclAlive(fn_decl); |
| 3183 | | return o.resolveLlvmFunction(fn_decl_index); |
| 3264 | const function_index = try o.resolveLlvmFunction(fn_decl_index); |
| 3265 | return function_index.toLlvm(&o.builder); |
| 3184 | 3266 | }, |
| 3185 | 3267 | .func => |func| { |
| 3186 | 3268 | const fn_decl_index = func.owner_decl; |
| 3187 | 3269 | const fn_decl = mod.declPtr(fn_decl_index); |
| 3188 | 3270 | try mod.markDeclAlive(fn_decl); |
| 3189 | | return o.resolveLlvmFunction(fn_decl_index); |
| 3271 | const function_index = try o.resolveLlvmFunction(fn_decl_index); |
| 3272 | return function_index.toLlvm(&o.builder); |
| 3190 | 3273 | }, |
| 3191 | 3274 | .int => { |
| 3192 | 3275 | var bigint_space: Value.BigIntSpace = undefined; |
| ... | ... | @@ -3194,7 +3277,7 @@ pub const Object = struct { |
| 3194 | 3277 | return lowerBigInt(o, tv.ty, bigint); |
| 3195 | 3278 | }, |
| 3196 | 3279 | .err => |err| { |
| 3197 | | const llvm_ty = try o.lowerType(Type.anyerror); |
| 3280 | const llvm_ty = try o.lowerLlvmType(Type.anyerror); |
| 3198 | 3281 | const int = try mod.getErrorValue(err.name); |
| 3199 | 3282 | return llvm_ty.constInt(int, .False); |
| 3200 | 3283 | }, |
| ... | ... | @@ -3230,7 +3313,7 @@ pub const Object = struct { |
| 3230 | 3313 | }); |
| 3231 | 3314 | var fields_buf: [3]*llvm.Value = undefined; |
| 3232 | 3315 | |
| 3233 | | const llvm_ty = try o.lowerType(tv.ty); |
| 3316 | const llvm_ty = try o.lowerLlvmType(tv.ty); |
| 3234 | 3317 | const llvm_field_count = llvm_ty.countStructElementTypes(); |
| 3235 | 3318 | if (llvm_field_count > 2) { |
| 3236 | 3319 | assert(llvm_field_count == 3); |
| ... | ... | @@ -3274,7 +3357,7 @@ pub const Object = struct { |
| 3274 | 3357 | return unsigned_val; |
| 3275 | 3358 | }, |
| 3276 | 3359 | .float => { |
| 3277 | | const llvm_ty = try o.lowerType(tv.ty); |
| 3360 | const llvm_ty = try o.lowerLlvmType(tv.ty); |
| 3278 | 3361 | switch (tv.ty.floatBits(target)) { |
| 3279 | 3362 | 16 => { |
| 3280 | 3363 | const repr = @as(u16, @bitCast(tv.val.toFloat(f16, mod))); |
| ... | ... | @@ -3359,7 +3442,7 @@ pub const Object = struct { |
| 3359 | 3442 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 3360 | 3443 | return non_null_bit; |
| 3361 | 3444 | } |
| 3362 | | const llvm_ty = try o.lowerType(tv.ty); |
| 3445 | const llvm_ty = try o.lowerLlvmType(tv.ty); |
| 3363 | 3446 | if (tv.ty.optionalReprIsPayload(mod)) return switch (opt.val) { |
| 3364 | 3447 | .none => llvm_ty.constNull(), |
| 3365 | 3448 | else => |payload| o.lowerValue(.{ .ty = payload_ty, .val = payload.toValue() }), |
| ... | ... | @@ -3405,7 +3488,7 @@ pub const Object = struct { |
| 3405 | 3488 | .True, |
| 3406 | 3489 | ); |
| 3407 | 3490 | } else { |
| 3408 | | const llvm_elem_ty = try o.lowerType(elem_ty); |
| 3491 | const llvm_elem_ty = try o.lowerLlvmType(elem_ty); |
| 3409 | 3492 | return llvm_elem_ty.constArray( |
| 3410 | 3493 | llvm_elems.ptr, |
| 3411 | 3494 | @as(c_uint, @intCast(llvm_elems.len)), |
| ... | ... | @@ -3440,7 +3523,7 @@ pub const Object = struct { |
| 3440 | 3523 | .True, |
| 3441 | 3524 | ); |
| 3442 | 3525 | } else { |
| 3443 | | const llvm_elem_ty = try o.lowerType(elem_ty); |
| 3526 | const llvm_elem_ty = try o.lowerLlvmType(elem_ty); |
| 3444 | 3527 | return llvm_elem_ty.constArray( |
| 3445 | 3528 | llvm_elems.ptr, |
| 3446 | 3529 | @as(c_uint, @intCast(llvm_elems.len)), |
| ... | ... | @@ -3527,7 +3610,7 @@ pub const Object = struct { |
| 3527 | 3610 | .False, |
| 3528 | 3611 | ); |
| 3529 | 3612 | } else { |
| 3530 | | const llvm_struct_ty = try o.lowerType(tv.ty); |
| 3613 | const llvm_struct_ty = try o.lowerLlvmType(tv.ty); |
| 3531 | 3614 | return llvm_struct_ty.constNamedStruct( |
| 3532 | 3615 | llvm_fields.items.ptr, |
| 3533 | 3616 | @as(c_uint, @intCast(llvm_fields.items.len)), |
| ... | ... | @@ -3536,7 +3619,7 @@ pub const Object = struct { |
| 3536 | 3619 | }, |
| 3537 | 3620 | .struct_type => |struct_type| { |
| 3538 | 3621 | const struct_obj = mod.structPtrUnwrap(struct_type.index).?; |
| 3539 | | const llvm_struct_ty = try o.lowerType(tv.ty); |
| 3622 | const llvm_struct_ty = try o.lowerLlvmType(tv.ty); |
| 3540 | 3623 | |
| 3541 | 3624 | if (struct_obj.layout == .Packed) { |
| 3542 | 3625 | assert(struct_obj.haveLayout()); |
| ... | ... | @@ -3633,7 +3716,7 @@ pub const Object = struct { |
| 3633 | 3716 | else => unreachable, |
| 3634 | 3717 | }, |
| 3635 | 3718 | .un => { |
| 3636 | | const llvm_union_ty = try o.lowerType(tv.ty); |
| 3719 | const llvm_union_ty = try o.lowerLlvmType(tv.ty); |
| 3637 | 3720 | const tag_and_val: Value.Payload.Union.Data = switch (tv.val.toIntern()) { |
| 3638 | 3721 | .none => tv.val.castTag(.@"union").?.data, |
| 3639 | 3722 | else => switch (mod.intern_pool.indexToKey(tv.val.toIntern())) { |
| ... | ... | @@ -3803,7 +3886,7 @@ pub const Object = struct { |
| 3803 | 3886 | llvm_u32.constInt(0, .False), |
| 3804 | 3887 | llvm_u32.constInt(payload_offset, .False), |
| 3805 | 3888 | }; |
| 3806 | | const eu_llvm_ty = try o.lowerType(eu_ty); |
| 3889 | const eu_llvm_ty = try o.lowerLlvmType(eu_ty); |
| 3807 | 3890 | return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 3808 | 3891 | }, |
| 3809 | 3892 | .opt_payload => |opt_ptr| { |
| ... | ... | @@ -3824,19 +3907,19 @@ pub const Object = struct { |
| 3824 | 3907 | llvm_u32.constInt(0, .False), |
| 3825 | 3908 | llvm_u32.constInt(0, .False), |
| 3826 | 3909 | }; |
| 3827 | | const opt_llvm_ty = try o.lowerType(opt_ty); |
| 3910 | const opt_llvm_ty = try o.lowerLlvmType(opt_ty); |
| 3828 | 3911 | return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 3829 | 3912 | }, |
| 3830 | 3913 | .comptime_field => unreachable, |
| 3831 | 3914 | .elem => |elem_ptr| { |
| 3832 | 3915 | const parent_llvm_ptr = try o.lowerParentPtr(elem_ptr.base.toValue(), true); |
| 3833 | 3916 | |
| 3834 | | const llvm_usize = try o.lowerType(Type.usize); |
| 3917 | const llvm_usize = try o.lowerLlvmType(Type.usize); |
| 3835 | 3918 | const indices: [1]*llvm.Value = .{ |
| 3836 | 3919 | llvm_usize.constInt(elem_ptr.index, .False), |
| 3837 | 3920 | }; |
| 3838 | 3921 | const elem_ty = mod.intern_pool.typeOf(elem_ptr.base).toType().elemType2(mod); |
| 3839 | | const elem_llvm_ty = try o.lowerType(elem_ty); |
| 3922 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); |
| 3840 | 3923 | return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 3841 | 3924 | }, |
| 3842 | 3925 | .field => |field_ptr| { |
| ... | ... | @@ -3865,7 +3948,7 @@ pub const Object = struct { |
| 3865 | 3948 | llvm_u32.constInt(0, .False), |
| 3866 | 3949 | llvm_u32.constInt(llvm_pl_index, .False), |
| 3867 | 3950 | }; |
| 3868 | | const parent_llvm_ty = try o.lowerType(parent_ty); |
| 3951 | const parent_llvm_ty = try o.lowerLlvmType(parent_ty); |
| 3869 | 3952 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 3870 | 3953 | }, |
| 3871 | 3954 | .Struct => { |
| ... | ... | @@ -3888,7 +3971,7 @@ pub const Object = struct { |
| 3888 | 3971 | return field_addr.constIntToPtr(final_llvm_ty); |
| 3889 | 3972 | } |
| 3890 | 3973 | |
| 3891 | | const parent_llvm_ty = try o.lowerType(parent_ty); |
| 3974 | const parent_llvm_ty = try o.lowerLlvmType(parent_ty); |
| 3892 | 3975 | if (llvmField(parent_ty, field_index, mod)) |llvm_field| { |
| 3893 | 3976 | const indices: [2]*llvm.Value = .{ |
| 3894 | 3977 | llvm_u32.constInt(0, .False), |
| ... | ... | @@ -3907,7 +3990,7 @@ pub const Object = struct { |
| 3907 | 3990 | llvm_u32.constInt(0, .False), |
| 3908 | 3991 | llvm_u32.constInt(field_index, .False), |
| 3909 | 3992 | }; |
| 3910 | | const parent_llvm_ty = try o.lowerType(parent_ty); |
| 3993 | const parent_llvm_ty = try o.lowerLlvmType(parent_ty); |
| 3911 | 3994 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 3912 | 3995 | }, |
| 3913 | 3996 | else => unreachable, |
| ... | ... | @@ -3949,9 +4032,9 @@ pub const Object = struct { |
| 3949 | 4032 | try mod.markDeclAlive(decl); |
| 3950 | 4033 | |
| 3951 | 4034 | const llvm_decl_val = if (is_fn_body) |
| 3952 | | try o.resolveLlvmFunction(decl_index) |
| 4035 | (try o.resolveLlvmFunction(decl_index)).toLlvm(&o.builder) |
| 3953 | 4036 | else |
| 3954 | | try o.resolveGlobalDecl(decl_index); |
| 4037 | (try o.resolveGlobalDecl(decl_index)).toLlvm(&o.builder); |
| 3955 | 4038 | |
| 3956 | 4039 | const target = mod.getTarget(); |
| 3957 | 4040 | const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); |
| ... | ... | @@ -3961,7 +4044,7 @@ pub const Object = struct { |
| 3961 | 4044 | break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty); |
| 3962 | 4045 | } else llvm_decl_val; |
| 3963 | 4046 | |
| 3964 | | const llvm_type = try o.lowerType(tv.ty); |
| 4047 | const llvm_type = try o.lowerLlvmType(tv.ty); |
| 3965 | 4048 | if (tv.ty.zigTypeTag(mod) == .Int) { |
| 3966 | 4049 | return llvm_val.constPtrToInt(llvm_type); |
| 3967 | 4050 | } else { |
| ... | ... | @@ -3976,8 +4059,8 @@ pub const Object = struct { |
| 3976 | 4059 | // The value cannot be undefined, because we use the `nonnull` annotation |
| 3977 | 4060 | // for non-optional pointers. We also need to respect the alignment, even though |
| 3978 | 4061 | // the address will never be dereferenced. |
| 3979 | | const llvm_usize = try o.lowerType(Type.usize); |
| 3980 | | const llvm_ptr_ty = try o.lowerType(ptr_ty); |
| 4062 | const llvm_usize = try o.lowerLlvmType(Type.usize); |
| 4063 | const llvm_ptr_ty = try o.lowerLlvmType(ptr_ty); |
| 3981 | 4064 | if (ptr_ty.ptrInfo(mod).flags.alignment.toByteUnitsOptional()) |alignment| { |
| 3982 | 4065 | return llvm_usize.constInt(alignment, .False).constIntToPtr(llvm_ptr_ty); |
| 3983 | 4066 | } |
| ... | ... | @@ -4159,20 +4242,26 @@ pub const DeclGen = struct { |
| 4159 | 4242 | _ = try o.resolveLlvmFunction(extern_func.decl); |
| 4160 | 4243 | } else { |
| 4161 | 4244 | const target = mod.getTarget(); |
| 4162 | | var global = try o.resolveGlobalDecl(decl_index); |
| 4163 | | global.setAlignment(decl.getAlignment(mod)); |
| 4164 | | if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| global.setSection(s); |
| 4245 | const object_index = try o.resolveGlobalDecl(decl_index); |
| 4246 | const object = object_index.ptr(&o.builder); |
| 4247 | const global = object.global.ptr(&o.builder); |
| 4248 | var llvm_global = object.global.toLlvm(&o.builder); |
| 4249 | global.alignment = Builder.Alignment.fromByteUnits(decl.getAlignment(mod)); |
| 4250 | llvm_global.setAlignment(decl.getAlignment(mod)); |
| 4251 | if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| llvm_global.setSection(s); |
| 4165 | 4252 | assert(decl.has_tv); |
| 4166 | 4253 | const init_val = if (decl.val.getVariable(mod)) |variable| init_val: { |
| 4254 | object.mutability = .global; |
| 4167 | 4255 | break :init_val variable.init; |
| 4168 | 4256 | } else init_val: { |
| 4169 | | global.setGlobalConstant(.True); |
| 4257 | object.mutability = .constant; |
| 4258 | llvm_global.setGlobalConstant(.True); |
| 4170 | 4259 | break :init_val decl.val.toIntern(); |
| 4171 | 4260 | }; |
| 4172 | 4261 | if (init_val != .none) { |
| 4173 | 4262 | const llvm_init = try o.lowerValue(.{ .ty = decl.ty, .val = init_val.toValue() }); |
| 4174 | | if (global.globalGetValueType() == llvm_init.typeOf()) { |
| 4175 | | global.setInitializer(llvm_init); |
| 4263 | if (llvm_global.globalGetValueType() == llvm_init.typeOf()) { |
| 4264 | llvm_global.setInitializer(llvm_init); |
| 4176 | 4265 | } else { |
| 4177 | 4266 | // LLVM does not allow us to change the type of globals. So we must |
| 4178 | 4267 | // create a new global with the correct type, copy all its attributes, |
| ... | ... | @@ -4193,18 +4282,18 @@ pub const DeclGen = struct { |
| 4193 | 4282 | "", |
| 4194 | 4283 | llvm_global_addrspace, |
| 4195 | 4284 | ); |
| 4196 | | new_global.setLinkage(global.getLinkage()); |
| 4197 | | new_global.setUnnamedAddr(global.getUnnamedAddress()); |
| 4198 | | new_global.setAlignment(global.getAlignment()); |
| 4285 | new_global.setLinkage(llvm_global.getLinkage()); |
| 4286 | new_global.setUnnamedAddr(llvm_global.getUnnamedAddress()); |
| 4287 | new_global.setAlignment(llvm_global.getAlignment()); |
| 4199 | 4288 | if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| |
| 4200 | 4289 | new_global.setSection(s); |
| 4201 | 4290 | new_global.setInitializer(llvm_init); |
| 4202 | 4291 | // TODO: How should this work then the address space of a global changed? |
| 4203 | | global.replaceAllUsesWith(new_global); |
| 4204 | | o.decl_map.putAssumeCapacity(decl_index, new_global); |
| 4205 | | new_global.takeName(global); |
| 4206 | | global.deleteGlobal(); |
| 4207 | | global = new_global; |
| 4292 | llvm_global.replaceAllUsesWith(new_global); |
| 4293 | new_global.takeName(llvm_global); |
| 4294 | o.builder.llvm_globals.items[@intFromEnum(object.global)] = new_global; |
| 4295 | llvm_global.deleteGlobal(); |
| 4296 | llvm_global = new_global; |
| 4208 | 4297 | } |
| 4209 | 4298 | } |
| 4210 | 4299 | |
| ... | ... | @@ -4216,7 +4305,7 @@ pub const DeclGen = struct { |
| 4216 | 4305 | const di_global = dib.createGlobalVariableExpression( |
| 4217 | 4306 | di_file.toScope(), |
| 4218 | 4307 | mod.intern_pool.stringToSlice(decl.name), |
| 4219 | | global.getValueName(), |
| 4308 | llvm_global.getValueName(), |
| 4220 | 4309 | di_file, |
| 4221 | 4310 | line_number, |
| 4222 | 4311 | try o.lowerDebugType(decl.ty, .full), |
| ... | ... | @@ -4224,7 +4313,7 @@ pub const DeclGen = struct { |
| 4224 | 4313 | ); |
| 4225 | 4314 | |
| 4226 | 4315 | try o.di_map.put(o.gpa, dg.decl, di_global.getVariable().toNode()); |
| 4227 | | if (!is_internal_linkage or decl.isExtern(mod)) global.attachMetaData(di_global); |
| 4316 | if (!is_internal_linkage or decl.isExtern(mod)) llvm_global.attachMetaData(di_global); |
| 4228 | 4317 | } |
| 4229 | 4318 | } |
| 4230 | 4319 | } |
| ... | ... | @@ -4618,7 +4707,7 @@ pub const FuncGen = struct { |
| 4618 | 4707 | defer llvm_args.deinit(); |
| 4619 | 4708 | |
| 4620 | 4709 | const ret_ptr = if (!sret) null else blk: { |
| 4621 | | const llvm_ret_ty = try o.lowerType(return_type); |
| 4710 | const llvm_ret_ty = try o.lowerLlvmType(return_type); |
| 4622 | 4711 | const ret_ptr = self.buildAlloca(llvm_ret_ty, return_type.abiAlignment(mod)); |
| 4623 | 4712 | try llvm_args.append(ret_ptr); |
| 4624 | 4713 | break :blk ret_ptr; |
| ... | ... | @@ -4637,7 +4726,7 @@ pub const FuncGen = struct { |
| 4637 | 4726 | const arg = args[it.zig_index - 1]; |
| 4638 | 4727 | const param_ty = self.typeOf(arg); |
| 4639 | 4728 | const llvm_arg = try self.resolveInst(arg); |
| 4640 | | const llvm_param_ty = try o.lowerType(param_ty); |
| 4729 | const llvm_param_ty = try o.lowerLlvmType(param_ty); |
| 4641 | 4730 | if (isByRef(param_ty, mod)) { |
| 4642 | 4731 | const alignment = param_ty.abiAlignment(mod); |
| 4643 | 4732 | const load_inst = self.builder.buildLoad(llvm_param_ty, llvm_arg, ""); |
| ... | ... | @@ -4668,7 +4757,7 @@ pub const FuncGen = struct { |
| 4668 | 4757 | const llvm_arg = try self.resolveInst(arg); |
| 4669 | 4758 | |
| 4670 | 4759 | const alignment = param_ty.abiAlignment(mod); |
| 4671 | | const param_llvm_ty = try o.lowerType(param_ty); |
| 4760 | const param_llvm_ty = try o.lowerLlvmType(param_ty); |
| 4672 | 4761 | const arg_ptr = self.buildAlloca(param_llvm_ty, alignment); |
| 4673 | 4762 | if (isByRef(param_ty, mod)) { |
| 4674 | 4763 | const load_inst = self.builder.buildLoad(param_llvm_ty, llvm_arg, ""); |
| ... | ... | @@ -4759,7 +4848,7 @@ pub const FuncGen = struct { |
| 4759 | 4848 | llvm_arg = store_inst; |
| 4760 | 4849 | } |
| 4761 | 4850 | |
| 4762 | | const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty, mod).?); |
| 4851 | const float_ty = try o.lowerLlvmType(aarch64_c_abi.getFloatArrayType(arg_ty, mod).?); |
| 4763 | 4852 | const array_llvm_ty = float_ty.arrayType(count); |
| 4764 | 4853 | |
| 4765 | 4854 | const alignment = arg_ty.abiAlignment(mod); |
| ... | ... | @@ -4788,7 +4877,7 @@ pub const FuncGen = struct { |
| 4788 | 4877 | }; |
| 4789 | 4878 | |
| 4790 | 4879 | const call = self.builder.buildCall( |
| 4791 | | try o.lowerType(zig_fn_ty), |
| 4880 | try o.lowerLlvmType(zig_fn_ty), |
| 4792 | 4881 | llvm_fn, |
| 4793 | 4882 | llvm_args.items.ptr, |
| 4794 | 4883 | @as(c_uint, @intCast(llvm_args.items.len)), |
| ... | ... | @@ -4813,7 +4902,7 @@ pub const FuncGen = struct { |
| 4813 | 4902 | .byref => { |
| 4814 | 4903 | const param_index = it.zig_index - 1; |
| 4815 | 4904 | const param_ty = fn_info.param_types.get(ip)[param_index].toType(); |
| 4816 | | const param_llvm_ty = try o.lowerType(param_ty); |
| 4905 | const param_llvm_ty = try o.lowerLlvmType(param_ty); |
| 4817 | 4906 | const alignment = param_ty.abiAlignment(mod); |
| 4818 | 4907 | o.addByRefParamAttrs(call, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty); |
| 4819 | 4908 | }, |
| ... | ... | @@ -4862,7 +4951,7 @@ pub const FuncGen = struct { |
| 4862 | 4951 | return null; |
| 4863 | 4952 | } |
| 4864 | 4953 | |
| 4865 | | const llvm_ret_ty = try o.lowerType(return_type); |
| 4954 | const llvm_ret_ty = try o.lowerLlvmType(return_type); |
| 4866 | 4955 | |
| 4867 | 4956 | if (ret_ptr) |rp| { |
| 4868 | 4957 | call.setCallSret(llvm_ret_ty); |
| ... | ... | @@ -4939,8 +5028,8 @@ pub const FuncGen = struct { |
| 4939 | 5028 | const fn_info = mod.typeToFunc(panic_decl.ty).?; |
| 4940 | 5029 | const panic_global = try o.resolveLlvmFunction(panic_func.owner_decl); |
| 4941 | 5030 | _ = fg.builder.buildCall( |
| 4942 | | try o.lowerType(panic_decl.ty), |
| 4943 | | panic_global, |
| 5031 | try o.lowerLlvmType(panic_decl.ty), |
| 5032 | panic_global.toLlvm(&o.builder), |
| 4944 | 5033 | &args, |
| 4945 | 5034 | args.len, |
| 4946 | 5035 | toLlvmCallConv(fn_info.cc, target), |
| ... | ... | @@ -4968,7 +5057,7 @@ pub const FuncGen = struct { |
| 4968 | 5057 | // Functions with an empty error set are emitted with an error code |
| 4969 | 5058 | // return type and return zero so they can be function pointers coerced |
| 4970 | 5059 | // to functions that return anyerror. |
| 4971 | | const err_int = try o.lowerType(Type.anyerror); |
| 5060 | const err_int = try o.lowerLlvmType(Type.anyerror); |
| 4972 | 5061 | _ = self.builder.buildRet(err_int.constInt(0, .False)); |
| 4973 | 5062 | } else { |
| 4974 | 5063 | _ = self.builder.buildRetVoid(); |
| ... | ... | @@ -5016,7 +5105,7 @@ pub const FuncGen = struct { |
| 5016 | 5105 | // Functions with an empty error set are emitted with an error code |
| 5017 | 5106 | // return type and return zero so they can be function pointers coerced |
| 5018 | 5107 | // to functions that return anyerror. |
| 5019 | | const err_int = try o.lowerType(Type.anyerror); |
| 5108 | const err_int = try o.lowerLlvmType(Type.anyerror); |
| 5020 | 5109 | _ = self.builder.buildRet(err_int.constInt(0, .False)); |
| 5021 | 5110 | } else { |
| 5022 | 5111 | _ = self.builder.buildRetVoid(); |
| ... | ... | @@ -5040,7 +5129,7 @@ pub const FuncGen = struct { |
| 5040 | 5129 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 5041 | 5130 | const list = try self.resolveInst(ty_op.operand); |
| 5042 | 5131 | const arg_ty = self.air.getRefType(ty_op.ty); |
| 5043 | | const llvm_arg_ty = try o.lowerType(arg_ty); |
| 5132 | const llvm_arg_ty = try o.lowerLlvmType(arg_ty); |
| 5044 | 5133 | |
| 5045 | 5134 | return self.builder.buildVAArg(list, llvm_arg_ty, ""); |
| 5046 | 5135 | } |
| ... | ... | @@ -5050,7 +5139,7 @@ pub const FuncGen = struct { |
| 5050 | 5139 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 5051 | 5140 | const src_list = try self.resolveInst(ty_op.operand); |
| 5052 | 5141 | const va_list_ty = self.air.getRefType(ty_op.ty); |
| 5053 | | const llvm_va_list_ty = try o.lowerType(va_list_ty); |
| 5142 | const llvm_va_list_ty = try o.lowerLlvmType(va_list_ty); |
| 5054 | 5143 | const mod = o.module; |
| 5055 | 5144 | |
| 5056 | 5145 | const result_alignment = va_list_ty.abiAlignment(mod); |
| ... | ... | @@ -5098,7 +5187,7 @@ pub const FuncGen = struct { |
| 5098 | 5187 | const o = self.dg.object; |
| 5099 | 5188 | const mod = o.module; |
| 5100 | 5189 | const va_list_ty = self.typeOfIndex(inst); |
| 5101 | | const llvm_va_list_ty = try o.lowerType(va_list_ty); |
| 5190 | const llvm_va_list_ty = try o.lowerLlvmType(va_list_ty); |
| 5102 | 5191 | |
| 5103 | 5192 | const result_alignment = va_list_ty.abiAlignment(mod); |
| 5104 | 5193 | const list = self.buildAlloca(llvm_va_list_ty, result_alignment); |
| ... | ... | @@ -5177,7 +5266,7 @@ pub const FuncGen = struct { |
| 5177 | 5266 | // We need to emit instructions to check for equality/inequality |
| 5178 | 5267 | // of optionals that are not pointers. |
| 5179 | 5268 | const is_by_ref = isByRef(scalar_ty, mod); |
| 5180 | | const opt_llvm_ty = try o.lowerType(scalar_ty); |
| 5269 | const opt_llvm_ty = try o.lowerLlvmType(scalar_ty); |
| 5181 | 5270 | const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref); |
| 5182 | 5271 | const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref); |
| 5183 | 5272 | const llvm_i2 = self.context.intType(2); |
| ... | ... | @@ -5287,7 +5376,7 @@ pub const FuncGen = struct { |
| 5287 | 5376 | const is_body = inst_ty.zigTypeTag(mod) == .Fn; |
| 5288 | 5377 | if (!is_body and !inst_ty.hasRuntimeBitsIgnoreComptime(mod)) return null; |
| 5289 | 5378 | |
| 5290 | | const raw_llvm_ty = try o.lowerType(inst_ty); |
| 5379 | const raw_llvm_ty = try o.lowerLlvmType(inst_ty); |
| 5291 | 5380 | |
| 5292 | 5381 | const llvm_ty = ty: { |
| 5293 | 5382 | // If the zig tag type is a function, this represents an actual function body; not |
| ... | ... | @@ -5392,11 +5481,11 @@ pub const FuncGen = struct { |
| 5392 | 5481 | const mod = o.module; |
| 5393 | 5482 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| 5394 | 5483 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod); |
| 5395 | | const err_union_llvm_ty = try o.lowerType(err_union_ty); |
| 5484 | const err_union_llvm_ty = try o.lowerLlvmType(err_union_ty); |
| 5396 | 5485 | |
| 5397 | 5486 | if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { |
| 5398 | 5487 | const is_err = err: { |
| 5399 | | const err_set_ty = try o.lowerType(Type.anyerror); |
| 5488 | const err_set_ty = try o.lowerLlvmType(Type.anyerror); |
| 5400 | 5489 | const zero = err_set_ty.constNull(); |
| 5401 | 5490 | if (!payload_has_bits) { |
| 5402 | 5491 | // TODO add alignment to this load |
| ... | ... | @@ -5531,9 +5620,9 @@ pub const FuncGen = struct { |
| 5531 | 5620 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 5532 | 5621 | const operand_ty = self.typeOf(ty_op.operand); |
| 5533 | 5622 | const array_ty = operand_ty.childType(mod); |
| 5534 | | const llvm_usize = try o.lowerType(Type.usize); |
| 5623 | const llvm_usize = try o.lowerLlvmType(Type.usize); |
| 5535 | 5624 | const len = llvm_usize.constInt(array_ty.arrayLen(mod), .False); |
| 5536 | | const slice_llvm_ty = try o.lowerType(self.typeOfIndex(inst)); |
| 5625 | const slice_llvm_ty = try o.lowerLlvmType(self.typeOfIndex(inst)); |
| 5537 | 5626 | const operand = try self.resolveInst(ty_op.operand); |
| 5538 | 5627 | if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 5539 | 5628 | const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), operand, 0, ""); |
| ... | ... | @@ -5542,7 +5631,7 @@ pub const FuncGen = struct { |
| 5542 | 5631 | const indices: [2]*llvm.Value = .{ |
| 5543 | 5632 | llvm_usize.constNull(), llvm_usize.constNull(), |
| 5544 | 5633 | }; |
| 5545 | | const array_llvm_ty = try o.lowerType(array_ty); |
| 5634 | const array_llvm_ty = try o.lowerLlvmType(array_ty); |
| 5546 | 5635 | const ptr = self.builder.buildInBoundsGEP(array_llvm_ty, operand, &indices, indices.len, ""); |
| 5547 | 5636 | const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, ""); |
| 5548 | 5637 | return self.builder.buildInsertValue(partial, len, 1, ""); |
| ... | ... | @@ -5559,7 +5648,7 @@ pub const FuncGen = struct { |
| 5559 | 5648 | |
| 5560 | 5649 | const dest_ty = self.typeOfIndex(inst); |
| 5561 | 5650 | const dest_scalar_ty = dest_ty.scalarType(mod); |
| 5562 | | const dest_llvm_ty = try o.lowerType(dest_ty); |
| 5651 | const dest_llvm_ty = try o.lowerLlvmType(dest_ty); |
| 5563 | 5652 | const target = mod.getTarget(); |
| 5564 | 5653 | |
| 5565 | 5654 | if (intrinsicsAllowed(dest_scalar_ty, target)) { |
| ... | ... | @@ -5600,7 +5689,7 @@ pub const FuncGen = struct { |
| 5600 | 5689 | param_types = [1]*llvm.Type{v2i64}; |
| 5601 | 5690 | } |
| 5602 | 5691 | |
| 5603 | | const libc_fn = self.getLibcFunction(fn_name, &param_types, dest_llvm_ty); |
| 5692 | const libc_fn = try self.getLibcFunction(fn_name, &param_types, dest_llvm_ty); |
| 5604 | 5693 | const params = [1]*llvm.Value{extended}; |
| 5605 | 5694 | |
| 5606 | 5695 | return self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, ""); |
| ... | ... | @@ -5620,7 +5709,7 @@ pub const FuncGen = struct { |
| 5620 | 5709 | |
| 5621 | 5710 | const dest_ty = self.typeOfIndex(inst); |
| 5622 | 5711 | const dest_scalar_ty = dest_ty.scalarType(mod); |
| 5623 | | const dest_llvm_ty = try o.lowerType(dest_ty); |
| 5712 | const dest_llvm_ty = try o.lowerLlvmType(dest_ty); |
| 5624 | 5713 | |
| 5625 | 5714 | if (intrinsicsAllowed(operand_scalar_ty, target)) { |
| 5626 | 5715 | // TODO set fast math flag |
| ... | ... | @@ -5652,9 +5741,9 @@ pub const FuncGen = struct { |
| 5652 | 5741 | compiler_rt_dest_abbrev, |
| 5653 | 5742 | }) catch unreachable; |
| 5654 | 5743 | |
| 5655 | | const operand_llvm_ty = try o.lowerType(operand_ty); |
| 5744 | const operand_llvm_ty = try o.lowerLlvmType(operand_ty); |
| 5656 | 5745 | const param_types = [1]*llvm.Type{operand_llvm_ty}; |
| 5657 | | const libc_fn = self.getLibcFunction(fn_name, &param_types, libc_ret_ty); |
| 5746 | const libc_fn = try self.getLibcFunction(fn_name, &param_types, libc_ret_ty); |
| 5658 | 5747 | const params = [1]*llvm.Value{operand}; |
| 5659 | 5748 | |
| 5660 | 5749 | var result = self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, ""); |
| ... | ... | @@ -5762,7 +5851,7 @@ pub const FuncGen = struct { |
| 5762 | 5851 | const array_ty = self.typeOf(bin_op.lhs); |
| 5763 | 5852 | const array_llvm_val = try self.resolveInst(bin_op.lhs); |
| 5764 | 5853 | const rhs = try self.resolveInst(bin_op.rhs); |
| 5765 | | const array_llvm_ty = try o.lowerType(array_ty); |
| 5854 | const array_llvm_ty = try o.lowerLlvmType(array_ty); |
| 5766 | 5855 | const elem_ty = array_ty.childType(mod); |
| 5767 | 5856 | if (isByRef(array_ty, mod)) { |
| 5768 | 5857 | const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs }; |
| ... | ... | @@ -5773,7 +5862,7 @@ pub const FuncGen = struct { |
| 5773 | 5862 | |
| 5774 | 5863 | return self.loadByRef(elem_ptr, elem_ty, elem_ty.abiAlignment(mod), false); |
| 5775 | 5864 | } else { |
| 5776 | | const elem_llvm_ty = try o.lowerType(elem_ty); |
| 5865 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); |
| 5777 | 5866 | if (Air.refToIndex(bin_op.lhs)) |lhs_index| { |
| 5778 | 5867 | if (self.air.instructions.items(.tag)[lhs_index] == .load) { |
| 5779 | 5868 | const load_data = self.air.instructions.items(.data)[lhs_index]; |
| ... | ... | @@ -5898,7 +5987,7 @@ pub const FuncGen = struct { |
| 5898 | 5987 | const containing_int = struct_llvm_val; |
| 5899 | 5988 | const shift_amt = containing_int.typeOf().constInt(bit_offset, .False); |
| 5900 | 5989 | const shifted_value = self.builder.buildLShr(containing_int, shift_amt, ""); |
| 5901 | | const elem_llvm_ty = try o.lowerType(field_ty); |
| 5990 | const elem_llvm_ty = try o.lowerLlvmType(field_ty); |
| 5902 | 5991 | if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) { |
| 5903 | 5992 | const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod))); |
| 5904 | 5993 | const same_size_int = self.context.intType(elem_bits); |
| ... | ... | @@ -5920,7 +6009,7 @@ pub const FuncGen = struct { |
| 5920 | 6009 | .Union => { |
| 5921 | 6010 | assert(struct_ty.containerLayout(mod) == .Packed); |
| 5922 | 6011 | const containing_int = struct_llvm_val; |
| 5923 | | const elem_llvm_ty = try o.lowerType(field_ty); |
| 6012 | const elem_llvm_ty = try o.lowerLlvmType(field_ty); |
| 5924 | 6013 | if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) { |
| 5925 | 6014 | const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod))); |
| 5926 | 6015 | const same_size_int = self.context.intType(elem_bits); |
| ... | ... | @@ -5942,7 +6031,7 @@ pub const FuncGen = struct { |
| 5942 | 6031 | .Struct => { |
| 5943 | 6032 | assert(struct_ty.containerLayout(mod) != .Packed); |
| 5944 | 6033 | const llvm_field = llvmField(struct_ty, field_index, mod).?; |
| 5945 | | const struct_llvm_ty = try o.lowerType(struct_ty); |
| 6034 | const struct_llvm_ty = try o.lowerLlvmType(struct_ty); |
| 5946 | 6035 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field.index, ""); |
| 5947 | 6036 | const field_ptr_ty = try mod.ptrType(.{ |
| 5948 | 6037 | .child = llvm_field.ty.toIntern(), |
| ... | ... | @@ -5961,11 +6050,11 @@ pub const FuncGen = struct { |
| 5961 | 6050 | } |
| 5962 | 6051 | }, |
| 5963 | 6052 | .Union => { |
| 5964 | | const union_llvm_ty = try o.lowerType(struct_ty); |
| 6053 | const union_llvm_ty = try o.lowerLlvmType(struct_ty); |
| 5965 | 6054 | const layout = struct_ty.unionGetLayout(mod); |
| 5966 | 6055 | const payload_index = @intFromBool(layout.tag_align >= layout.payload_align); |
| 5967 | 6056 | const field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, ""); |
| 5968 | | const llvm_field_ty = try o.lowerType(field_ty); |
| 6057 | const llvm_field_ty = try o.lowerLlvmType(field_ty); |
| 5969 | 6058 | if (isByRef(field_ty, mod)) { |
| 5970 | 6059 | if (canElideLoad(self, body_tail)) |
| 5971 | 6060 | return field_ptr; |
| ... | ... | @@ -5991,7 +6080,7 @@ pub const FuncGen = struct { |
| 5991 | 6080 | const parent_ty = self.air.getRefType(ty_pl.ty).childType(mod); |
| 5992 | 6081 | const field_offset = parent_ty.structFieldOffset(extra.field_index, mod); |
| 5993 | 6082 | |
| 5994 | | const res_ty = try o.lowerType(self.air.getRefType(ty_pl.ty)); |
| 6083 | const res_ty = try o.lowerLlvmType(self.air.getRefType(ty_pl.ty)); |
| 5995 | 6084 | if (field_offset == 0) { |
| 5996 | 6085 | return field_ptr; |
| 5997 | 6086 | } |
| ... | ... | @@ -6273,7 +6362,7 @@ pub const FuncGen = struct { |
| 6273 | 6362 | } |
| 6274 | 6363 | } else { |
| 6275 | 6364 | const ret_ty = self.typeOfIndex(inst); |
| 6276 | | llvm_ret_types[llvm_ret_i] = try o.lowerType(ret_ty); |
| 6365 | llvm_ret_types[llvm_ret_i] = try o.lowerLlvmType(ret_ty); |
| 6277 | 6366 | llvm_ret_i += 1; |
| 6278 | 6367 | } |
| 6279 | 6368 | |
| ... | ... | @@ -6316,7 +6405,7 @@ pub const FuncGen = struct { |
| 6316 | 6405 | llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf(); |
| 6317 | 6406 | } else { |
| 6318 | 6407 | const alignment = arg_ty.abiAlignment(mod); |
| 6319 | | const arg_llvm_ty = try o.lowerType(arg_ty); |
| 6408 | const arg_llvm_ty = try o.lowerLlvmType(arg_ty); |
| 6320 | 6409 | const load_inst = self.builder.buildLoad(arg_llvm_ty, arg_llvm_value, ""); |
| 6321 | 6410 | load_inst.setAlignment(alignment); |
| 6322 | 6411 | llvm_param_values[llvm_param_i] = load_inst; |
| ... | ... | @@ -6554,7 +6643,7 @@ pub const FuncGen = struct { |
| 6554 | 6643 | const operand = try self.resolveInst(un_op); |
| 6555 | 6644 | const operand_ty = self.typeOf(un_op); |
| 6556 | 6645 | const optional_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; |
| 6557 | | const optional_llvm_ty = try o.lowerType(optional_ty); |
| 6646 | const optional_llvm_ty = try o.lowerLlvmType(optional_ty); |
| 6558 | 6647 | const payload_ty = optional_ty.optionalChild(mod); |
| 6559 | 6648 | if (optional_ty.optionalReprIsPayload(mod)) { |
| 6560 | 6649 | const loaded = if (operand_is_ptr) |
| ... | ... | @@ -6563,7 +6652,7 @@ pub const FuncGen = struct { |
| 6563 | 6652 | operand; |
| 6564 | 6653 | if (payload_ty.isSlice(mod)) { |
| 6565 | 6654 | const slice_ptr = self.builder.buildExtractValue(loaded, 0, ""); |
| 6566 | | const ptr_ty = try o.lowerType(payload_ty.slicePtrFieldType(mod)); |
| 6655 | const ptr_ty = try o.lowerLlvmType(payload_ty.slicePtrFieldType(mod)); |
| 6567 | 6656 | return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), ""); |
| 6568 | 6657 | } |
| 6569 | 6658 | return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), ""); |
| ... | ... | @@ -6602,7 +6691,7 @@ pub const FuncGen = struct { |
| 6602 | 6691 | const operand_ty = self.typeOf(un_op); |
| 6603 | 6692 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; |
| 6604 | 6693 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| 6605 | | const err_set_ty = try o.lowerType(Type.anyerror); |
| 6694 | const err_set_ty = try o.lowerLlvmType(Type.anyerror); |
| 6606 | 6695 | const zero = err_set_ty.constNull(); |
| 6607 | 6696 | |
| 6608 | 6697 | if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { |
| ... | ... | @@ -6616,7 +6705,7 @@ pub const FuncGen = struct { |
| 6616 | 6705 | |
| 6617 | 6706 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 6618 | 6707 | const loaded = if (operand_is_ptr) |
| 6619 | | self.builder.buildLoad(try o.lowerType(err_union_ty), operand, "") |
| 6708 | self.builder.buildLoad(try o.lowerLlvmType(err_union_ty), operand, "") |
| 6620 | 6709 | else |
| 6621 | 6710 | operand; |
| 6622 | 6711 | return self.builder.buildICmp(op, loaded, zero, ""); |
| ... | ... | @@ -6625,7 +6714,7 @@ pub const FuncGen = struct { |
| 6625 | 6714 | const err_field_index = errUnionErrorOffset(payload_ty, mod); |
| 6626 | 6715 | |
| 6627 | 6716 | if (operand_is_ptr or isByRef(err_union_ty, mod)) { |
| 6628 | | const err_union_llvm_ty = try o.lowerType(err_union_ty); |
| 6717 | const err_union_llvm_ty = try o.lowerLlvmType(err_union_ty); |
| 6629 | 6718 | const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, err_field_index, ""); |
| 6630 | 6719 | const loaded = self.builder.buildLoad(err_set_ty, err_field_ptr, ""); |
| 6631 | 6720 | return self.builder.buildICmp(op, loaded, zero, ""); |
| ... | ... | @@ -6651,7 +6740,7 @@ pub const FuncGen = struct { |
| 6651 | 6740 | // The payload and the optional are the same value. |
| 6652 | 6741 | return operand; |
| 6653 | 6742 | } |
| 6654 | | const optional_llvm_ty = try o.lowerType(optional_ty); |
| 6743 | const optional_llvm_ty = try o.lowerLlvmType(optional_ty); |
| 6655 | 6744 | return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, ""); |
| 6656 | 6745 | } |
| 6657 | 6746 | |
| ... | ... | @@ -6677,7 +6766,7 @@ pub const FuncGen = struct { |
| 6677 | 6766 | } |
| 6678 | 6767 | |
| 6679 | 6768 | // First set the non-null bit. |
| 6680 | | const optional_llvm_ty = try o.lowerType(optional_ty); |
| 6769 | const optional_llvm_ty = try o.lowerLlvmType(optional_ty); |
| 6681 | 6770 | const non_null_ptr = self.builder.buildStructGEP(optional_llvm_ty, operand, 1, ""); |
| 6682 | 6771 | // TODO set alignment on this store |
| 6683 | 6772 | _ = self.builder.buildStore(non_null_bit, non_null_ptr); |
| ... | ... | @@ -6704,7 +6793,7 @@ pub const FuncGen = struct { |
| 6704 | 6793 | return operand; |
| 6705 | 6794 | } |
| 6706 | 6795 | |
| 6707 | | const opt_llvm_ty = try o.lowerType(optional_ty); |
| 6796 | const opt_llvm_ty = try o.lowerLlvmType(optional_ty); |
| 6708 | 6797 | const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false; |
| 6709 | 6798 | return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load); |
| 6710 | 6799 | } |
| ... | ... | @@ -6728,7 +6817,7 @@ pub const FuncGen = struct { |
| 6728 | 6817 | return if (operand_is_ptr) operand else null; |
| 6729 | 6818 | } |
| 6730 | 6819 | const offset = errUnionPayloadOffset(payload_ty, mod); |
| 6731 | | const err_union_llvm_ty = try o.lowerType(err_union_ty); |
| 6820 | const err_union_llvm_ty = try o.lowerLlvmType(err_union_ty); |
| 6732 | 6821 | if (operand_is_ptr) { |
| 6733 | 6822 | return self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, ""); |
| 6734 | 6823 | } else if (isByRef(err_union_ty, mod)) { |
| ... | ... | @@ -6758,7 +6847,7 @@ pub const FuncGen = struct { |
| 6758 | 6847 | const operand_ty = self.typeOf(ty_op.operand); |
| 6759 | 6848 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; |
| 6760 | 6849 | if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { |
| 6761 | | const err_llvm_ty = try o.lowerType(Type.anyerror); |
| 6850 | const err_llvm_ty = try o.lowerLlvmType(Type.anyerror); |
| 6762 | 6851 | if (operand_is_ptr) { |
| 6763 | 6852 | return operand; |
| 6764 | 6853 | } else { |
| ... | ... | @@ -6766,7 +6855,7 @@ pub const FuncGen = struct { |
| 6766 | 6855 | } |
| 6767 | 6856 | } |
| 6768 | 6857 | |
| 6769 | | const err_set_llvm_ty = try o.lowerType(Type.anyerror); |
| 6858 | const err_set_llvm_ty = try o.lowerLlvmType(Type.anyerror); |
| 6770 | 6859 | |
| 6771 | 6860 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| 6772 | 6861 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| ... | ... | @@ -6777,7 +6866,7 @@ pub const FuncGen = struct { |
| 6777 | 6866 | const offset = errUnionErrorOffset(payload_ty, mod); |
| 6778 | 6867 | |
| 6779 | 6868 | if (operand_is_ptr or isByRef(err_union_ty, mod)) { |
| 6780 | | const err_union_llvm_ty = try o.lowerType(err_union_ty); |
| 6869 | const err_union_llvm_ty = try o.lowerLlvmType(err_union_ty); |
| 6781 | 6870 | const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, ""); |
| 6782 | 6871 | return self.builder.buildLoad(err_set_llvm_ty, err_field_ptr, ""); |
| 6783 | 6872 | } |
| ... | ... | @@ -6798,7 +6887,7 @@ pub const FuncGen = struct { |
| 6798 | 6887 | _ = self.builder.buildStore(non_error_val, operand); |
| 6799 | 6888 | return operand; |
| 6800 | 6889 | } |
| 6801 | | const err_union_llvm_ty = try o.lowerType(err_union_ty); |
| 6890 | const err_union_llvm_ty = try o.lowerLlvmType(err_union_ty); |
| 6802 | 6891 | { |
| 6803 | 6892 | const error_offset = errUnionErrorOffset(payload_ty, mod); |
| 6804 | 6893 | // First set the non-error value. |
| ... | ... | @@ -6834,7 +6923,7 @@ pub const FuncGen = struct { |
| 6834 | 6923 | |
| 6835 | 6924 | const mod = o.module; |
| 6836 | 6925 | const llvm_field = llvmField(struct_ty, field_index, mod).?; |
| 6837 | | const struct_llvm_ty = try o.lowerType(struct_ty); |
| 6926 | const struct_llvm_ty = try o.lowerLlvmType(struct_ty); |
| 6838 | 6927 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field.index, ""); |
| 6839 | 6928 | const field_ptr_ty = try mod.ptrType(.{ |
| 6840 | 6929 | .child = llvm_field.ty.toIntern(), |
| ... | ... | @@ -6858,7 +6947,7 @@ pub const FuncGen = struct { |
| 6858 | 6947 | if (optional_ty.optionalReprIsPayload(mod)) { |
| 6859 | 6948 | return operand; |
| 6860 | 6949 | } |
| 6861 | | const llvm_optional_ty = try o.lowerType(optional_ty); |
| 6950 | const llvm_optional_ty = try o.lowerLlvmType(optional_ty); |
| 6862 | 6951 | if (isByRef(optional_ty, mod)) { |
| 6863 | 6952 | const optional_ptr = self.buildAlloca(llvm_optional_ty, optional_ty.abiAlignment(mod)); |
| 6864 | 6953 | const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, ""); |
| ... | ... | @@ -6882,8 +6971,8 @@ pub const FuncGen = struct { |
| 6882 | 6971 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 6883 | 6972 | return operand; |
| 6884 | 6973 | } |
| 6885 | | const ok_err_code = (try o.lowerType(Type.anyerror)).constNull(); |
| 6886 | | const err_un_llvm_ty = try o.lowerType(err_un_ty); |
| 6974 | const ok_err_code = (try o.lowerLlvmType(Type.anyerror)).constNull(); |
| 6975 | const err_un_llvm_ty = try o.lowerLlvmType(err_un_ty); |
| 6887 | 6976 | |
| 6888 | 6977 | const payload_offset = errUnionPayloadOffset(payload_ty, mod); |
| 6889 | 6978 | const error_offset = errUnionErrorOffset(payload_ty, mod); |
| ... | ... | @@ -6912,7 +7001,7 @@ pub const FuncGen = struct { |
| 6912 | 7001 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 6913 | 7002 | return operand; |
| 6914 | 7003 | } |
| 6915 | | const err_un_llvm_ty = try o.lowerType(err_un_ty); |
| 7004 | const err_un_llvm_ty = try o.lowerLlvmType(err_un_ty); |
| 6916 | 7005 | |
| 6917 | 7006 | const payload_offset = errUnionPayloadOffset(payload_ty, mod); |
| 6918 | 7007 | const error_offset = errUnionErrorOffset(payload_ty, mod); |
| ... | ... | @@ -6968,7 +7057,7 @@ pub const FuncGen = struct { |
| 6968 | 7057 | const operand = try self.resolveInst(extra.rhs); |
| 6969 | 7058 | |
| 6970 | 7059 | const loaded_vector = blk: { |
| 6971 | | const elem_llvm_ty = try o.lowerType(vector_ptr_ty.childType(mod)); |
| 7060 | const elem_llvm_ty = try o.lowerLlvmType(vector_ptr_ty.childType(mod)); |
| 6972 | 7061 | const load_inst = self.builder.buildLoad(elem_llvm_ty, vector_ptr, ""); |
| 6973 | 7062 | load_inst.setAlignment(vector_ptr_ty.ptrAlignment(mod)); |
| 6974 | 7063 | load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr(mod))); |
| ... | ... | @@ -7012,7 +7101,7 @@ pub const FuncGen = struct { |
| 7012 | 7101 | const ptr = try self.resolveInst(bin_op.lhs); |
| 7013 | 7102 | const len = try self.resolveInst(bin_op.rhs); |
| 7014 | 7103 | const inst_ty = self.typeOfIndex(inst); |
| 7015 | | const llvm_slice_ty = try o.lowerType(inst_ty); |
| 7104 | const llvm_slice_ty = try o.lowerLlvmType(inst_ty); |
| 7016 | 7105 | |
| 7017 | 7106 | // In case of slicing a global, the result type looks something like `{ i8*, i64 }` |
| 7018 | 7107 | // but `ptr` is pointing to the global directly. |
| ... | ... | @@ -7056,7 +7145,7 @@ pub const FuncGen = struct { |
| 7056 | 7145 | true => signed_intrinsic, |
| 7057 | 7146 | false => unsigned_intrinsic, |
| 7058 | 7147 | }; |
| 7059 | | const llvm_inst_ty = try o.lowerType(inst_ty); |
| 7148 | const llvm_inst_ty = try o.lowerLlvmType(inst_ty); |
| 7060 | 7149 | const llvm_fn = fg.getIntrinsic(intrinsic_name, &.{llvm_inst_ty}); |
| 7061 | 7150 | const result_struct = fg.builder.buildCall( |
| 7062 | 7151 | llvm_fn.globalGetValueType(), |
| ... | ... | @@ -7229,11 +7318,11 @@ pub const FuncGen = struct { |
| 7229 | 7318 | return self.buildFloatOp(.floor, inst_ty, 1, .{result}); |
| 7230 | 7319 | } |
| 7231 | 7320 | if (scalar_ty.isSignedInt(mod)) { |
| 7232 | | const inst_llvm_ty = try o.lowerType(inst_ty); |
| 7321 | const inst_llvm_ty = try o.lowerLlvmType(inst_ty); |
| 7233 | 7322 | const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1; |
| 7234 | 7323 | const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: { |
| 7235 | 7324 | const vec_len = inst_ty.vectorLen(mod); |
| 7236 | | const scalar_llvm_ty = try o.lowerType(scalar_ty); |
| 7325 | const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty); |
| 7237 | 7326 | |
| 7238 | 7327 | const shifts = try self.gpa.alloc(*llvm.Value, vec_len); |
| 7239 | 7328 | defer self.gpa.free(shifts); |
| ... | ... | @@ -7295,7 +7384,7 @@ pub const FuncGen = struct { |
| 7295 | 7384 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7296 | 7385 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7297 | 7386 | const inst_ty = self.typeOfIndex(inst); |
| 7298 | | const inst_llvm_ty = try o.lowerType(inst_ty); |
| 7387 | const inst_llvm_ty = try o.lowerLlvmType(inst_ty); |
| 7299 | 7388 | const scalar_ty = inst_ty.scalarType(mod); |
| 7300 | 7389 | |
| 7301 | 7390 | if (scalar_ty.isRuntimeFloat()) { |
| ... | ... | @@ -7310,7 +7399,7 @@ pub const FuncGen = struct { |
| 7310 | 7399 | const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1; |
| 7311 | 7400 | const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: { |
| 7312 | 7401 | const vec_len = inst_ty.vectorLen(mod); |
| 7313 | | const scalar_llvm_ty = try o.lowerType(scalar_ty); |
| 7402 | const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty); |
| 7314 | 7403 | |
| 7315 | 7404 | const shifts = try self.gpa.alloc(*llvm.Value, vec_len); |
| 7316 | 7405 | defer self.gpa.free(shifts); |
| ... | ... | @@ -7408,8 +7497,8 @@ pub const FuncGen = struct { |
| 7408 | 7497 | |
| 7409 | 7498 | const intrinsic_name = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic; |
| 7410 | 7499 | |
| 7411 | | const llvm_lhs_ty = try o.lowerType(lhs_ty); |
| 7412 | | const llvm_dest_ty = try o.lowerType(dest_ty); |
| 7500 | const llvm_lhs_ty = try o.lowerLlvmType(lhs_ty); |
| 7501 | const llvm_dest_ty = try o.lowerLlvmType(dest_ty); |
| 7413 | 7502 | |
| 7414 | 7503 | const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty}); |
| 7415 | 7504 | const result_struct = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &[_]*llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, ""); |
| ... | ... | @@ -7472,15 +7561,30 @@ pub const FuncGen = struct { |
| 7472 | 7561 | fn_name: [:0]const u8, |
| 7473 | 7562 | param_types: []const *llvm.Type, |
| 7474 | 7563 | return_type: *llvm.Type, |
| 7475 | | ) *llvm.Value { |
| 7564 | ) Allocator.Error!*llvm.Value { |
| 7476 | 7565 | const o = self.dg.object; |
| 7477 | 7566 | return o.llvm_module.getNamedFunction(fn_name.ptr) orelse b: { |
| 7478 | 7567 | const alias = o.llvm_module.getNamedGlobalAlias(fn_name.ptr, fn_name.len); |
| 7479 | 7568 | break :b if (alias) |a| a.getAliasee() else null; |
| 7480 | 7569 | } orelse b: { |
| 7570 | const name = try o.builder.string(fn_name); |
| 7571 | |
| 7481 | 7572 | const params_len = @as(c_uint, @intCast(param_types.len)); |
| 7482 | 7573 | const fn_type = llvm.functionType(return_type, param_types.ptr, params_len, .False); |
| 7483 | | const f = o.llvm_module.addFunction(fn_name, fn_type); |
| 7574 | const f = o.llvm_module.addFunction(name.toSlice(&o.builder).?, fn_type); |
| 7575 | |
| 7576 | var global = Builder.Global{ |
| 7577 | .type = .void, |
| 7578 | .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) }, |
| 7579 | }; |
| 7580 | var function = Builder.Function{ |
| 7581 | .global = @enumFromInt(o.builder.globals.count()), |
| 7582 | }; |
| 7583 | |
| 7584 | try o.builder.llvm_globals.append(self.gpa, f); |
| 7585 | _ = try o.builder.addGlobal(name, global); |
| 7586 | try o.builder.functions.append(self.gpa, function); |
| 7587 | |
| 7484 | 7588 | break :b f; |
| 7485 | 7589 | }; |
| 7486 | 7590 | } |
| ... | ... | @@ -7497,7 +7601,7 @@ pub const FuncGen = struct { |
| 7497 | 7601 | const mod = o.module; |
| 7498 | 7602 | const target = o.module.getTarget(); |
| 7499 | 7603 | const scalar_ty = ty.scalarType(mod); |
| 7500 | | const scalar_llvm_ty = try o.lowerType(scalar_ty); |
| 7604 | const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty); |
| 7501 | 7605 | |
| 7502 | 7606 | if (intrinsicsAllowed(scalar_ty, target)) { |
| 7503 | 7607 | const llvm_predicate: llvm.RealPredicate = switch (pred) { |
| ... | ... | @@ -7528,7 +7632,7 @@ pub const FuncGen = struct { |
| 7528 | 7632 | |
| 7529 | 7633 | const param_types = [2]*llvm.Type{ scalar_llvm_ty, scalar_llvm_ty }; |
| 7530 | 7634 | const llvm_i32 = self.context.intType(32); |
| 7531 | | const libc_fn = self.getLibcFunction(fn_name, param_types[0..], llvm_i32); |
| 7635 | const libc_fn = try self.getLibcFunction(fn_name, param_types[0..], llvm_i32); |
| 7532 | 7636 | |
| 7533 | 7637 | const zero = llvm_i32.constInt(0, .False); |
| 7534 | 7638 | const int_pred: llvm.IntPredicate = switch (pred) { |
| ... | ... | @@ -7600,8 +7704,8 @@ pub const FuncGen = struct { |
| 7600 | 7704 | const mod = o.module; |
| 7601 | 7705 | const target = mod.getTarget(); |
| 7602 | 7706 | const scalar_ty = ty.scalarType(mod); |
| 7603 | | const llvm_ty = try o.lowerType(ty); |
| 7604 | | const scalar_llvm_ty = try o.lowerType(scalar_ty); |
| 7707 | const llvm_ty = try o.lowerLlvmType(ty); |
| 7708 | const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty); |
| 7605 | 7709 | |
| 7606 | 7710 | const intrinsics_allowed = op != .tan and intrinsicsAllowed(scalar_ty, target); |
| 7607 | 7711 | var fn_name_buf: [64]u8 = undefined; |
| ... | ... | @@ -7672,7 +7776,7 @@ pub const FuncGen = struct { |
| 7672 | 7776 | .intrinsic => |fn_name| self.getIntrinsic(fn_name, &.{llvm_ty}), |
| 7673 | 7777 | .libc => |fn_name| b: { |
| 7674 | 7778 | const param_types = [3]*llvm.Type{ scalar_llvm_ty, scalar_llvm_ty, scalar_llvm_ty }; |
| 7675 | | const libc_fn = self.getLibcFunction(fn_name, param_types[0..params.len], scalar_llvm_ty); |
| 7779 | const libc_fn = try self.getLibcFunction(fn_name, param_types[0..params.len], scalar_llvm_ty); |
| 7676 | 7780 | if (ty.zigTypeTag(mod) == .Vector) { |
| 7677 | 7781 | const result = llvm_ty.getUndef(); |
| 7678 | 7782 | return self.buildElementwiseCall(libc_fn, &params, result, ty.vectorLen(mod)); |
| ... | ... | @@ -7711,10 +7815,10 @@ pub const FuncGen = struct { |
| 7711 | 7815 | const rhs_scalar_ty = rhs_ty.scalarType(mod); |
| 7712 | 7816 | |
| 7713 | 7817 | const dest_ty = self.typeOfIndex(inst); |
| 7714 | | const llvm_dest_ty = try o.lowerType(dest_ty); |
| 7818 | const llvm_dest_ty = try o.lowerLlvmType(dest_ty); |
| 7715 | 7819 | |
| 7716 | 7820 | const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod)) |
| 7717 | | self.builder.buildZExt(rhs, try o.lowerType(lhs_ty), "") |
| 7821 | self.builder.buildZExt(rhs, try o.lowerLlvmType(lhs_ty), "") |
| 7718 | 7822 | else |
| 7719 | 7823 | rhs; |
| 7720 | 7824 | |
| ... | ... | @@ -7785,7 +7889,7 @@ pub const FuncGen = struct { |
| 7785 | 7889 | const rhs_scalar_ty = rhs_ty.scalarType(mod); |
| 7786 | 7890 | |
| 7787 | 7891 | const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod)) |
| 7788 | | self.builder.buildZExt(rhs, try o.lowerType(lhs_ty), "") |
| 7892 | self.builder.buildZExt(rhs, try o.lowerLlvmType(lhs_ty), "") |
| 7789 | 7893 | else |
| 7790 | 7894 | rhs; |
| 7791 | 7895 | if (lhs_scalar_ty.isSignedInt(mod)) return self.builder.buildNSWShl(lhs, casted_rhs, ""); |
| ... | ... | @@ -7806,7 +7910,7 @@ pub const FuncGen = struct { |
| 7806 | 7910 | const rhs_scalar_ty = rhs_type.scalarType(mod); |
| 7807 | 7911 | |
| 7808 | 7912 | const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod)) |
| 7809 | | self.builder.buildZExt(rhs, try o.lowerType(lhs_type), "") |
| 7913 | self.builder.buildZExt(rhs, try o.lowerLlvmType(lhs_type), "") |
| 7810 | 7914 | else |
| 7811 | 7915 | rhs; |
| 7812 | 7916 | return self.builder.buildShl(lhs, casted_rhs, ""); |
| ... | ... | @@ -7841,7 +7945,7 @@ pub const FuncGen = struct { |
| 7841 | 7945 | // poison value." |
| 7842 | 7946 | // However Zig semantics says that saturating shift left can never produce |
| 7843 | 7947 | // undefined; instead it saturates. |
| 7844 | | const lhs_scalar_llvm_ty = try o.lowerType(lhs_scalar_ty); |
| 7948 | const lhs_scalar_llvm_ty = try o.lowerLlvmType(lhs_scalar_ty); |
| 7845 | 7949 | const bits = lhs_scalar_llvm_ty.constInt(lhs_bits, .False); |
| 7846 | 7950 | const lhs_max = lhs_scalar_llvm_ty.constAllOnes(); |
| 7847 | 7951 | if (rhs_ty.zigTypeTag(mod) == .Vector) { |
| ... | ... | @@ -7870,7 +7974,7 @@ pub const FuncGen = struct { |
| 7870 | 7974 | const rhs_scalar_ty = rhs_ty.scalarType(mod); |
| 7871 | 7975 | |
| 7872 | 7976 | const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod)) |
| 7873 | | self.builder.buildZExt(rhs, try o.lowerType(lhs_ty), "") |
| 7977 | self.builder.buildZExt(rhs, try o.lowerLlvmType(lhs_ty), "") |
| 7874 | 7978 | else |
| 7875 | 7979 | rhs; |
| 7876 | 7980 | const is_signed_int = lhs_scalar_ty.isSignedInt(mod); |
| ... | ... | @@ -7896,7 +8000,7 @@ pub const FuncGen = struct { |
| 7896 | 8000 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 7897 | 8001 | const dest_ty = self.typeOfIndex(inst); |
| 7898 | 8002 | const dest_info = dest_ty.intInfo(mod); |
| 7899 | | const dest_llvm_ty = try o.lowerType(dest_ty); |
| 8003 | const dest_llvm_ty = try o.lowerLlvmType(dest_ty); |
| 7900 | 8004 | const operand = try self.resolveInst(ty_op.operand); |
| 7901 | 8005 | const operand_ty = self.typeOf(ty_op.operand); |
| 7902 | 8006 | const operand_info = operand_ty.intInfo(mod); |
| ... | ... | @@ -7917,7 +8021,7 @@ pub const FuncGen = struct { |
| 7917 | 8021 | const o = self.dg.object; |
| 7918 | 8022 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 7919 | 8023 | const operand = try self.resolveInst(ty_op.operand); |
| 7920 | | const dest_llvm_ty = try o.lowerType(self.typeOfIndex(inst)); |
| 8024 | const dest_llvm_ty = try o.lowerLlvmType(self.typeOfIndex(inst)); |
| 7921 | 8025 | return self.builder.buildTrunc(operand, dest_llvm_ty, ""); |
| 7922 | 8026 | } |
| 7923 | 8027 | |
| ... | ... | @@ -7933,11 +8037,11 @@ pub const FuncGen = struct { |
| 7933 | 8037 | const src_bits = operand_ty.floatBits(target); |
| 7934 | 8038 | |
| 7935 | 8039 | if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) { |
| 7936 | | const dest_llvm_ty = try o.lowerType(dest_ty); |
| 8040 | const dest_llvm_ty = try o.lowerLlvmType(dest_ty); |
| 7937 | 8041 | return self.builder.buildFPTrunc(operand, dest_llvm_ty, ""); |
| 7938 | 8042 | } else { |
| 7939 | | const operand_llvm_ty = try o.lowerType(operand_ty); |
| 7940 | | const dest_llvm_ty = try o.lowerType(dest_ty); |
| 8043 | const operand_llvm_ty = try o.lowerLlvmType(operand_ty); |
| 8044 | const dest_llvm_ty = try o.lowerLlvmType(dest_ty); |
| 7941 | 8045 | |
| 7942 | 8046 | var fn_name_buf: [64]u8 = undefined; |
| 7943 | 8047 | const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__trunc{s}f{s}f2", .{ |
| ... | ... | @@ -7946,7 +8050,7 @@ pub const FuncGen = struct { |
| 7946 | 8050 | |
| 7947 | 8051 | const params = [1]*llvm.Value{operand}; |
| 7948 | 8052 | const param_types = [1]*llvm.Type{operand_llvm_ty}; |
| 7949 | | const llvm_fn = self.getLibcFunction(fn_name, &param_types, dest_llvm_ty); |
| 8053 | const llvm_fn = try self.getLibcFunction(fn_name, &param_types, dest_llvm_ty); |
| 7950 | 8054 | |
| 7951 | 8055 | return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .C, .Auto, ""); |
| 7952 | 8056 | } |
| ... | ... | @@ -7964,11 +8068,11 @@ pub const FuncGen = struct { |
| 7964 | 8068 | const src_bits = operand_ty.floatBits(target); |
| 7965 | 8069 | |
| 7966 | 8070 | if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) { |
| 7967 | | const dest_llvm_ty = try o.lowerType(dest_ty); |
| 8071 | const dest_llvm_ty = try o.lowerLlvmType(dest_ty); |
| 7968 | 8072 | return self.builder.buildFPExt(operand, dest_llvm_ty, ""); |
| 7969 | 8073 | } else { |
| 7970 | | const operand_llvm_ty = try o.lowerType(operand_ty); |
| 7971 | | const dest_llvm_ty = try o.lowerType(dest_ty); |
| 8074 | const operand_llvm_ty = try o.lowerLlvmType(operand_ty); |
| 8075 | const dest_llvm_ty = try o.lowerLlvmType(dest_ty); |
| 7972 | 8076 | |
| 7973 | 8077 | var fn_name_buf: [64]u8 = undefined; |
| 7974 | 8078 | const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__extend{s}f{s}f2", .{ |
| ... | ... | @@ -7977,7 +8081,7 @@ pub const FuncGen = struct { |
| 7977 | 8081 | |
| 7978 | 8082 | const params = [1]*llvm.Value{operand}; |
| 7979 | 8083 | const param_types = [1]*llvm.Type{operand_llvm_ty}; |
| 7980 | | const llvm_fn = self.getLibcFunction(fn_name, &param_types, dest_llvm_ty); |
| 8084 | const llvm_fn = try self.getLibcFunction(fn_name, &param_types, dest_llvm_ty); |
| 7981 | 8085 | |
| 7982 | 8086 | return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .C, .Auto, ""); |
| 7983 | 8087 | } |
| ... | ... | @@ -7989,7 +8093,7 @@ pub const FuncGen = struct { |
| 7989 | 8093 | const operand = try self.resolveInst(un_op); |
| 7990 | 8094 | const ptr_ty = self.typeOf(un_op); |
| 7991 | 8095 | const operand_ptr = self.sliceOrArrayPtr(operand, ptr_ty); |
| 7992 | | const dest_llvm_ty = try o.lowerType(self.typeOfIndex(inst)); |
| 8096 | const dest_llvm_ty = try o.lowerLlvmType(self.typeOfIndex(inst)); |
| 7993 | 8097 | return self.builder.buildPtrToInt(operand_ptr, dest_llvm_ty, ""); |
| 7994 | 8098 | } |
| 7995 | 8099 | |
| ... | ... | @@ -8006,7 +8110,7 @@ pub const FuncGen = struct { |
| 8006 | 8110 | const mod = o.module; |
| 8007 | 8111 | const operand_is_ref = isByRef(operand_ty, mod); |
| 8008 | 8112 | const result_is_ref = isByRef(inst_ty, mod); |
| 8009 | | const llvm_dest_ty = try o.lowerType(inst_ty); |
| 8113 | const llvm_dest_ty = try o.lowerLlvmType(inst_ty); |
| 8010 | 8114 | |
| 8011 | 8115 | if (operand_is_ref and result_is_ref) { |
| 8012 | 8116 | // They are both pointers, so just return the same opaque pointer :) |
| ... | ... | @@ -8036,7 +8140,7 @@ pub const FuncGen = struct { |
| 8036 | 8140 | } else { |
| 8037 | 8141 | // If the ABI size of the element type is not evenly divisible by size in bits; |
| 8038 | 8142 | // a simple bitcast will not work, and we fall back to extractelement. |
| 8039 | | const llvm_usize = try o.lowerType(Type.usize); |
| 8143 | const llvm_usize = try o.lowerLlvmType(Type.usize); |
| 8040 | 8144 | const llvm_u32 = self.context.intType(32); |
| 8041 | 8145 | const zero = llvm_usize.constNull(); |
| 8042 | 8146 | const vector_len = operand_ty.arrayLen(mod); |
| ... | ... | @@ -8053,7 +8157,7 @@ pub const FuncGen = struct { |
| 8053 | 8157 | return array_ptr; |
| 8054 | 8158 | } else if (operand_ty.zigTypeTag(mod) == .Array and inst_ty.zigTypeTag(mod) == .Vector) { |
| 8055 | 8159 | const elem_ty = operand_ty.childType(mod); |
| 8056 | | const llvm_vector_ty = try o.lowerType(inst_ty); |
| 8160 | const llvm_vector_ty = try o.lowerLlvmType(inst_ty); |
| 8057 | 8161 | if (!operand_is_ref) { |
| 8058 | 8162 | return self.dg.todo("implement bitcast non-ref array to vector", .{}); |
| 8059 | 8163 | } |
| ... | ... | @@ -8068,9 +8172,9 @@ pub const FuncGen = struct { |
| 8068 | 8172 | } else { |
| 8069 | 8173 | // If the ABI size of the element type is not evenly divisible by size in bits; |
| 8070 | 8174 | // a simple bitcast will not work, and we fall back to extractelement. |
| 8071 | | const array_llvm_ty = try o.lowerType(operand_ty); |
| 8072 | | const elem_llvm_ty = try o.lowerType(elem_ty); |
| 8073 | | const llvm_usize = try o.lowerType(Type.usize); |
| 8175 | const array_llvm_ty = try o.lowerLlvmType(operand_ty); |
| 8176 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); |
| 8177 | const llvm_usize = try o.lowerLlvmType(Type.usize); |
| 8074 | 8178 | const llvm_u32 = self.context.intType(32); |
| 8075 | 8179 | const zero = llvm_usize.constNull(); |
| 8076 | 8180 | const vector_len = operand_ty.arrayLen(mod); |
| ... | ... | @@ -8179,7 +8283,7 @@ pub const FuncGen = struct { |
| 8179 | 8283 | if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) |
| 8180 | 8284 | return o.lowerPtrToVoid(ptr_ty); |
| 8181 | 8285 | |
| 8182 | | const pointee_llvm_ty = try o.lowerType(pointee_type); |
| 8286 | const pointee_llvm_ty = try o.lowerLlvmType(pointee_type); |
| 8183 | 8287 | const alignment = ptr_ty.ptrAlignment(mod); |
| 8184 | 8288 | return self.buildAlloca(pointee_llvm_ty, alignment); |
| 8185 | 8289 | } |
| ... | ... | @@ -8191,7 +8295,7 @@ pub const FuncGen = struct { |
| 8191 | 8295 | const ret_ty = ptr_ty.childType(mod); |
| 8192 | 8296 | if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return o.lowerPtrToVoid(ptr_ty); |
| 8193 | 8297 | if (self.ret_ptr) |ret_ptr| return ret_ptr; |
| 8194 | | const ret_llvm_ty = try o.lowerType(ret_ty); |
| 8298 | const ret_llvm_ty = try o.lowerLlvmType(ret_ty); |
| 8195 | 8299 | return self.buildAlloca(ret_llvm_ty, ptr_ty.ptrAlignment(mod)); |
| 8196 | 8300 | } |
| 8197 | 8301 | |
| ... | ... | @@ -8223,7 +8327,7 @@ pub const FuncGen = struct { |
| 8223 | 8327 | else |
| 8224 | 8328 | u8_llvm_ty.getUndef(); |
| 8225 | 8329 | const operand_size = operand_ty.abiSize(mod); |
| 8226 | | const usize_llvm_ty = try o.lowerType(Type.usize); |
| 8330 | const usize_llvm_ty = try o.lowerLlvmType(Type.usize); |
| 8227 | 8331 | const len = usize_llvm_ty.constInt(operand_size, .False); |
| 8228 | 8332 | const dest_ptr_align = ptr_ty.ptrAlignment(mod); |
| 8229 | 8333 | _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr(mod)); |
| ... | ... | @@ -8296,7 +8400,7 @@ pub const FuncGen = struct { |
| 8296 | 8400 | _ = inst; |
| 8297 | 8401 | const o = self.dg.object; |
| 8298 | 8402 | const mod = o.module; |
| 8299 | | const llvm_usize = try o.lowerType(Type.usize); |
| 8403 | const llvm_usize = try o.lowerLlvmType(Type.usize); |
| 8300 | 8404 | const target = mod.getTarget(); |
| 8301 | 8405 | if (!target_util.supportsReturnAddress(target)) { |
| 8302 | 8406 | // https://github.com/ziglang/zig/issues/11946 |
| ... | ... | @@ -8324,7 +8428,7 @@ pub const FuncGen = struct { |
| 8324 | 8428 | |
| 8325 | 8429 | const params = [_]*llvm.Value{llvm_i32.constNull()}; |
| 8326 | 8430 | const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, ""); |
| 8327 | | const llvm_usize = try o.lowerType(Type.usize); |
| 8431 | const llvm_usize = try o.lowerLlvmType(Type.usize); |
| 8328 | 8432 | return self.builder.buildPtrToInt(ptr_val, llvm_usize, ""); |
| 8329 | 8433 | } |
| 8330 | 8434 | |
| ... | ... | @@ -8370,7 +8474,7 @@ pub const FuncGen = struct { |
| 8370 | 8474 | |
| 8371 | 8475 | var payload = self.builder.buildExtractValue(result, 0, ""); |
| 8372 | 8476 | if (opt_abi_ty != null) { |
| 8373 | | payload = self.builder.buildTrunc(payload, try o.lowerType(operand_ty), ""); |
| 8477 | payload = self.builder.buildTrunc(payload, try o.lowerLlvmType(operand_ty), ""); |
| 8374 | 8478 | } |
| 8375 | 8479 | const success_bit = self.builder.buildExtractValue(result, 1, ""); |
| 8376 | 8480 | |
| ... | ... | @@ -8415,7 +8519,7 @@ pub const FuncGen = struct { |
| 8415 | 8519 | ordering, |
| 8416 | 8520 | single_threaded, |
| 8417 | 8521 | ); |
| 8418 | | const operand_llvm_ty = try o.lowerType(operand_ty); |
| 8522 | const operand_llvm_ty = try o.lowerLlvmType(operand_ty); |
| 8419 | 8523 | if (is_float) { |
| 8420 | 8524 | return self.builder.buildBitCast(uncasted_result, operand_llvm_ty, ""); |
| 8421 | 8525 | } else { |
| ... | ... | @@ -8428,7 +8532,7 @@ pub const FuncGen = struct { |
| 8428 | 8532 | } |
| 8429 | 8533 | |
| 8430 | 8534 | // It's a pointer but we need to treat it as an int. |
| 8431 | | const usize_llvm_ty = try o.lowerType(Type.usize); |
| 8535 | const usize_llvm_ty = try o.lowerLlvmType(Type.usize); |
| 8432 | 8536 | const casted_operand = self.builder.buildPtrToInt(operand, usize_llvm_ty, ""); |
| 8433 | 8537 | const uncasted_result = self.builder.buildAtomicRmw( |
| 8434 | 8538 | op, |
| ... | ... | @@ -8437,7 +8541,7 @@ pub const FuncGen = struct { |
| 8437 | 8541 | ordering, |
| 8438 | 8542 | single_threaded, |
| 8439 | 8543 | ); |
| 8440 | | const operand_llvm_ty = try o.lowerType(operand_ty); |
| 8544 | const operand_llvm_ty = try o.lowerLlvmType(operand_ty); |
| 8441 | 8545 | return self.builder.buildIntToPtr(uncasted_result, operand_llvm_ty, ""); |
| 8442 | 8546 | } |
| 8443 | 8547 | |
| ... | ... | @@ -8456,7 +8560,7 @@ pub const FuncGen = struct { |
| 8456 | 8560 | const ptr_alignment = @as(u32, @intCast(ptr_info.flags.alignment.toByteUnitsOptional() orelse |
| 8457 | 8561 | ptr_info.child.toType().abiAlignment(mod))); |
| 8458 | 8562 | const ptr_volatile = llvm.Bool.fromBool(ptr_info.flags.is_volatile); |
| 8459 | | const elem_llvm_ty = try o.lowerType(elem_ty); |
| 8563 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); |
| 8460 | 8564 | |
| 8461 | 8565 | if (opt_abi_llvm_ty) |abi_llvm_ty| { |
| 8462 | 8566 | // operand needs widening and truncating |
| ... | ... | @@ -8606,7 +8710,7 @@ pub const FuncGen = struct { |
| 8606 | 8710 | .One => llvm_usize_ty.constInt(ptr_ty.childType(mod).arrayLen(mod), .False), |
| 8607 | 8711 | .Many, .C => unreachable, |
| 8608 | 8712 | }; |
| 8609 | | const elem_llvm_ty = try o.lowerType(elem_ty); |
| 8713 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); |
| 8610 | 8714 | const len_gep = [_]*llvm.Value{len}; |
| 8611 | 8715 | const end_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, dest_ptr, &len_gep, len_gep.len, ""); |
| 8612 | 8716 | _ = self.builder.buildBr(loop_block); |
| ... | ... | @@ -8731,7 +8835,7 @@ pub const FuncGen = struct { |
| 8731 | 8835 | _ = self.builder.buildStore(new_tag, union_ptr); |
| 8732 | 8836 | return null; |
| 8733 | 8837 | } |
| 8734 | | const un_llvm_ty = try o.lowerType(un_ty); |
| 8838 | const un_llvm_ty = try o.lowerLlvmType(un_ty); |
| 8735 | 8839 | const tag_index = @intFromBool(layout.tag_align < layout.payload_align); |
| 8736 | 8840 | const tag_field_ptr = self.builder.buildStructGEP(un_llvm_ty, union_ptr, tag_index, ""); |
| 8737 | 8841 | // TODO alignment on this store |
| ... | ... | @@ -8748,7 +8852,7 @@ pub const FuncGen = struct { |
| 8748 | 8852 | if (layout.tag_size == 0) return null; |
| 8749 | 8853 | const union_handle = try self.resolveInst(ty_op.operand); |
| 8750 | 8854 | if (isByRef(un_ty, mod)) { |
| 8751 | | const llvm_un_ty = try o.lowerType(un_ty); |
| 8855 | const llvm_un_ty = try o.lowerLlvmType(un_ty); |
| 8752 | 8856 | if (layout.payload_size == 0) { |
| 8753 | 8857 | return self.builder.buildLoad(llvm_un_ty, union_handle, ""); |
| 8754 | 8858 | } |
| ... | ... | @@ -8790,13 +8894,13 @@ pub const FuncGen = struct { |
| 8790 | 8894 | const operand = try self.resolveInst(ty_op.operand); |
| 8791 | 8895 | |
| 8792 | 8896 | const llvm_i1 = self.context.intType(1); |
| 8793 | | const operand_llvm_ty = try o.lowerType(operand_ty); |
| 8897 | const operand_llvm_ty = try o.lowerLlvmType(operand_ty); |
| 8794 | 8898 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); |
| 8795 | 8899 | |
| 8796 | 8900 | const params = [_]*llvm.Value{ operand, llvm_i1.constNull() }; |
| 8797 | 8901 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); |
| 8798 | 8902 | const result_ty = self.typeOfIndex(inst); |
| 8799 | | const result_llvm_ty = try o.lowerType(result_ty); |
| 8903 | const result_llvm_ty = try o.lowerLlvmType(result_ty); |
| 8800 | 8904 | |
| 8801 | 8905 | const bits = operand_ty.intInfo(mod).bits; |
| 8802 | 8906 | const result_bits = result_ty.intInfo(mod).bits; |
| ... | ... | @@ -8817,12 +8921,12 @@ pub const FuncGen = struct { |
| 8817 | 8921 | const operand = try self.resolveInst(ty_op.operand); |
| 8818 | 8922 | |
| 8819 | 8923 | const params = [_]*llvm.Value{operand}; |
| 8820 | | const operand_llvm_ty = try o.lowerType(operand_ty); |
| 8924 | const operand_llvm_ty = try o.lowerLlvmType(operand_ty); |
| 8821 | 8925 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); |
| 8822 | 8926 | |
| 8823 | 8927 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); |
| 8824 | 8928 | const result_ty = self.typeOfIndex(inst); |
| 8825 | | const result_llvm_ty = try o.lowerType(result_ty); |
| 8929 | const result_llvm_ty = try o.lowerLlvmType(result_ty); |
| 8826 | 8930 | |
| 8827 | 8931 | const bits = operand_ty.intInfo(mod).bits; |
| 8828 | 8932 | const result_bits = result_ty.intInfo(mod).bits; |
| ... | ... | @@ -8844,7 +8948,7 @@ pub const FuncGen = struct { |
| 8844 | 8948 | assert(bits % 8 == 0); |
| 8845 | 8949 | |
| 8846 | 8950 | var operand = try self.resolveInst(ty_op.operand); |
| 8847 | | var operand_llvm_ty = try o.lowerType(operand_ty); |
| 8951 | var operand_llvm_ty = try o.lowerLlvmType(operand_ty); |
| 8848 | 8952 | |
| 8849 | 8953 | if (bits % 16 == 8) { |
| 8850 | 8954 | // If not an even byte-multiple, we need zero-extend + shift-left 1 byte |
| ... | ... | @@ -8878,7 +8982,7 @@ pub const FuncGen = struct { |
| 8878 | 8982 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); |
| 8879 | 8983 | |
| 8880 | 8984 | const result_ty = self.typeOfIndex(inst); |
| 8881 | | const result_llvm_ty = try o.lowerType(result_ty); |
| 8985 | const result_llvm_ty = try o.lowerLlvmType(result_ty); |
| 8882 | 8986 | const result_bits = result_ty.intInfo(mod).bits; |
| 8883 | 8987 | if (bits > result_bits) { |
| 8884 | 8988 | return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, ""); |
| ... | ... | @@ -8957,9 +9061,9 @@ pub const FuncGen = struct { |
| 8957 | 9061 | const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod); |
| 8958 | 9062 | const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{}", .{fqn.fmt(&mod.intern_pool)}); |
| 8959 | 9063 | |
| 8960 | | const param_types = [_]*llvm.Type{try o.lowerType(enum_type.tag_ty.toType())}; |
| 9064 | const param_types = [_]*llvm.Type{try o.lowerLlvmType(enum_type.tag_ty.toType())}; |
| 8961 | 9065 | |
| 8962 | | const llvm_ret_ty = try o.lowerType(Type.bool); |
| 9066 | const llvm_ret_ty = try o.lowerLlvmType(Type.bool); |
| 8963 | 9067 | const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False); |
| 8964 | 9068 | const fn_val = o.llvm_module.addFunction(llvm_fn_name, fn_type); |
| 8965 | 9069 | fn_val.setLinkage(.Internal); |
| ... | ... | @@ -9020,29 +9124,32 @@ pub const FuncGen = struct { |
| 9020 | 9124 | |
| 9021 | 9125 | // TODO: detect when the type changes and re-emit this function. |
| 9022 | 9126 | const gop = try o.decl_map.getOrPut(o.gpa, enum_type.decl); |
| 9023 | | if (gop.found_existing) return gop.value_ptr.*; |
| 9127 | if (gop.found_existing) return gop.value_ptr.toLlvm(&o.builder); |
| 9024 | 9128 | errdefer assert(o.decl_map.remove(enum_type.decl)); |
| 9025 | 9129 | |
| 9026 | | var arena_allocator = std.heap.ArenaAllocator.init(self.gpa); |
| 9027 | | defer arena_allocator.deinit(); |
| 9028 | | const arena = arena_allocator.allocator(); |
| 9029 | | |
| 9030 | 9130 | const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod); |
| 9031 | | const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{fqn.fmt(&mod.intern_pool)}); |
| 9131 | const llvm_fn_name = try o.builder.fmt("__zig_tag_name_{}", .{fqn.fmt(&mod.intern_pool)}); |
| 9032 | 9132 | |
| 9033 | 9133 | const slice_ty = Type.slice_const_u8_sentinel_0; |
| 9034 | | const llvm_ret_ty = try o.lowerType(slice_ty); |
| 9035 | | const usize_llvm_ty = try o.lowerType(Type.usize); |
| 9134 | const llvm_ret_ty = try o.lowerLlvmType(slice_ty); |
| 9135 | const usize_llvm_ty = try o.lowerLlvmType(Type.usize); |
| 9036 | 9136 | const slice_alignment = slice_ty.abiAlignment(mod); |
| 9037 | 9137 | |
| 9038 | | const param_types = [_]*llvm.Type{try o.lowerType(enum_type.tag_ty.toType())}; |
| 9138 | const param_types = [_]*llvm.Type{try o.lowerLlvmType(enum_type.tag_ty.toType())}; |
| 9039 | 9139 | |
| 9040 | 9140 | const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False); |
| 9041 | | const fn_val = o.llvm_module.addFunction(llvm_fn_name, fn_type); |
| 9141 | const fn_val = o.llvm_module.addFunction(llvm_fn_name.toSlice(&o.builder).?, fn_type); |
| 9042 | 9142 | fn_val.setLinkage(.Internal); |
| 9043 | 9143 | fn_val.setFunctionCallConv(.Fast); |
| 9044 | 9144 | o.addCommonFnAttributes(fn_val); |
| 9045 | | gop.value_ptr.* = fn_val; |
| 9145 | |
| 9146 | var global = Builder.Global{ |
| 9147 | .type = .void, |
| 9148 | .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) }, |
| 9149 | }; |
| 9150 | var function = Builder.Function{ |
| 9151 | .global = @enumFromInt(o.builder.globals.count()), |
| 9152 | }; |
| 9046 | 9153 | |
| 9047 | 9154 | const prev_block = self.builder.getInsertBlock(); |
| 9048 | 9155 | const prev_debug_location = self.builder.getCurrentDebugLocation2(); |
| ... | ... | @@ -9104,6 +9211,10 @@ pub const FuncGen = struct { |
| 9104 | 9211 | |
| 9105 | 9212 | self.builder.positionBuilderAtEnd(bad_value_block); |
| 9106 | 9213 | _ = self.builder.buildUnreachable(); |
| 9214 | |
| 9215 | try o.builder.llvm_globals.append(self.gpa, fn_val); |
| 9216 | gop.value_ptr.* = try o.builder.addGlobal(llvm_fn_name, global); |
| 9217 | try o.builder.functions.append(self.gpa, function); |
| 9107 | 9218 | return fn_val; |
| 9108 | 9219 | } |
| 9109 | 9220 | |
| ... | ... | @@ -9116,8 +9227,8 @@ pub const FuncGen = struct { |
| 9116 | 9227 | |
| 9117 | 9228 | // Function signature: fn (anyerror) bool |
| 9118 | 9229 | |
| 9119 | | const ret_llvm_ty = try o.lowerType(Type.bool); |
| 9120 | | const anyerror_llvm_ty = try o.lowerType(Type.anyerror); |
| 9230 | const ret_llvm_ty = try o.lowerLlvmType(Type.bool); |
| 9231 | const anyerror_llvm_ty = try o.lowerLlvmType(Type.anyerror); |
| 9121 | 9232 | const param_types = [_]*llvm.Type{anyerror_llvm_ty}; |
| 9122 | 9233 | |
| 9123 | 9234 | const fn_type = llvm.functionType(ret_llvm_ty, &param_types, param_types.len, .False); |
| ... | ... | @@ -9133,7 +9244,7 @@ pub const FuncGen = struct { |
| 9133 | 9244 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 9134 | 9245 | const operand = try self.resolveInst(un_op); |
| 9135 | 9246 | const slice_ty = self.typeOfIndex(inst); |
| 9136 | | const slice_llvm_ty = try o.lowerType(slice_ty); |
| 9247 | const slice_llvm_ty = try o.lowerLlvmType(slice_ty); |
| 9137 | 9248 | |
| 9138 | 9249 | const error_name_table_ptr = try self.getErrorNameTable(); |
| 9139 | 9250 | const ptr_slice_llvm_ty = self.context.pointerType(0); |
| ... | ... | @@ -9219,7 +9330,7 @@ pub const FuncGen = struct { |
| 9219 | 9330 | accum_init: *llvm.Value, |
| 9220 | 9331 | ) !*llvm.Value { |
| 9221 | 9332 | const o = self.dg.object; |
| 9222 | | const llvm_usize_ty = try o.lowerType(Type.usize); |
| 9333 | const llvm_usize_ty = try o.lowerLlvmType(Type.usize); |
| 9223 | 9334 | const llvm_vector_len = llvm_usize_ty.constInt(vector_len, .False); |
| 9224 | 9335 | const llvm_result_ty = accum_init.typeOf(); |
| 9225 | 9336 | |
| ... | ... | @@ -9296,7 +9407,7 @@ pub const FuncGen = struct { |
| 9296 | 9407 | .Add => switch (scalar_ty.zigTypeTag(mod)) { |
| 9297 | 9408 | .Int => return self.builder.buildAddReduce(operand), |
| 9298 | 9409 | .Float => if (intrinsicsAllowed(scalar_ty, target)) { |
| 9299 | | const scalar_llvm_ty = try o.lowerType(scalar_ty); |
| 9410 | const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty); |
| 9300 | 9411 | const neutral_value = scalar_llvm_ty.constReal(-0.0); |
| 9301 | 9412 | return self.builder.buildFPAddReduce(neutral_value, operand); |
| 9302 | 9413 | }, |
| ... | ... | @@ -9305,7 +9416,7 @@ pub const FuncGen = struct { |
| 9305 | 9416 | .Mul => switch (scalar_ty.zigTypeTag(mod)) { |
| 9306 | 9417 | .Int => return self.builder.buildMulReduce(operand), |
| 9307 | 9418 | .Float => if (intrinsicsAllowed(scalar_ty, target)) { |
| 9308 | | const scalar_llvm_ty = try o.lowerType(scalar_ty); |
| 9419 | const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty); |
| 9309 | 9420 | const neutral_value = scalar_llvm_ty.constReal(1.0); |
| 9310 | 9421 | return self.builder.buildFPMulReduce(neutral_value, operand); |
| 9311 | 9422 | }, |
| ... | ... | @@ -9333,9 +9444,9 @@ pub const FuncGen = struct { |
| 9333 | 9444 | else => unreachable, |
| 9334 | 9445 | }; |
| 9335 | 9446 | |
| 9336 | | const param_llvm_ty = try o.lowerType(scalar_ty); |
| 9447 | const param_llvm_ty = try o.lowerLlvmType(scalar_ty); |
| 9337 | 9448 | const param_types = [2]*llvm.Type{ param_llvm_ty, param_llvm_ty }; |
| 9338 | | const libc_fn = self.getLibcFunction(fn_name, &param_types, param_llvm_ty); |
| 9449 | const libc_fn = try self.getLibcFunction(fn_name, &param_types, param_llvm_ty); |
| 9339 | 9450 | const init_value = try o.lowerValue(.{ |
| 9340 | 9451 | .ty = scalar_ty, |
| 9341 | 9452 | .val = try mod.floatValue(scalar_ty, switch (reduce.operation) { |
| ... | ... | @@ -9356,7 +9467,7 @@ pub const FuncGen = struct { |
| 9356 | 9467 | const result_ty = self.typeOfIndex(inst); |
| 9357 | 9468 | const len = @as(usize, @intCast(result_ty.arrayLen(mod))); |
| 9358 | 9469 | const elements = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[ty_pl.payload..][0..len])); |
| 9359 | | const llvm_result_ty = try o.lowerType(result_ty); |
| 9470 | const llvm_result_ty = try o.lowerLlvmType(result_ty); |
| 9360 | 9471 | |
| 9361 | 9472 | switch (result_ty.zigTypeTag(mod)) { |
| 9362 | 9473 | .Vector => { |
| ... | ... | @@ -9444,7 +9555,7 @@ pub const FuncGen = struct { |
| 9444 | 9555 | .Array => { |
| 9445 | 9556 | assert(isByRef(result_ty, mod)); |
| 9446 | 9557 | |
| 9447 | | const llvm_usize = try o.lowerType(Type.usize); |
| 9558 | const llvm_usize = try o.lowerLlvmType(Type.usize); |
| 9448 | 9559 | const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod)); |
| 9449 | 9560 | |
| 9450 | 9561 | const array_info = result_ty.arrayInfo(mod); |
| ... | ... | @@ -9487,7 +9598,7 @@ pub const FuncGen = struct { |
| 9487 | 9598 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 9488 | 9599 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| 9489 | 9600 | const union_ty = self.typeOfIndex(inst); |
| 9490 | | const union_llvm_ty = try o.lowerType(union_ty); |
| 9601 | const union_llvm_ty = try o.lowerLlvmType(union_ty); |
| 9491 | 9602 | const layout = union_ty.unionGetLayout(mod); |
| 9492 | 9603 | const union_obj = mod.typeToUnion(union_ty).?; |
| 9493 | 9604 | |
| ... | ... | @@ -9529,7 +9640,7 @@ pub const FuncGen = struct { |
| 9529 | 9640 | const llvm_payload = try self.resolveInst(extra.init); |
| 9530 | 9641 | assert(union_obj.haveFieldTypes()); |
| 9531 | 9642 | const field = union_obj.fields.values()[extra.field_index]; |
| 9532 | | const field_llvm_ty = try o.lowerType(field.ty); |
| 9643 | const field_llvm_ty = try o.lowerLlvmType(field.ty); |
| 9533 | 9644 | const field_size = field.ty.abiSize(mod); |
| 9534 | 9645 | const field_align = field.normalAlignment(mod); |
| 9535 | 9646 | |
| ... | ... | @@ -9552,7 +9663,7 @@ pub const FuncGen = struct { |
| 9552 | 9663 | const fields: [1]*llvm.Type = .{payload}; |
| 9553 | 9664 | break :t self.context.structType(&fields, fields.len, .False); |
| 9554 | 9665 | } |
| 9555 | | const tag_llvm_ty = try o.lowerType(union_obj.tag_ty); |
| 9666 | const tag_llvm_ty = try o.lowerLlvmType(union_obj.tag_ty); |
| 9556 | 9667 | var fields: [3]*llvm.Type = undefined; |
| 9557 | 9668 | var fields_len: c_uint = 2; |
| 9558 | 9669 | if (layout.tag_align >= layout.payload_align) { |
| ... | ... | @@ -9605,7 +9716,7 @@ pub const FuncGen = struct { |
| 9605 | 9716 | index_type.constInt(@intFromBool(layout.tag_align < layout.payload_align), .False), |
| 9606 | 9717 | }; |
| 9607 | 9718 | const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, indices.len, ""); |
| 9608 | | const tag_llvm_ty = try o.lowerType(union_obj.tag_ty); |
| 9719 | const tag_llvm_ty = try o.lowerLlvmType(union_obj.tag_ty); |
| 9609 | 9720 | const llvm_tag = tag_llvm_ty.constInt(tag_int, .False); |
| 9610 | 9721 | const store_inst = self.builder.buildStore(llvm_tag, field_ptr); |
| 9611 | 9722 | store_inst.setAlignment(union_obj.tag_ty.abiAlignment(mod)); |
| ... | ... | @@ -9687,7 +9798,7 @@ pub const FuncGen = struct { |
| 9687 | 9798 | const inst_ty = self.typeOfIndex(inst); |
| 9688 | 9799 | const operand = try self.resolveInst(ty_op.operand); |
| 9689 | 9800 | |
| 9690 | | const llvm_dest_ty = try o.lowerType(inst_ty); |
| 9801 | const llvm_dest_ty = try o.lowerLlvmType(inst_ty); |
| 9691 | 9802 | return self.builder.buildAddrSpaceCast(operand, llvm_dest_ty, ""); |
| 9692 | 9803 | } |
| 9693 | 9804 | |
| ... | ... | @@ -9821,7 +9932,7 @@ pub const FuncGen = struct { |
| 9821 | 9932 | |
| 9822 | 9933 | return fg.loadByRef(payload_ptr, payload_ty, payload_alignment, false); |
| 9823 | 9934 | } |
| 9824 | | const payload_llvm_ty = try o.lowerType(payload_ty); |
| 9935 | const payload_llvm_ty = try o.lowerLlvmType(payload_ty); |
| 9825 | 9936 | const load_inst = fg.builder.buildLoad(payload_llvm_ty, payload_ptr, ""); |
| 9826 | 9937 | load_inst.setAlignment(payload_alignment); |
| 9827 | 9938 | return load_inst; |
| ... | ... | @@ -9838,7 +9949,7 @@ pub const FuncGen = struct { |
| 9838 | 9949 | non_null_bit: *llvm.Value, |
| 9839 | 9950 | ) !?*llvm.Value { |
| 9840 | 9951 | const o = self.dg.object; |
| 9841 | | const optional_llvm_ty = try o.lowerType(optional_ty); |
| 9952 | const optional_llvm_ty = try o.lowerLlvmType(optional_ty); |
| 9842 | 9953 | const non_null_field = self.builder.buildZExt(non_null_bit, self.context.intType(8), ""); |
| 9843 | 9954 | const mod = o.module; |
| 9844 | 9955 | |
| ... | ... | @@ -9893,7 +10004,7 @@ pub const FuncGen = struct { |
| 9893 | 10004 | const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, mod); |
| 9894 | 10005 | if (byte_offset == 0) return struct_ptr; |
| 9895 | 10006 | const byte_llvm_ty = self.context.intType(8); |
| 9896 | | const llvm_usize = try o.lowerType(Type.usize); |
| 10007 | const llvm_usize = try o.lowerLlvmType(Type.usize); |
| 9897 | 10008 | const llvm_index = llvm_usize.constInt(byte_offset, .False); |
| 9898 | 10009 | const indices: [1]*llvm.Value = .{llvm_index}; |
| 9899 | 10010 | return self.builder.buildInBoundsGEP(byte_llvm_ty, struct_ptr, &indices, indices.len, ""); |
| ... | ... | @@ -9919,7 +10030,7 @@ pub const FuncGen = struct { |
| 9919 | 10030 | const layout = struct_ty.unionGetLayout(mod); |
| 9920 | 10031 | if (layout.payload_size == 0 or struct_ty.containerLayout(mod) == .Packed) return struct_ptr; |
| 9921 | 10032 | const payload_index = @intFromBool(layout.tag_align >= layout.payload_align); |
| 9922 | | const union_llvm_ty = try o.lowerType(struct_ty); |
| 10033 | const union_llvm_ty = try o.lowerLlvmType(struct_ty); |
| 9923 | 10034 | const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_ptr, payload_index, ""); |
| 9924 | 10035 | return union_field_ptr; |
| 9925 | 10036 | }, |
| ... | ... | @@ -9944,7 +10055,7 @@ pub const FuncGen = struct { |
| 9944 | 10055 | ) !*llvm.Value { |
| 9945 | 10056 | const o = fg.dg.object; |
| 9946 | 10057 | const mod = o.module; |
| 9947 | | const pointee_llvm_ty = try o.lowerType(pointee_type); |
| 10058 | const pointee_llvm_ty = try o.lowerLlvmType(pointee_type); |
| 9948 | 10059 | const result_align = @max(ptr_alignment, pointee_type.abiAlignment(mod)); |
| 9949 | 10060 | const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align); |
| 9950 | 10061 | const llvm_usize = fg.context.intType(Type.usize.intInfo(mod).bits); |
| ... | ... | @@ -9977,7 +10088,7 @@ pub const FuncGen = struct { |
| 9977 | 10088 | assert(info.flags.vector_index != .runtime); |
| 9978 | 10089 | if (info.flags.vector_index != .none) { |
| 9979 | 10090 | const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False); |
| 9980 | | const vec_elem_ty = try o.lowerType(elem_ty); |
| 10091 | const vec_elem_ty = try o.lowerLlvmType(elem_ty); |
| 9981 | 10092 | const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size); |
| 9982 | 10093 | |
| 9983 | 10094 | const loaded_vector = self.builder.buildLoad(vec_ty, ptr, ""); |
| ... | ... | @@ -9991,7 +10102,7 @@ pub const FuncGen = struct { |
| 9991 | 10102 | if (isByRef(elem_ty, mod)) { |
| 9992 | 10103 | return self.loadByRef(ptr, elem_ty, ptr_alignment, info.flags.is_volatile); |
| 9993 | 10104 | } |
| 9994 | | const elem_llvm_ty = try o.lowerType(elem_ty); |
| 10105 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); |
| 9995 | 10106 | const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, ""); |
| 9996 | 10107 | llvm_inst.setAlignment(ptr_alignment); |
| 9997 | 10108 | llvm_inst.setVolatile(ptr_volatile); |
| ... | ... | @@ -10006,7 +10117,7 @@ pub const FuncGen = struct { |
| 10006 | 10117 | const elem_bits = @as(c_uint, @intCast(ptr_ty.childType(mod).bitSize(mod))); |
| 10007 | 10118 | const shift_amt = containing_int.typeOf().constInt(info.packed_offset.bit_offset, .False); |
| 10008 | 10119 | const shifted_value = self.builder.buildLShr(containing_int, shift_amt, ""); |
| 10009 | | const elem_llvm_ty = try o.lowerType(elem_ty); |
| 10120 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); |
| 10010 | 10121 | |
| 10011 | 10122 | if (isByRef(elem_ty, mod)) { |
| 10012 | 10123 | const result_align = elem_ty.abiAlignment(mod); |
| ... | ... | @@ -10054,7 +10165,7 @@ pub const FuncGen = struct { |
| 10054 | 10165 | assert(info.flags.vector_index != .runtime); |
| 10055 | 10166 | if (info.flags.vector_index != .none) { |
| 10056 | 10167 | const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False); |
| 10057 | | const vec_elem_ty = try o.lowerType(elem_ty); |
| 10168 | const vec_elem_ty = try o.lowerLlvmType(elem_ty); |
| 10058 | 10169 | const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size); |
| 10059 | 10170 | |
| 10060 | 10171 | const loaded_vector = self.builder.buildLoad(vec_ty, ptr, ""); |
| ... | ... | @@ -10702,7 +10813,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { |
| 10702 | 10813 | // anyerror return type instead, so that it can be coerced into a function |
| 10703 | 10814 | // pointer type which has anyerror as the return type. |
| 10704 | 10815 | if (return_type.isError(mod)) { |
| 10705 | | return o.lowerType(Type.anyerror); |
| 10816 | return o.lowerLlvmType(Type.anyerror); |
| 10706 | 10817 | } else { |
| 10707 | 10818 | return o.context.voidType(); |
| 10708 | 10819 | } |
| ... | ... | @@ -10713,19 +10824,19 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { |
| 10713 | 10824 | if (isByRef(return_type, mod)) { |
| 10714 | 10825 | return o.context.voidType(); |
| 10715 | 10826 | } else { |
| 10716 | | return o.lowerType(return_type); |
| 10827 | return o.lowerLlvmType(return_type); |
| 10717 | 10828 | } |
| 10718 | 10829 | }, |
| 10719 | 10830 | .C => { |
| 10720 | 10831 | switch (target.cpu.arch) { |
| 10721 | | .mips, .mipsel => return o.lowerType(return_type), |
| 10832 | .mips, .mipsel => return o.lowerLlvmType(return_type), |
| 10722 | 10833 | .x86_64 => switch (target.os.tag) { |
| 10723 | 10834 | .windows => return lowerWin64FnRetTy(o, fn_info), |
| 10724 | 10835 | else => return lowerSystemVFnRetTy(o, fn_info), |
| 10725 | 10836 | }, |
| 10726 | 10837 | .wasm32 => { |
| 10727 | 10838 | if (isScalar(mod, return_type)) { |
| 10728 | | return o.lowerType(return_type); |
| 10839 | return o.lowerLlvmType(return_type); |
| 10729 | 10840 | } |
| 10730 | 10841 | const classes = wasm_c_abi.classifyType(return_type, mod); |
| 10731 | 10842 | if (classes[0] == .indirect or classes[0] == .none) { |
| ... | ... | @@ -10740,8 +10851,8 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { |
| 10740 | 10851 | .aarch64, .aarch64_be => { |
| 10741 | 10852 | switch (aarch64_c_abi.classifyType(return_type, mod)) { |
| 10742 | 10853 | .memory => return o.context.voidType(), |
| 10743 | | .float_array => return o.lowerType(return_type), |
| 10744 | | .byval => return o.lowerType(return_type), |
| 10854 | .float_array => return o.lowerLlvmType(return_type), |
| 10855 | .byval => return o.lowerLlvmType(return_type), |
| 10745 | 10856 | .integer => { |
| 10746 | 10857 | const bit_size = return_type.bitSize(mod); |
| 10747 | 10858 | return o.context.intType(@as(c_uint, @intCast(bit_size))); |
| ... | ... | @@ -10757,7 +10868,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { |
| 10757 | 10868 | } else { |
| 10758 | 10869 | return o.context.voidType(); |
| 10759 | 10870 | }, |
| 10760 | | .byval => return o.lowerType(return_type), |
| 10871 | .byval => return o.lowerLlvmType(return_type), |
| 10761 | 10872 | } |
| 10762 | 10873 | }, |
| 10763 | 10874 | .riscv32, .riscv64 => { |
| ... | ... | @@ -10774,23 +10885,23 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { |
| 10774 | 10885 | }; |
| 10775 | 10886 | return o.context.structType(&llvm_types_buffer, 2, .False); |
| 10776 | 10887 | }, |
| 10777 | | .byval => return o.lowerType(return_type), |
| 10888 | .byval => return o.lowerLlvmType(return_type), |
| 10778 | 10889 | } |
| 10779 | 10890 | }, |
| 10780 | 10891 | // TODO investigate C ABI for other architectures |
| 10781 | | else => return o.lowerType(return_type), |
| 10892 | else => return o.lowerLlvmType(return_type), |
| 10782 | 10893 | } |
| 10783 | 10894 | }, |
| 10784 | 10895 | .Win64 => return lowerWin64FnRetTy(o, fn_info), |
| 10785 | 10896 | .SysV => return lowerSystemVFnRetTy(o, fn_info), |
| 10786 | 10897 | .Stdcall => { |
| 10787 | 10898 | if (isScalar(mod, return_type)) { |
| 10788 | | return o.lowerType(return_type); |
| 10899 | return o.lowerLlvmType(return_type); |
| 10789 | 10900 | } else { |
| 10790 | 10901 | return o.context.voidType(); |
| 10791 | 10902 | } |
| 10792 | 10903 | }, |
| 10793 | | else => return o.lowerType(return_type), |
| 10904 | else => return o.lowerLlvmType(return_type), |
| 10794 | 10905 | } |
| 10795 | 10906 | } |
| 10796 | 10907 | |
| ... | ... | @@ -10800,7 +10911,7 @@ fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { |
| 10800 | 10911 | switch (x86_64_abi.classifyWindows(return_type, mod)) { |
| 10801 | 10912 | .integer => { |
| 10802 | 10913 | if (isScalar(mod, return_type)) { |
| 10803 | | return o.lowerType(return_type); |
| 10914 | return o.lowerLlvmType(return_type); |
| 10804 | 10915 | } else { |
| 10805 | 10916 | const abi_size = return_type.abiSize(mod); |
| 10806 | 10917 | return o.context.intType(@as(c_uint, @intCast(abi_size * 8))); |
| ... | ... | @@ -10808,7 +10919,7 @@ fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { |
| 10808 | 10919 | }, |
| 10809 | 10920 | .win_i128 => return o.context.intType(64).vectorType(2), |
| 10810 | 10921 | .memory => return o.context.voidType(), |
| 10811 | | .sse => return o.lowerType(return_type), |
| 10922 | .sse => return o.lowerLlvmType(return_type), |
| 10812 | 10923 | else => unreachable, |
| 10813 | 10924 | } |
| 10814 | 10925 | } |
| ... | ... | @@ -10817,7 +10928,7 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type |
| 10817 | 10928 | const mod = o.module; |
| 10818 | 10929 | const return_type = fn_info.return_type.toType(); |
| 10819 | 10930 | if (isScalar(mod, return_type)) { |
| 10820 | | return o.lowerType(return_type); |
| 10931 | return o.lowerLlvmType(return_type); |
| 10821 | 10932 | } |
| 10822 | 10933 | const classes = x86_64_abi.classifySystemV(return_type, mod, .ret); |
| 10823 | 10934 | if (classes[0] == .memory) { |
| ... | ... | @@ -10847,7 +10958,7 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type |
| 10847 | 10958 | if (llvm_types_index != 0 or classes[2] != .none) { |
| 10848 | 10959 | return o.context.voidType(); |
| 10849 | 10960 | } |
| 10850 | | llvm_types_buffer[llvm_types_index] = o.context.x86FP80Type(); |
| 10961 | llvm_types_buffer[llvm_types_index] = o.context.x86_fp80Type(); |
| 10851 | 10962 | llvm_types_index += 1; |
| 10852 | 10963 | }, |
| 10853 | 10964 | .x87up => continue, |