| ... | @@ -7,6 +7,7 @@ const math = std.math; | ... | @@ -7,6 +7,7 @@ const math = std.math; |
| 7 | const native_endian = builtin.cpu.arch.endian(); | 7 | const native_endian = builtin.cpu.arch.endian(); |
| 8 | const DW = std.dwarf; | 8 | const DW = std.dwarf; |
| 9 | | 9 | |
| | 10 | const Builder = @import("llvm/Builder.zig"); |
| 10 | const llvm = @import("llvm/bindings.zig"); | 11 | const llvm = @import("llvm/bindings.zig"); |
| 11 | const link = @import("../link.zig"); | 12 | const link = @import("../link.zig"); |
| 12 | const Compilation = @import("../Compilation.zig"); | 13 | const Compilation = @import("../Compilation.zig"); |
| ... | @@ -338,6 +339,8 @@ fn deleteLlvmGlobal(llvm_global: *llvm.Value) void { | ... | @@ -338,6 +339,8 @@ fn deleteLlvmGlobal(llvm_global: *llvm.Value) void { |
| 338 | | 339 | |
| 339 | pub const Object = struct { | 340 | pub const Object = struct { |
| 340 | gpa: Allocator, | 341 | gpa: Allocator, |
| | 342 | builder: Builder, |
| | 343 | |
| 341 | module: *Module, | 344 | module: *Module, |
| 342 | llvm_module: *llvm.Module, | 345 | llvm_module: *llvm.Module, |
| 343 | di_builder: ?*llvm.DIBuilder, | 346 | di_builder: ?*llvm.DIBuilder, |
| ... | @@ -359,7 +362,7 @@ pub const Object = struct { | ... | @@ -359,7 +362,7 @@ pub const Object = struct { |
| 359 | /// version of the name and incorrectly get function not found in the llvm module. | 362 | /// version of the name and incorrectly get function not found in the llvm module. |
| 360 | /// * it works for functions not all globals. | 363 | /// * it works for functions not all globals. |
| 361 | /// Therefore, this table keeps track of the mapping. | 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 | /// Serves the same purpose as `decl_map` but only used for the `is_named_enum_value` instruction. | 366 | /// Serves the same purpose as `decl_map` but only used for the `is_named_enum_value` instruction. |
| 364 | named_enum_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *llvm.Value), | 367 | named_enum_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *llvm.Value), |
| 365 | /// Maps Zig types to LLVM types. The table memory is backed by the GPA of | 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,13 +397,19 @@ pub const Object = struct { |
| 394 | } | 397 | } |
| 395 | | 398 | |
| 396 | pub fn init(gpa: Allocator, options: link.Options) !Object { | 399 | pub fn init(gpa: Allocator, options: link.Options) !Object { |
| 397 | const context = llvm.Context.create(); | 400 | var builder = Builder{ |
| 398 | errdefer context.dispose(); | 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 | initializeLLVMTarget(options.target.cpu.arch); | 409 | initializeLLVMTarget(options.target.cpu.arch); |
| 401 | | 410 | |
| 402 | const llvm_module = llvm.Module.createWithName(options.root_name.ptr, context); | 411 | builder.llvm_module = llvm.Module.createWithName(options.root_name.ptr, builder.llvm_context); |
| 403 | errdefer llvm_module.dispose(); | 412 | errdefer builder.llvm_module.dispose(); |
| 404 | | 413 | |
| 405 | const llvm_target_triple = try targetTriple(gpa, options.target); | 414 | const llvm_target_triple = try targetTriple(gpa, options.target); |
| 406 | defer gpa.free(llvm_target_triple); | 415 | defer gpa.free(llvm_target_triple); |
| ... | @@ -414,7 +423,7 @@ pub const Object = struct { | ... | @@ -414,7 +423,7 @@ pub const Object = struct { |
| 414 | return error.InvalidLlvmTriple; | 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 | var opt_di_builder: ?*llvm.DIBuilder = null; | 427 | var opt_di_builder: ?*llvm.DIBuilder = null; |
| 419 | errdefer if (opt_di_builder) |di_builder| di_builder.dispose(); | 428 | errdefer if (opt_di_builder) |di_builder| di_builder.dispose(); |
| 420 | | 429 | |
| ... | @@ -422,10 +431,10 @@ pub const Object = struct { | ... | @@ -422,10 +431,10 @@ pub const Object = struct { |
| 422 | | 431 | |
| 423 | if (!options.strip) { | 432 | if (!options.strip) { |
| 424 | switch (options.target.ofmt) { | 433 | switch (options.target.ofmt) { |
| 425 | .coff => llvm_module.addModuleCodeViewFlag(), | 434 | .coff => builder.llvm_module.addModuleCodeViewFlag(), |
| 426 | else => llvm_module.addModuleDebugInfoFlag(options.dwarf_format == std.dwarf.Format.@"64"), | 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 | opt_di_builder = di_builder; | 438 | opt_di_builder = di_builder; |
| 430 | | 439 | |
| 431 | // Don't use the version string here; LLVM misparses it when it | 440 | // Don't use the version string here; LLVM misparses it when it |
| ... | @@ -508,24 +517,35 @@ pub const Object = struct { | ... | @@ -508,24 +517,35 @@ pub const Object = struct { |
| 508 | const target_data = target_machine.createTargetDataLayout(); | 517 | const target_data = target_machine.createTargetDataLayout(); |
| 509 | errdefer target_data.dispose(); | 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(); | 522 | if (options.pic) builder.llvm_module.setModulePICLevel(); |
| 514 | if (options.pie) llvm_module.setModulePIELevel(); | 523 | if (options.pie) builder.llvm_module.setModulePIELevel(); |
| 515 | if (code_model != .Default) llvm_module.setModuleCodeModel(code_model); | 524 | if (code_model != .Default) builder.llvm_module.setModuleCodeModel(code_model); |
| 516 | | 525 | |
| 517 | if (options.opt_bisect_limit >= 0) { | 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 | return Object{ | 540 | return Object{ |
| 522 | .gpa = gpa, | 541 | .gpa = gpa, |
| | 542 | .builder = builder, |
| 523 | .module = options.module.?, | 543 | .module = options.module.?, |
| 524 | .llvm_module = llvm_module, | 544 | .llvm_module = builder.llvm_module, |
| 525 | .di_map = .{}, | 545 | .di_map = .{}, |
| 526 | .di_builder = opt_di_builder, | 546 | .di_builder = opt_di_builder, |
| 527 | .di_compile_unit = di_compile_unit, | 547 | .di_compile_unit = di_compile_unit, |
| 528 | .context = context, | 548 | .context = builder.llvm_context, |
| 529 | .target_machine = target_machine, | 549 | .target_machine = target_machine, |
| 530 | .target_data = target_data, | 550 | .target_data = target_data, |
| 531 | .target = options.target, | 551 | .target = options.target, |
| ... | @@ -553,6 +573,7 @@ pub const Object = struct { | ... | @@ -553,6 +573,7 @@ pub const Object = struct { |
| 553 | self.named_enum_map.deinit(gpa); | 573 | self.named_enum_map.deinit(gpa); |
| 554 | self.type_map.deinit(gpa); | 574 | self.type_map.deinit(gpa); |
| 555 | self.extern_collisions.deinit(gpa); | 575 | self.extern_collisions.deinit(gpa); |
| | 576 | self.builder.deinit(); |
| 556 | self.* = undefined; | 577 | self.* = undefined; |
| 557 | } | 578 | } |
| 558 | | 579 | |
| ... | @@ -671,34 +692,36 @@ pub const Object = struct { | ... | @@ -671,34 +692,36 @@ pub const Object = struct { |
| 671 | | 692 | |
| 672 | // This map has externs with incorrect symbol names. | 693 | // This map has externs with incorrect symbol names. |
| 673 | for (object.extern_collisions.keys()) |decl_index| { | 694 | for (object.extern_collisions.keys()) |decl_index| { |
| 674 | const entry = object.decl_map.getEntry(decl_index) orelse continue; | 695 | const global = object.decl_map.get(decl_index) orelse continue; |
| 675 | const llvm_global = entry.value_ptr.*; | 696 | const llvm_global = global.toLlvm(&object.builder); |
| 676 | // Same logic as below but for externs instead of exports. | 697 | // Same logic as below but for externs instead of exports. |
| 677 | const decl = mod.declPtr(decl_index); | 698 | const decl_name = object.builder.stringIfExists(mod.intern_pool.stringToSlice(mod.declPtr(decl_index).name)) orelse continue; |
| 678 | const other_global = object.getLlvmGlobal(mod.intern_pool.stringToSlice(decl.name)) orelse continue; | 699 | const other_global = object.builder.getGlobal(decl_name) orelse continue; |
| 679 | if (other_global == llvm_global) 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 | deleteLlvmGlobal(llvm_global); | 704 | deleteLlvmGlobal(llvm_global); |
| 683 | entry.value_ptr.* = other_global; | 705 | object.builder.llvm_globals.items[@intFromEnum(global)] = other_llvm_global; |
| 684 | } | 706 | } |
| 685 | object.extern_collisions.clearRetainingCapacity(); | 707 | object.extern_collisions.clearRetainingCapacity(); |
| 686 | | 708 | |
| 687 | const export_keys = mod.decl_exports.keys(); | 709 | for (mod.decl_exports.keys(), mod.decl_exports.values()) |decl_index, export_list| { |
| 688 | for (mod.decl_exports.values(), 0..) |export_list, i| { | 710 | const global = object.decl_map.get(decl_index) orelse continue; |
| 689 | const decl_index = export_keys[i]; | 711 | const llvm_global = global.toLlvm(&object.builder); |
| 690 | const llvm_global = object.decl_map.get(decl_index) orelse continue; | | |
| 691 | for (export_list.items) |exp| { | 712 | for (export_list.items) |exp| { |
| 692 | // Detect if the LLVM global has already been created as an extern. In such | 713 | // Detect if the LLVM global has already been created as an extern. In such |
| 693 | // case, we need to replace all uses of it with this exported global. | 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; | 717 | const other_global = object.builder.getGlobal(exp_name) orelse continue; |
| 697 | if (other_global == llvm_global) 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); | 721 | other_llvm_global.replaceAllUsesWith(llvm_global); |
| 700 | llvm_global.takeName(other_global); | 722 | try global.takeName(&object.builder, other_global); |
| 701 | deleteLlvmGlobal(other_global); | 723 | deleteLlvmGlobal(other_llvm_global); |
| | 724 | object.builder.llvm_globals.items[@intFromEnum(other_global)] = llvm_global; |
| 702 | // Problem: now we need to replace in the decl_map that | 725 | // Problem: now we need to replace in the decl_map that |
| 703 | // the extern decl index points to this new global. However we don't | 726 | // the extern decl index points to this new global. However we don't |
| 704 | // know the decl index. | 727 | // know the decl index. |
| ... | @@ -813,6 +836,12 @@ pub const Object = struct { | ... | @@ -813,6 +836,12 @@ pub const Object = struct { |
| 813 | emit_asm_msg, emit_bin_msg, emit_llvm_ir_msg, emit_llvm_bc_msg, | 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 | // Unfortunately, LLVM shits the bed when we ask for both binary and assembly. | 845 | // Unfortunately, LLVM shits the bed when we ask for both binary and assembly. |
| 817 | // So we call the entire pipeline multiple times if this is requested. | 846 | // So we call the entire pipeline multiple times if this is requested. |
| 818 | var error_message: [*:0]const u8 = undefined; | 847 | var error_message: [*:0]const u8 = undefined; |
| ... | @@ -884,7 +913,9 @@ pub const Object = struct { | ... | @@ -884,7 +913,9 @@ pub const Object = struct { |
| 884 | .err_msg = null, | 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 | if (func.analysis(ip).is_noinline) { | 920 | if (func.analysis(ip).is_noinline) { |
| 890 | o.addFnAttr(llvm_func, "noinline"); | 921 | o.addFnAttr(llvm_func, "noinline"); |
| ... | @@ -932,6 +963,7 @@ pub const Object = struct { | ... | @@ -932,6 +963,7 @@ pub const Object = struct { |
| 932 | | 963 | |
| 933 | const builder = o.context.createBuilder(); | 964 | const builder = o.context.createBuilder(); |
| 934 | | 965 | |
| | 966 | function.body = {}; |
| 935 | const entry_block = o.context.appendBasicBlock(llvm_func, "Entry"); | 967 | const entry_block = o.context.appendBasicBlock(llvm_func, "Entry"); |
| 936 | builder.positionBuilderAtEnd(entry_block); | 968 | builder.positionBuilderAtEnd(entry_block); |
| 937 | | 969 | |
| ... | @@ -988,7 +1020,7 @@ pub const Object = struct { | ... | @@ -988,7 +1020,7 @@ pub const Object = struct { |
| 988 | }, | 1020 | }, |
| 989 | .byref => { | 1021 | .byref => { |
| 990 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); | 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 | const param = llvm_func.getParam(llvm_arg_i); | 1024 | const param = llvm_func.getParam(llvm_arg_i); |
| 993 | const alignment = param_ty.abiAlignment(mod); | 1025 | const alignment = param_ty.abiAlignment(mod); |
| 994 | | 1026 | |
| ... | @@ -1007,7 +1039,7 @@ pub const Object = struct { | ... | @@ -1007,7 +1039,7 @@ pub const Object = struct { |
| 1007 | }, | 1039 | }, |
| 1008 | .byref_mut => { | 1040 | .byref_mut => { |
| 1009 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); | 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 | const param = llvm_func.getParam(llvm_arg_i); | 1043 | const param = llvm_func.getParam(llvm_arg_i); |
| 1012 | const alignment = param_ty.abiAlignment(mod); | 1044 | const alignment = param_ty.abiAlignment(mod); |
| 1013 | | 1045 | |
| ... | @@ -1030,7 +1062,7 @@ pub const Object = struct { | ... | @@ -1030,7 +1062,7 @@ pub const Object = struct { |
| 1030 | const param = llvm_func.getParam(llvm_arg_i); | 1062 | const param = llvm_func.getParam(llvm_arg_i); |
| 1031 | llvm_arg_i += 1; | 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 | const abi_size = @as(c_uint, @intCast(param_ty.abiSize(mod))); | 1066 | const abi_size = @as(c_uint, @intCast(param_ty.abiSize(mod))); |
| 1035 | const int_llvm_ty = o.context.intType(abi_size * 8); | 1067 | const int_llvm_ty = o.context.intType(abi_size * 8); |
| 1036 | const alignment = @max( | 1068 | const alignment = @max( |
| ... | @@ -1075,7 +1107,7 @@ pub const Object = struct { | ... | @@ -1075,7 +1107,7 @@ pub const Object = struct { |
| 1075 | const len_param = llvm_func.getParam(llvm_arg_i); | 1107 | const len_param = llvm_func.getParam(llvm_arg_i); |
| 1076 | llvm_arg_i += 1; | 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 | const partial = builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr_param, 0, ""); | 1111 | const partial = builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr_param, 0, ""); |
| 1080 | const aggregate = builder.buildInsertValue(partial, len_param, 1, ""); | 1112 | const aggregate = builder.buildInsertValue(partial, len_param, 1, ""); |
| 1081 | try args.append(aggregate); | 1113 | try args.append(aggregate); |
| ... | @@ -1084,7 +1116,7 @@ pub const Object = struct { | ... | @@ -1084,7 +1116,7 @@ pub const Object = struct { |
| 1084 | assert(!it.byval_attr); | 1116 | assert(!it.byval_attr); |
| 1085 | const field_types = it.llvm_types_buffer[0..it.llvm_types_len]; | 1117 | const field_types = it.llvm_types_buffer[0..it.llvm_types_len]; |
| 1086 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); | 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 | const param_alignment = param_ty.abiAlignment(mod); | 1120 | const param_alignment = param_ty.abiAlignment(mod); |
| 1089 | const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, param_alignment, target); | 1121 | const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, param_alignment, target); |
| 1090 | const llvm_ty = o.context.structType(field_types.ptr, @as(c_uint, @intCast(field_types.len)), .False); | 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,7 +1147,7 @@ pub const Object = struct { |
| 1115 | }, | 1147 | }, |
| 1116 | .float_array => { | 1148 | .float_array => { |
| 1117 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); | 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 | const param = llvm_func.getParam(llvm_arg_i); | 1151 | const param = llvm_func.getParam(llvm_arg_i); |
| 1120 | llvm_arg_i += 1; | 1152 | llvm_arg_i += 1; |
| 1121 | | 1153 | |
| ... | @@ -1133,7 +1165,7 @@ pub const Object = struct { | ... | @@ -1133,7 +1165,7 @@ pub const Object = struct { |
| 1133 | }, | 1165 | }, |
| 1134 | .i32_array, .i64_array => { | 1166 | .i32_array, .i64_array => { |
| 1135 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); | 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 | const param = llvm_func.getParam(llvm_arg_i); | 1169 | const param = llvm_func.getParam(llvm_arg_i); |
| 1138 | llvm_arg_i += 1; | 1170 | llvm_arg_i += 1; |
| 1139 | | 1171 | |
| ... | @@ -1243,14 +1275,6 @@ pub const Object = struct { | ... | @@ -1243,14 +1275,6 @@ pub const Object = struct { |
| 1243 | try self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index)); | 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 | pub fn updateDeclExports( | 1278 | pub fn updateDeclExports( |
| 1255 | self: *Object, | 1279 | self: *Object, |
| 1256 | mod: *Module, | 1280 | mod: *Module, |
| ... | @@ -1260,45 +1284,49 @@ pub const Object = struct { | ... | @@ -1260,45 +1284,49 @@ pub const Object = struct { |
| 1260 | const gpa = mod.gpa; | 1284 | const gpa = mod.gpa; |
| 1261 | // If the module does not already have the function, we ignore this function call | 1285 | // If the module does not already have the function, we ignore this function call |
| 1262 | // because we call `updateDeclExports` at the end of `updateFunc` and `updateDecl`. | 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 | const decl = mod.declPtr(decl_index); | 1289 | const decl = mod.declPtr(decl_index); |
| 1265 | if (decl.isExtern(mod)) { | 1290 | if (decl.isExtern(mod)) { |
| 1266 | var free_decl_name = false; | | |
| 1267 | const decl_name = decl_name: { | 1291 | const decl_name = decl_name: { |
| 1268 | const decl_name = mod.intern_pool.stringToSlice(decl.name); | 1292 | const decl_name = mod.intern_pool.stringToSlice(decl.name); |
| 1269 | | 1293 | |
| 1270 | if (mod.getTarget().isWasm() and try decl.isFunction(mod)) { | 1294 | if (mod.getTarget().isWasm() and try decl.isFunction(mod)) { |
| 1271 | if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| { | 1295 | if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| { |
| 1272 | if (!std.mem.eql(u8, lib_name, "c")) { | 1296 | if (!std.mem.eql(u8, lib_name, "c")) { |
| 1273 | free_decl_name = true; | 1297 | break :decl_name try self.builder.fmt("{s}|{s}", .{ decl_name, lib_name }); |
| 1274 | break :decl_name try std.fmt.allocPrintZ(gpa, "{s}|{s}", .{ | | |
| 1275 | decl_name, lib_name, | | |
| 1276 | }); | | |
| 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); | 1305 | if (self.builder.getGlobal(decl_name)) |other_global| { |
| 1286 | if (self.getLlvmGlobal(decl_name)) |other_global| { | 1306 | if (other_global.toLlvm(&self.builder) != llvm_global) { |
| 1287 | if (other_global != llvm_global) { | | |
| 1288 | try self.extern_collisions.put(gpa, decl_index, {}); | 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 | llvm_global.setUnnamedAddr(.False); | 1315 | llvm_global.setUnnamedAddr(.False); |
| | 1316 | global.linkage = .external; |
| 1292 | llvm_global.setLinkage(.External); | 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 | if (self.di_map.get(decl)) |di_node| { | 1322 | if (self.di_map.get(decl)) |di_node| { |
| 1295 | if (try decl.isFunction(mod)) { | 1323 | if (try decl.isFunction(mod)) { |
| 1296 | const di_func = @as(*llvm.DISubprogram, @ptrCast(di_node)); | 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 | di_func.replaceLinkageName(linkage_name); | 1326 | di_func.replaceLinkageName(linkage_name); |
| 1299 | } else { | 1327 | } else { |
| 1300 | const di_global = @as(*llvm.DIGlobalVariable, @ptrCast(di_node)); | 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 | di_global.replaceLinkageName(linkage_name); | 1330 | di_global.replaceLinkageName(linkage_name); |
| 1303 | } | 1331 | } |
| 1304 | } | 1332 | } |
| ... | @@ -1313,18 +1341,19 @@ pub const Object = struct { | ... | @@ -1313,18 +1341,19 @@ pub const Object = struct { |
| 1313 | } | 1341 | } |
| 1314 | } | 1342 | } |
| 1315 | } else if (exports.len != 0) { | 1343 | } else if (exports.len != 0) { |
| 1316 | const exp_name = mod.intern_pool.stringToSlice(exports[0].opts.name); | 1344 | const exp_name = try self.builder.string(mod.intern_pool.stringToSlice(exports[0].opts.name)); |
| 1317 | llvm_global.setValueName2(exp_name.ptr, exp_name.len); | 1345 | try global_index.rename(&self.builder, exp_name); |
| 1318 | llvm_global.setUnnamedAddr(.False); | 1346 | llvm_global.setUnnamedAddr(.False); |
| 1319 | if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.DLLExport); | 1347 | if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.DLLExport); |
| 1320 | if (self.di_map.get(decl)) |di_node| { | 1348 | if (self.di_map.get(decl)) |di_node| { |
| | 1349 | const exp_name_slice = exp_name.toSlice(&self.builder).?; |
| 1321 | if (try decl.isFunction(mod)) { | 1350 | if (try decl.isFunction(mod)) { |
| 1322 | const di_func = @as(*llvm.DISubprogram, @ptrCast(di_node)); | 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 | di_func.replaceLinkageName(linkage_name); | 1353 | di_func.replaceLinkageName(linkage_name); |
| 1325 | } else { | 1354 | } else { |
| 1326 | const di_global = @as(*llvm.DIGlobalVariable, @ptrCast(di_node)); | 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 | di_global.replaceLinkageName(linkage_name); | 1357 | di_global.replaceLinkageName(linkage_name); |
| 1329 | } | 1358 | } |
| 1330 | } | 1359 | } |
| ... | @@ -1369,8 +1398,8 @@ pub const Object = struct { | ... | @@ -1369,8 +1398,8 @@ pub const Object = struct { |
| 1369 | } | 1398 | } |
| 1370 | } | 1399 | } |
| 1371 | } else { | 1400 | } else { |
| 1372 | const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod)); | 1401 | const fqn = try self.builder.string(mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod))); |
| 1373 | llvm_global.setValueName2(fqn.ptr, fqn.len); | 1402 | try global_index.rename(&self.builder, fqn); |
| 1374 | llvm_global.setLinkage(.Internal); | 1403 | llvm_global.setLinkage(.Internal); |
| 1375 | if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.Default); | 1404 | if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.Default); |
| 1376 | llvm_global.setUnnamedAddr(.True); | 1405 | llvm_global.setUnnamedAddr(.True); |
| ... | @@ -1386,8 +1415,8 @@ pub const Object = struct { | ... | @@ -1386,8 +1415,8 @@ pub const Object = struct { |
| 1386 | } | 1415 | } |
| 1387 | | 1416 | |
| 1388 | pub fn freeDecl(self: *Object, decl_index: Module.Decl.Index) void { | 1417 | pub fn freeDecl(self: *Object, decl_index: Module.Decl.Index) void { |
| 1389 | const llvm_value = self.decl_map.get(decl_index) orelse return; | 1418 | const global = self.decl_map.get(decl_index) orelse return; |
| 1390 | llvm_value.deleteGlobal(); | 1419 | global.toLlvm(&self.builder).deleteGlobal(); |
| 1391 | } | 1420 | } |
| 1392 | | 1421 | |
| 1393 | fn getDIFile(o: *Object, gpa: Allocator, file: *const Module.File) !*llvm.DIFile { | 1422 | fn getDIFile(o: *Object, gpa: Allocator, file: *const Module.File) !*llvm.DIFile { |
| ... | @@ -2459,27 +2488,34 @@ pub const Object = struct { | ... | @@ -2459,27 +2488,34 @@ pub const Object = struct { |
| 2459 | /// If the llvm function does not exist, create it. | 2488 | /// If the llvm function does not exist, create it. |
| 2460 | /// Note that this can be called before the function's semantic analysis has | 2489 | /// Note that this can be called before the function's semantic analysis has |
| 2461 | /// completed, so if any attributes rely on that, they must be done in updateFunc, not here. | 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 | const mod = o.module; | 2492 | const mod = o.module; |
| 2464 | const gpa = o.gpa; | 2493 | const gpa = o.gpa; |
| 2465 | const decl = mod.declPtr(decl_index); | 2494 | const decl = mod.declPtr(decl_index); |
| 2466 | const zig_fn_type = decl.ty; | 2495 | const zig_fn_type = decl.ty; |
| 2467 | const gop = try o.decl_map.getOrPut(gpa, decl_index); | 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 | assert(decl.has_tv); | 2499 | assert(decl.has_tv); |
| 2471 | const fn_info = mod.typeToFunc(zig_fn_type).?; | 2500 | const fn_info = mod.typeToFunc(zig_fn_type).?; |
| 2472 | const target = mod.getTarget(); | 2501 | const target = mod.getTarget(); |
| 2473 | const sret = firstParamSRet(fn_info, mod); | 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 | const ip = &mod.intern_pool; | 2506 | const ip = &mod.intern_pool; |
| | 2507 | const fqn = try o.builder.string(ip.stringToSlice(try decl.getFullyQualifiedName(mod))); |
| 2479 | | 2508 | |
| 2480 | const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); | 2509 | const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); |
| 2481 | const llvm_fn = o.llvm_module.addFunctionInAddressSpace(ip.stringToSlice(fqn), fn_type, llvm_addrspace); | 2510 | const llvm_fn = o.llvm_module.addFunctionInAddressSpace(fqn.toSlice(&o.builder).?, fn_type, llvm_addrspace); |
| 2482 | gop.value_ptr.* = llvm_fn; | 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 | const is_extern = decl.isExtern(mod); | 2520 | const is_extern = decl.isExtern(mod); |
| 2485 | if (!is_extern) { | 2521 | if (!is_extern) { |
| ... | @@ -2500,7 +2536,7 @@ pub const Object = struct { | ... | @@ -2500,7 +2536,7 @@ pub const Object = struct { |
| 2500 | o.addArgAttr(llvm_fn, 0, "nonnull"); // Sret pointers must not be address 0 | 2536 | o.addArgAttr(llvm_fn, 0, "nonnull"); // Sret pointers must not be address 0 |
| 2501 | o.addArgAttr(llvm_fn, 0, "noalias"); | 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 | llvm_fn.addSretAttr(raw_llvm_ret_ty); | 2540 | llvm_fn.addSretAttr(raw_llvm_ret_ty); |
| 2505 | } | 2541 | } |
| 2506 | | 2542 | |
| ... | @@ -2554,7 +2590,7 @@ pub const Object = struct { | ... | @@ -2554,7 +2590,7 @@ pub const Object = struct { |
| 2554 | }, | 2590 | }, |
| 2555 | .byref => { | 2591 | .byref => { |
| 2556 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1]; | 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 | const alignment = param_ty.toType().abiAlignment(mod); | 2594 | const alignment = param_ty.toType().abiAlignment(mod); |
| 2559 | o.addByRefParamAttrs(llvm_fn, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty); | 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,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 | fn addCommonFnAttributes(o: *Object, llvm_fn: *llvm.Value) void { | 2621 | fn addCommonFnAttributes(o: *Object, llvm_fn: *llvm.Value) void { |
| ... | @@ -2622,60 +2661,89 @@ pub const Object = struct { | ... | @@ -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 | const gop = try o.decl_map.getOrPut(o.gpa, decl_index); | 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 | errdefer assert(o.decl_map.remove(decl_index)); | 2667 | errdefer assert(o.decl_map.remove(decl_index)); |
| 2629 | | 2668 | |
| 2630 | const mod = o.module; | 2669 | const mod = o.module; |
| 2631 | const decl = mod.declPtr(decl_index); | 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 | const target = mod.getTarget(); | 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 | const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target); | 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 | const llvm_global = o.llvm_module.addGlobalInAddressSpace( | 2693 | const llvm_global = o.llvm_module.addGlobalInAddressSpace( |
| 2640 | llvm_type, | 2694 | llvm_type, |
| 2641 | mod.intern_pool.stringToSlice(fqn), | 2695 | fqn.toSlice(&o.builder).?, |
| 2642 | llvm_actual_addrspace, | 2696 | llvm_actual_addrspace, |
| 2643 | ); | 2697 | ); |
| 2644 | gop.value_ptr.* = llvm_global; | | |
| 2645 | | 2698 | |
| 2646 | // This is needed for declarations created by `@extern`. | 2699 | // This is needed for declarations created by `@extern`. |
| 2647 | if (decl.isExtern(mod)) { | 2700 | if (is_extern) { |
| 2648 | llvm_global.setValueName(mod.intern_pool.stringToSlice(decl.name)); | 2701 | global.unnamed_addr = .none; |
| 2649 | llvm_global.setUnnamedAddr(.False); | 2702 | llvm_global.setUnnamedAddr(.False); |
| | 2703 | global.linkage = .external; |
| 2650 | llvm_global.setLinkage(.External); | 2704 | llvm_global.setLinkage(.External); |
| 2651 | if (decl.val.getVariable(mod)) |variable| { | 2705 | if (decl.val.getVariable(mod)) |variable| { |
| 2652 | const single_threaded = mod.comp.bin_file.options.single_threaded; | 2706 | const single_threaded = mod.comp.bin_file.options.single_threaded; |
| 2653 | if (variable.is_threadlocal and !single_threaded) { | 2707 | if (variable.is_threadlocal and !single_threaded) { |
| | 2708 | object.thread_local = .generaldynamic; |
| 2654 | llvm_global.setThreadLocalMode(.GeneralDynamicTLSModel); | 2709 | llvm_global.setThreadLocalMode(.GeneralDynamicTLSModel); |
| 2655 | } else { | 2710 | } else { |
| | 2711 | object.thread_local = .none; |
| 2656 | llvm_global.setThreadLocalMode(.NotThreadLocal); | 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 | } else { | 2719 | } else { |
| | 2720 | global.linkage = .internal; |
| 2661 | llvm_global.setLinkage(.Internal); | 2721 | llvm_global.setLinkage(.Internal); |
| | 2722 | global.unnamed_addr = .unnamed_addr; |
| 2662 | llvm_global.setUnnamedAddr(.True); | 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 | fn isUnnamedType(o: *Object, ty: Type, val: *llvm.Value) bool { | 2732 | fn isUnnamedType(o: *Object, ty: Type, val: *llvm.Value) bool { |
| 2669 | // Once `lowerType` succeeds, successive calls to it with the same Zig type | 2733 | // Once `lowerLlvmType` 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 | 2734 | // are guaranteed to succeed. So if a call to `lowerLlvmType` fails here it means |
| 2671 | // it is the first time lowering the type, which means the value can't possible | 2735 | // it is the first time lowering the type, which means the value can't possible |
| 2672 | // have that type. | 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 | return val.typeOf() != llvm_ty; | 2738 | return val.typeOf() != llvm_ty; |
| 2675 | } | 2739 | } |
| 2676 | | 2740 | |
| 2677 | fn lowerType(o: *Object, t: Type) Allocator.Error!*llvm.Type { | 2741 | fn lowerLlvmType(o: *Object, t: Type) Allocator.Error!*llvm.Type { |
| 2678 | const llvm_ty = try lowerTypeInner(o, t); | 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 | const mod = o.module; | 2747 | const mod = o.module; |
| 2680 | if (std.debug.runtime_safety and false) check: { | 2748 | if (std.debug.runtime_safety and false) check: { |
| 2681 | if (t.zigTypeTag(mod) == .Opaque) break :check; | 2749 | if (t.zigTypeTag(mod) == .Opaque) break :check; |
| ... | @@ -2693,7 +2761,7 @@ pub const Object = struct { | ... | @@ -2693,7 +2761,7 @@ pub const Object = struct { |
| 2693 | return llvm_ty; | 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 | const gpa = o.gpa; | 2765 | const gpa = o.gpa; |
| 2698 | const mod = o.module; | 2766 | const mod = o.module; |
| 2699 | const target = mod.getTarget(); | 2767 | const target = mod.getTarget(); |
| ... | @@ -2714,7 +2782,7 @@ pub const Object = struct { | ... | @@ -2714,7 +2782,7 @@ pub const Object = struct { |
| 2714 | 16 => return if (backendSupportsF16(target)) o.context.halfType() else o.context.intType(16), | 2782 | 16 => return if (backendSupportsF16(target)) o.context.halfType() else o.context.intType(16), |
| 2715 | 32 => return o.context.floatType(), | 2783 | 32 => return o.context.floatType(), |
| 2716 | 64 => return o.context.doubleType(), | 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 | 128 => return o.context.fp128Type(), | 2786 | 128 => return o.context.fp128Type(), |
| 2719 | else => unreachable, | 2787 | else => unreachable, |
| 2720 | }, | 2788 | }, |
| ... | @@ -2724,8 +2792,8 @@ pub const Object = struct { | ... | @@ -2724,8 +2792,8 @@ pub const Object = struct { |
| 2724 | const ptr_type = t.slicePtrFieldType(mod); | 2792 | const ptr_type = t.slicePtrFieldType(mod); |
| 2725 | | 2793 | |
| 2726 | const fields: [2]*llvm.Type = .{ | 2794 | const fields: [2]*llvm.Type = .{ |
| 2727 | try o.lowerType(ptr_type), | 2795 | try o.lowerLlvmType(ptr_type), |
| 2728 | try o.lowerType(Type.usize), | 2796 | try o.lowerLlvmType(Type.usize), |
| 2729 | }; | 2797 | }; |
| 2730 | return o.context.structType(&fields, fields.len, .False); | 2798 | return o.context.structType(&fields, fields.len, .False); |
| 2731 | } | 2799 | } |
| ... | @@ -2749,12 +2817,12 @@ pub const Object = struct { | ... | @@ -2749,12 +2817,12 @@ pub const Object = struct { |
| 2749 | .Array => { | 2817 | .Array => { |
| 2750 | const elem_ty = t.childType(mod); | 2818 | const elem_ty = t.childType(mod); |
| 2751 | if (std.debug.runtime_safety) assert((try elem_ty.onePossibleValue(mod)) == null); | 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 | const total_len = t.arrayLen(mod) + @intFromBool(t.sentinel(mod) != null); | 2821 | const total_len = t.arrayLen(mod) + @intFromBool(t.sentinel(mod) != null); |
| 2754 | return elem_llvm_ty.arrayType(@as(c_uint, @intCast(total_len))); | 2822 | return elem_llvm_ty.arrayType(@as(c_uint, @intCast(total_len))); |
| 2755 | }, | 2823 | }, |
| 2756 | .Vector => { | 2824 | .Vector => { |
| 2757 | const elem_type = try o.lowerType(t.childType(mod)); | 2825 | const elem_type = try o.lowerLlvmType(t.childType(mod)); |
| 2758 | return elem_type.vectorType(t.vectorLen(mod)); | 2826 | return elem_type.vectorType(t.vectorLen(mod)); |
| 2759 | }, | 2827 | }, |
| 2760 | .Optional => { | 2828 | .Optional => { |
| ... | @@ -2762,7 +2830,7 @@ pub const Object = struct { | ... | @@ -2762,7 +2830,7 @@ pub const Object = struct { |
| 2762 | if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 2830 | if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 2763 | return o.context.intType(8); | 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 | if (t.optionalReprIsPayload(mod)) { | 2834 | if (t.optionalReprIsPayload(mod)) { |
| 2767 | return payload_llvm_ty; | 2835 | return payload_llvm_ty; |
| 2768 | } | 2836 | } |
| ... | @@ -2783,10 +2851,10 @@ pub const Object = struct { | ... | @@ -2783,10 +2851,10 @@ pub const Object = struct { |
| 2783 | .ErrorUnion => { | 2851 | .ErrorUnion => { |
| 2784 | const payload_ty = t.errorUnionPayload(mod); | 2852 | const payload_ty = t.errorUnionPayload(mod); |
| 2785 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 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); | 2856 | const llvm_error_type = try o.lowerLlvmType(Type.anyerror); |
| 2789 | const llvm_payload_type = try o.lowerType(payload_ty); | 2857 | const llvm_payload_type = try o.lowerLlvmType(payload_ty); |
| 2790 | | 2858 | |
| 2791 | const payload_align = payload_ty.abiAlignment(mod); | 2859 | const payload_align = payload_ty.abiAlignment(mod); |
| 2792 | const error_align = Type.anyerror.abiAlignment(mod); | 2860 | const error_align = Type.anyerror.abiAlignment(mod); |
| ... | @@ -2855,7 +2923,7 @@ pub const Object = struct { | ... | @@ -2855,7 +2923,7 @@ pub const Object = struct { |
| 2855 | const llvm_array_ty = o.context.intType(8).arrayType(@as(c_uint, @intCast(padding_len))); | 2923 | const llvm_array_ty = o.context.intType(8).arrayType(@as(c_uint, @intCast(padding_len))); |
| 2856 | try llvm_field_types.append(gpa, llvm_array_ty); | 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 | try llvm_field_types.append(gpa, field_llvm_ty); | 2927 | try llvm_field_types.append(gpa, field_llvm_ty); |
| 2860 | | 2928 | |
| 2861 | offset += field_ty.toType().abiSize(mod); | 2929 | offset += field_ty.toType().abiSize(mod); |
| ... | @@ -2886,14 +2954,17 @@ pub const Object = struct { | ... | @@ -2886,14 +2954,17 @@ pub const Object = struct { |
| 2886 | | 2954 | |
| 2887 | if (struct_obj.layout == .Packed) { | 2955 | if (struct_obj.layout == .Packed) { |
| 2888 | assert(struct_obj.haveLayout()); | 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 | gop.value_ptr.* = int_llvm_ty; | 2958 | gop.value_ptr.* = int_llvm_ty; |
| 2891 | return int_llvm_ty; | 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 | gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls | 2968 | gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls |
| 2898 | | 2969 | |
| 2899 | assert(struct_obj.haveFieldTypes()); | 2970 | assert(struct_obj.haveFieldTypes()); |
| ... | @@ -2924,7 +2995,7 @@ pub const Object = struct { | ... | @@ -2924,7 +2995,7 @@ pub const Object = struct { |
| 2924 | const llvm_array_ty = o.context.intType(8).arrayType(@as(c_uint, @intCast(padding_len))); | 2995 | const llvm_array_ty = o.context.intType(8).arrayType(@as(c_uint, @intCast(padding_len))); |
| 2925 | try llvm_field_types.append(gpa, llvm_array_ty); | 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 | try llvm_field_types.append(gpa, field_llvm_ty); | 2999 | try llvm_field_types.append(gpa, field_llvm_ty); |
| 2929 | | 3000 | |
| 2930 | offset += field.ty.abiSize(mod); | 3001 | offset += field.ty.abiSize(mod); |
| ... | @@ -2962,7 +3033,7 @@ pub const Object = struct { | ... | @@ -2962,7 +3033,7 @@ pub const Object = struct { |
| 2962 | } | 3033 | } |
| 2963 | | 3034 | |
| 2964 | if (layout.payload_size == 0) { | 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 | gop.value_ptr.* = enum_tag_llvm_ty; | 3037 | gop.value_ptr.* = enum_tag_llvm_ty; |
| 2967 | return enum_tag_llvm_ty; | 3038 | return enum_tag_llvm_ty; |
| 2968 | } | 3039 | } |
| ... | @@ -2973,7 +3044,7 @@ pub const Object = struct { | ... | @@ -2973,7 +3044,7 @@ pub const Object = struct { |
| 2973 | gop.value_ptr.* = llvm_union_ty; // must be done before any recursive calls | 3044 | gop.value_ptr.* = llvm_union_ty; // must be done before any recursive calls |
| 2974 | | 3045 | |
| 2975 | const aligned_field = union_obj.fields.values()[layout.most_aligned_field]; | 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 | const llvm_payload_ty = t: { | 3049 | const llvm_payload_ty = t: { |
| 2979 | if (layout.most_aligned_field_size == layout.payload_size) { | 3050 | if (layout.most_aligned_field_size == layout.payload_size) { |
| ... | @@ -2995,7 +3066,7 @@ pub const Object = struct { | ... | @@ -2995,7 +3066,7 @@ pub const Object = struct { |
| 2995 | llvm_union_ty.structSetBody(&llvm_fields, llvm_fields.len, .False); | 3066 | llvm_union_ty.structSetBody(&llvm_fields, llvm_fields.len, .False); |
| 2996 | return llvm_union_ty; | 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 | // Put the tag before or after the payload depending on which one's | 3071 | // Put the tag before or after the payload depending on which one's |
| 3001 | // alignment is greater. | 3072 | // alignment is greater. |
| ... | @@ -3017,7 +3088,7 @@ pub const Object = struct { | ... | @@ -3017,7 +3088,7 @@ pub const Object = struct { |
| 3017 | llvm_union_ty.structSetBody(&llvm_fields, llvm_fields_len, .False); | 3088 | llvm_union_ty.structSetBody(&llvm_fields, llvm_fields_len, .False); |
| 3018 | return llvm_union_ty; | 3089 | return llvm_union_ty; |
| 3019 | }, | 3090 | }, |
| 3020 | .Fn => return lowerTypeFn(o, t), | 3091 | .Fn => return lowerLlvmTypeFn(o, t), |
| 3021 | .ComptimeInt => unreachable, | 3092 | .ComptimeInt => unreachable, |
| 3022 | .ComptimeFloat => unreachable, | 3093 | .ComptimeFloat => unreachable, |
| 3023 | .Type => unreachable, | 3094 | .Type => unreachable, |
| ... | @@ -3030,7 +3101,17 @@ pub const Object = struct { | ... | @@ -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 | const mod = o.module; | 3115 | const mod = o.module; |
| 3035 | const ip = &mod.intern_pool; | 3116 | const ip = &mod.intern_pool; |
| 3036 | const fn_info = mod.typeToFunc(fn_ty).?; | 3117 | const fn_info = mod.typeToFunc(fn_ty).?; |
| ... | @@ -3047,7 +3128,7 @@ pub const Object = struct { | ... | @@ -3047,7 +3128,7 @@ pub const Object = struct { |
| 3047 | mod.comp.bin_file.options.error_return_tracing) | 3128 | mod.comp.bin_file.options.error_return_tracing) |
| 3048 | { | 3129 | { |
| 3049 | const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType()); | 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 | var it = iterateParamTypes(o, fn_info); | 3134 | var it = iterateParamTypes(o, fn_info); |
| ... | @@ -3055,7 +3136,7 @@ pub const Object = struct { | ... | @@ -3055,7 +3136,7 @@ pub const Object = struct { |
| 3055 | .no_bits => continue, | 3136 | .no_bits => continue, |
| 3056 | .byval => { | 3137 | .byval => { |
| 3057 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); | 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 | .byref, .byref_mut => { | 3141 | .byref, .byref_mut => { |
| 3061 | try llvm_params.append(o.context.pointerType(0)); | 3142 | try llvm_params.append(o.context.pointerType(0)); |
| ... | @@ -3071,8 +3152,8 @@ pub const Object = struct { | ... | @@ -3071,8 +3152,8 @@ pub const Object = struct { |
| 3071 | param_ty.optionalChild(mod).slicePtrFieldType(mod) | 3152 | param_ty.optionalChild(mod).slicePtrFieldType(mod) |
| 3072 | else | 3153 | else |
| 3073 | param_ty.slicePtrFieldType(mod); | 3154 | param_ty.slicePtrFieldType(mod); |
| 3074 | const ptr_llvm_ty = try o.lowerType(ptr_ty); | 3155 | const ptr_llvm_ty = try o.lowerLlvmType(ptr_ty); |
| 3075 | const len_llvm_ty = try o.lowerType(Type.usize); | 3156 | const len_llvm_ty = try o.lowerLlvmType(Type.usize); |
| 3076 | | 3157 | |
| 3077 | try llvm_params.ensureUnusedCapacity(2); | 3158 | try llvm_params.ensureUnusedCapacity(2); |
| 3078 | llvm_params.appendAssumeCapacity(ptr_llvm_ty); | 3159 | llvm_params.appendAssumeCapacity(ptr_llvm_ty); |
| ... | @@ -3086,7 +3167,7 @@ pub const Object = struct { | ... | @@ -3086,7 +3167,7 @@ pub const Object = struct { |
| 3086 | }, | 3167 | }, |
| 3087 | .float_array => |count| { | 3168 | .float_array => |count| { |
| 3088 | const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType(); | 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 | const field_count = @as(c_uint, @intCast(count)); | 3171 | const field_count = @as(c_uint, @intCast(count)); |
| 3091 | const arr_ty = float_ty.arrayType(field_count); | 3172 | const arr_ty = float_ty.arrayType(field_count); |
| 3092 | try llvm_params.append(arr_ty); | 3173 | try llvm_params.append(arr_ty); |
| ... | @@ -3106,7 +3187,7 @@ pub const Object = struct { | ... | @@ -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 | /// being a zero bit type, but it should still be lowered as an i8 in such case. | 3191 | /// being a zero bit type, but it should still be lowered as an i8 in such case. |
| 3111 | /// There are other similar cases handled here as well. | 3192 | /// There are other similar cases handled here as well. |
| 3112 | fn lowerPtrElemTy(o: *Object, elem_ty: Type) Allocator.Error!*llvm.Type { | 3193 | fn lowerPtrElemTy(o: *Object, elem_ty: Type) Allocator.Error!*llvm.Type { |
| ... | @@ -3118,7 +3199,7 @@ pub const Object = struct { | ... | @@ -3118,7 +3199,7 @@ pub const Object = struct { |
| 3118 | else => elem_ty.hasRuntimeBitsIgnoreComptime(mod), | 3199 | else => elem_ty.hasRuntimeBitsIgnoreComptime(mod), |
| 3119 | }; | 3200 | }; |
| 3120 | const llvm_elem_ty = if (lower_elem_ty) | 3201 | const llvm_elem_ty = if (lower_elem_ty) |
| 3121 | try o.lowerType(elem_ty) | 3202 | try o.lowerLlvmType(elem_ty) |
| 3122 | else | 3203 | else |
| 3123 | o.context.intType(8); | 3204 | o.context.intType(8); |
| 3124 | | 3205 | |
| ... | @@ -3135,7 +3216,7 @@ pub const Object = struct { | ... | @@ -3135,7 +3216,7 @@ pub const Object = struct { |
| 3135 | else => {}, | 3216 | else => {}, |
| 3136 | } | 3217 | } |
| 3137 | if (tv.val.isUndefDeep(mod)) { | 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 | return llvm_type.getUndef(); | 3220 | return llvm_type.getUndef(); |
| 3140 | } | 3221 | } |
| 3141 | | 3222 | |
| ... | @@ -3168,7 +3249,7 @@ pub const Object = struct { | ... | @@ -3168,7 +3249,7 @@ pub const Object = struct { |
| 3168 | .generic_poison, | 3249 | .generic_poison, |
| 3169 | => unreachable, // non-runtime values | 3250 | => unreachable, // non-runtime values |
| 3170 | .false, .true => { | 3251 | .false, .true => { |
| 3171 | const llvm_type = try o.lowerType(tv.ty); | 3252 | const llvm_type = try o.lowerLlvmType(tv.ty); |
| 3172 | return if (tv.val.toBool()) llvm_type.constAllOnes() else llvm_type.constNull(); | 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,13 +3261,15 @@ pub const Object = struct { |
| 3180 | const fn_decl_index = extern_func.decl; | 3261 | const fn_decl_index = extern_func.decl; |
| 3181 | const fn_decl = mod.declPtr(fn_decl_index); | 3262 | const fn_decl = mod.declPtr(fn_decl_index); |
| 3182 | try mod.markDeclAlive(fn_decl); | 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 | .func => |func| { | 3267 | .func => |func| { |
| 3186 | const fn_decl_index = func.owner_decl; | 3268 | const fn_decl_index = func.owner_decl; |
| 3187 | const fn_decl = mod.declPtr(fn_decl_index); | 3269 | const fn_decl = mod.declPtr(fn_decl_index); |
| 3188 | try mod.markDeclAlive(fn_decl); | 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 | .int => { | 3274 | .int => { |
| 3192 | var bigint_space: Value.BigIntSpace = undefined; | 3275 | var bigint_space: Value.BigIntSpace = undefined; |
| ... | @@ -3194,7 +3277,7 @@ pub const Object = struct { | ... | @@ -3194,7 +3277,7 @@ pub const Object = struct { |
| 3194 | return lowerBigInt(o, tv.ty, bigint); | 3277 | return lowerBigInt(o, tv.ty, bigint); |
| 3195 | }, | 3278 | }, |
| 3196 | .err => |err| { | 3279 | .err => |err| { |
| 3197 | const llvm_ty = try o.lowerType(Type.anyerror); | 3280 | const llvm_ty = try o.lowerLlvmType(Type.anyerror); |
| 3198 | const int = try mod.getErrorValue(err.name); | 3281 | const int = try mod.getErrorValue(err.name); |
| 3199 | return llvm_ty.constInt(int, .False); | 3282 | return llvm_ty.constInt(int, .False); |
| 3200 | }, | 3283 | }, |
| ... | @@ -3230,7 +3313,7 @@ pub const Object = struct { | ... | @@ -3230,7 +3313,7 @@ pub const Object = struct { |
| 3230 | }); | 3313 | }); |
| 3231 | var fields_buf: [3]*llvm.Value = undefined; | 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 | const llvm_field_count = llvm_ty.countStructElementTypes(); | 3317 | const llvm_field_count = llvm_ty.countStructElementTypes(); |
| 3235 | if (llvm_field_count > 2) { | 3318 | if (llvm_field_count > 2) { |
| 3236 | assert(llvm_field_count == 3); | 3319 | assert(llvm_field_count == 3); |
| ... | @@ -3274,7 +3357,7 @@ pub const Object = struct { | ... | @@ -3274,7 +3357,7 @@ pub const Object = struct { |
| 3274 | return unsigned_val; | 3357 | return unsigned_val; |
| 3275 | }, | 3358 | }, |
| 3276 | .float => { | 3359 | .float => { |
| 3277 | const llvm_ty = try o.lowerType(tv.ty); | 3360 | const llvm_ty = try o.lowerLlvmType(tv.ty); |
| 3278 | switch (tv.ty.floatBits(target)) { | 3361 | switch (tv.ty.floatBits(target)) { |
| 3279 | 16 => { | 3362 | 16 => { |
| 3280 | const repr = @as(u16, @bitCast(tv.val.toFloat(f16, mod))); | 3363 | const repr = @as(u16, @bitCast(tv.val.toFloat(f16, mod))); |
| ... | @@ -3359,7 +3442,7 @@ pub const Object = struct { | ... | @@ -3359,7 +3442,7 @@ pub const Object = struct { |
| 3359 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 3442 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 3360 | return non_null_bit; | 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 | if (tv.ty.optionalReprIsPayload(mod)) return switch (opt.val) { | 3446 | if (tv.ty.optionalReprIsPayload(mod)) return switch (opt.val) { |
| 3364 | .none => llvm_ty.constNull(), | 3447 | .none => llvm_ty.constNull(), |
| 3365 | else => |payload| o.lowerValue(.{ .ty = payload_ty, .val = payload.toValue() }), | 3448 | else => |payload| o.lowerValue(.{ .ty = payload_ty, .val = payload.toValue() }), |
| ... | @@ -3405,7 +3488,7 @@ pub const Object = struct { | ... | @@ -3405,7 +3488,7 @@ pub const Object = struct { |
| 3405 | .True, | 3488 | .True, |
| 3406 | ); | 3489 | ); |
| 3407 | } else { | 3490 | } else { |
| 3408 | const llvm_elem_ty = try o.lowerType(elem_ty); | 3491 | const llvm_elem_ty = try o.lowerLlvmType(elem_ty); |
| 3409 | return llvm_elem_ty.constArray( | 3492 | return llvm_elem_ty.constArray( |
| 3410 | llvm_elems.ptr, | 3493 | llvm_elems.ptr, |
| 3411 | @as(c_uint, @intCast(llvm_elems.len)), | 3494 | @as(c_uint, @intCast(llvm_elems.len)), |
| ... | @@ -3440,7 +3523,7 @@ pub const Object = struct { | ... | @@ -3440,7 +3523,7 @@ pub const Object = struct { |
| 3440 | .True, | 3523 | .True, |
| 3441 | ); | 3524 | ); |
| 3442 | } else { | 3525 | } else { |
| 3443 | const llvm_elem_ty = try o.lowerType(elem_ty); | 3526 | const llvm_elem_ty = try o.lowerLlvmType(elem_ty); |
| 3444 | return llvm_elem_ty.constArray( | 3527 | return llvm_elem_ty.constArray( |
| 3445 | llvm_elems.ptr, | 3528 | llvm_elems.ptr, |
| 3446 | @as(c_uint, @intCast(llvm_elems.len)), | 3529 | @as(c_uint, @intCast(llvm_elems.len)), |
| ... | @@ -3527,7 +3610,7 @@ pub const Object = struct { | ... | @@ -3527,7 +3610,7 @@ pub const Object = struct { |
| 3527 | .False, | 3610 | .False, |
| 3528 | ); | 3611 | ); |
| 3529 | } else { | 3612 | } else { |
| 3530 | const llvm_struct_ty = try o.lowerType(tv.ty); | 3613 | const llvm_struct_ty = try o.lowerLlvmType(tv.ty); |
| 3531 | return llvm_struct_ty.constNamedStruct( | 3614 | return llvm_struct_ty.constNamedStruct( |
| 3532 | llvm_fields.items.ptr, | 3615 | llvm_fields.items.ptr, |
| 3533 | @as(c_uint, @intCast(llvm_fields.items.len)), | 3616 | @as(c_uint, @intCast(llvm_fields.items.len)), |
| ... | @@ -3536,7 +3619,7 @@ pub const Object = struct { | ... | @@ -3536,7 +3619,7 @@ pub const Object = struct { |
| 3536 | }, | 3619 | }, |
| 3537 | .struct_type => |struct_type| { | 3620 | .struct_type => |struct_type| { |
| 3538 | const struct_obj = mod.structPtrUnwrap(struct_type.index).?; | 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 | if (struct_obj.layout == .Packed) { | 3624 | if (struct_obj.layout == .Packed) { |
| 3542 | assert(struct_obj.haveLayout()); | 3625 | assert(struct_obj.haveLayout()); |
| ... | @@ -3633,7 +3716,7 @@ pub const Object = struct { | ... | @@ -3633,7 +3716,7 @@ pub const Object = struct { |
| 3633 | else => unreachable, | 3716 | else => unreachable, |
| 3634 | }, | 3717 | }, |
| 3635 | .un => { | 3718 | .un => { |
| 3636 | const llvm_union_ty = try o.lowerType(tv.ty); | 3719 | const llvm_union_ty = try o.lowerLlvmType(tv.ty); |
| 3637 | const tag_and_val: Value.Payload.Union.Data = switch (tv.val.toIntern()) { | 3720 | const tag_and_val: Value.Payload.Union.Data = switch (tv.val.toIntern()) { |
| 3638 | .none => tv.val.castTag(.@"union").?.data, | 3721 | .none => tv.val.castTag(.@"union").?.data, |
| 3639 | else => switch (mod.intern_pool.indexToKey(tv.val.toIntern())) { | 3722 | else => switch (mod.intern_pool.indexToKey(tv.val.toIntern())) { |
| ... | @@ -3803,7 +3886,7 @@ pub const Object = struct { | ... | @@ -3803,7 +3886,7 @@ pub const Object = struct { |
| 3803 | llvm_u32.constInt(0, .False), | 3886 | llvm_u32.constInt(0, .False), |
| 3804 | llvm_u32.constInt(payload_offset, .False), | 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 | return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 3890 | return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 3808 | }, | 3891 | }, |
| 3809 | .opt_payload => |opt_ptr| { | 3892 | .opt_payload => |opt_ptr| { |
| ... | @@ -3824,19 +3907,19 @@ pub const Object = struct { | ... | @@ -3824,19 +3907,19 @@ pub const Object = struct { |
| 3824 | llvm_u32.constInt(0, .False), | 3907 | llvm_u32.constInt(0, .False), |
| 3825 | llvm_u32.constInt(0, .False), | 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 | return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 3911 | return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 3829 | }, | 3912 | }, |
| 3830 | .comptime_field => unreachable, | 3913 | .comptime_field => unreachable, |
| 3831 | .elem => |elem_ptr| { | 3914 | .elem => |elem_ptr| { |
| 3832 | const parent_llvm_ptr = try o.lowerParentPtr(elem_ptr.base.toValue(), true); | 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 | const indices: [1]*llvm.Value = .{ | 3918 | const indices: [1]*llvm.Value = .{ |
| 3836 | llvm_usize.constInt(elem_ptr.index, .False), | 3919 | llvm_usize.constInt(elem_ptr.index, .False), |
| 3837 | }; | 3920 | }; |
| 3838 | const elem_ty = mod.intern_pool.typeOf(elem_ptr.base).toType().elemType2(mod); | 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 | return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 3923 | return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 3841 | }, | 3924 | }, |
| 3842 | .field => |field_ptr| { | 3925 | .field => |field_ptr| { |
| ... | @@ -3865,7 +3948,7 @@ pub const Object = struct { | ... | @@ -3865,7 +3948,7 @@ pub const Object = struct { |
| 3865 | llvm_u32.constInt(0, .False), | 3948 | llvm_u32.constInt(0, .False), |
| 3866 | llvm_u32.constInt(llvm_pl_index, .False), | 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 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 3952 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 3870 | }, | 3953 | }, |
| 3871 | .Struct => { | 3954 | .Struct => { |
| ... | @@ -3888,7 +3971,7 @@ pub const Object = struct { | ... | @@ -3888,7 +3971,7 @@ pub const Object = struct { |
| 3888 | return field_addr.constIntToPtr(final_llvm_ty); | 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 | if (llvmField(parent_ty, field_index, mod)) |llvm_field| { | 3975 | if (llvmField(parent_ty, field_index, mod)) |llvm_field| { |
| 3893 | const indices: [2]*llvm.Value = .{ | 3976 | const indices: [2]*llvm.Value = .{ |
| 3894 | llvm_u32.constInt(0, .False), | 3977 | llvm_u32.constInt(0, .False), |
| ... | @@ -3907,7 +3990,7 @@ pub const Object = struct { | ... | @@ -3907,7 +3990,7 @@ pub const Object = struct { |
| 3907 | llvm_u32.constInt(0, .False), | 3990 | llvm_u32.constInt(0, .False), |
| 3908 | llvm_u32.constInt(field_index, .False), | 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 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); | 3994 | return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 3912 | }, | 3995 | }, |
| 3913 | else => unreachable, | 3996 | else => unreachable, |
| ... | @@ -3949,9 +4032,9 @@ pub const Object = struct { | ... | @@ -3949,9 +4032,9 @@ pub const Object = struct { |
| 3949 | try mod.markDeclAlive(decl); | 4032 | try mod.markDeclAlive(decl); |
| 3950 | | 4033 | |
| 3951 | const llvm_decl_val = if (is_fn_body) | 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 | else | 4036 | else |
| 3954 | try o.resolveGlobalDecl(decl_index); | 4037 | (try o.resolveGlobalDecl(decl_index)).toLlvm(&o.builder); |
| 3955 | | 4038 | |
| 3956 | const target = mod.getTarget(); | 4039 | const target = mod.getTarget(); |
| 3957 | const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); | 4040 | const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); |
| ... | @@ -3961,7 +4044,7 @@ pub const Object = struct { | ... | @@ -3961,7 +4044,7 @@ pub const Object = struct { |
| 3961 | break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty); | 4044 | break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty); |
| 3962 | } else llvm_decl_val; | 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 | if (tv.ty.zigTypeTag(mod) == .Int) { | 4048 | if (tv.ty.zigTypeTag(mod) == .Int) { |
| 3966 | return llvm_val.constPtrToInt(llvm_type); | 4049 | return llvm_val.constPtrToInt(llvm_type); |
| 3967 | } else { | 4050 | } else { |
| ... | @@ -3976,8 +4059,8 @@ pub const Object = struct { | ... | @@ -3976,8 +4059,8 @@ pub const Object = struct { |
| 3976 | // The value cannot be undefined, because we use the `nonnull` annotation | 4059 | // The value cannot be undefined, because we use the `nonnull` annotation |
| 3977 | // for non-optional pointers. We also need to respect the alignment, even though | 4060 | // for non-optional pointers. We also need to respect the alignment, even though |
| 3978 | // the address will never be dereferenced. | 4061 | // the address will never be dereferenced. |
| 3979 | const llvm_usize = try o.lowerType(Type.usize); | 4062 | const llvm_usize = try o.lowerLlvmType(Type.usize); |
| 3980 | const llvm_ptr_ty = try o.lowerType(ptr_ty); | 4063 | const llvm_ptr_ty = try o.lowerLlvmType(ptr_ty); |
| 3981 | if (ptr_ty.ptrInfo(mod).flags.alignment.toByteUnitsOptional()) |alignment| { | 4064 | if (ptr_ty.ptrInfo(mod).flags.alignment.toByteUnitsOptional()) |alignment| { |
| 3982 | return llvm_usize.constInt(alignment, .False).constIntToPtr(llvm_ptr_ty); | 4065 | return llvm_usize.constInt(alignment, .False).constIntToPtr(llvm_ptr_ty); |
| 3983 | } | 4066 | } |
| ... | @@ -4159,20 +4242,26 @@ pub const DeclGen = struct { | ... | @@ -4159,20 +4242,26 @@ pub const DeclGen = struct { |
| 4159 | _ = try o.resolveLlvmFunction(extern_func.decl); | 4242 | _ = try o.resolveLlvmFunction(extern_func.decl); |
| 4160 | } else { | 4243 | } else { |
| 4161 | const target = mod.getTarget(); | 4244 | const target = mod.getTarget(); |
| 4162 | var global = try o.resolveGlobalDecl(decl_index); | 4245 | const object_index = try o.resolveGlobalDecl(decl_index); |
| 4163 | global.setAlignment(decl.getAlignment(mod)); | 4246 | const object = object_index.ptr(&o.builder); |
| 4164 | if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| global.setSection(s); | 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 | assert(decl.has_tv); | 4252 | assert(decl.has_tv); |
| 4166 | const init_val = if (decl.val.getVariable(mod)) |variable| init_val: { | 4253 | const init_val = if (decl.val.getVariable(mod)) |variable| init_val: { |
| | 4254 | object.mutability = .global; |
| 4167 | break :init_val variable.init; | 4255 | break :init_val variable.init; |
| 4168 | } else init_val: { | 4256 | } else init_val: { |
| 4169 | global.setGlobalConstant(.True); | 4257 | object.mutability = .constant; |
| | 4258 | llvm_global.setGlobalConstant(.True); |
| 4170 | break :init_val decl.val.toIntern(); | 4259 | break :init_val decl.val.toIntern(); |
| 4171 | }; | 4260 | }; |
| 4172 | if (init_val != .none) { | 4261 | if (init_val != .none) { |
| 4173 | const llvm_init = try o.lowerValue(.{ .ty = decl.ty, .val = init_val.toValue() }); | 4262 | const llvm_init = try o.lowerValue(.{ .ty = decl.ty, .val = init_val.toValue() }); |
| 4174 | if (global.globalGetValueType() == llvm_init.typeOf()) { | 4263 | if (llvm_global.globalGetValueType() == llvm_init.typeOf()) { |
| 4175 | global.setInitializer(llvm_init); | 4264 | llvm_global.setInitializer(llvm_init); |
| 4176 | } else { | 4265 | } else { |
| 4177 | // LLVM does not allow us to change the type of globals. So we must | 4266 | // LLVM does not allow us to change the type of globals. So we must |
| 4178 | // create a new global with the correct type, copy all its attributes, | 4267 | // create a new global with the correct type, copy all its attributes, |
| ... | @@ -4193,18 +4282,18 @@ pub const DeclGen = struct { | ... | @@ -4193,18 +4282,18 @@ pub const DeclGen = struct { |
| 4193 | "", | 4282 | "", |
| 4194 | llvm_global_addrspace, | 4283 | llvm_global_addrspace, |
| 4195 | ); | 4284 | ); |
| 4196 | new_global.setLinkage(global.getLinkage()); | 4285 | new_global.setLinkage(llvm_global.getLinkage()); |
| 4197 | new_global.setUnnamedAddr(global.getUnnamedAddress()); | 4286 | new_global.setUnnamedAddr(llvm_global.getUnnamedAddress()); |
| 4198 | new_global.setAlignment(global.getAlignment()); | 4287 | new_global.setAlignment(llvm_global.getAlignment()); |
| 4199 | if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| | 4288 | if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| |
| 4200 | new_global.setSection(s); | 4289 | new_global.setSection(s); |
| 4201 | new_global.setInitializer(llvm_init); | 4290 | new_global.setInitializer(llvm_init); |
| 4202 | // TODO: How should this work then the address space of a global changed? | 4291 | // TODO: How should this work then the address space of a global changed? |
| 4203 | global.replaceAllUsesWith(new_global); | 4292 | llvm_global.replaceAllUsesWith(new_global); |
| 4204 | o.decl_map.putAssumeCapacity(decl_index, new_global); | 4293 | new_global.takeName(llvm_global); |
| 4205 | new_global.takeName(global); | 4294 | o.builder.llvm_globals.items[@intFromEnum(object.global)] = new_global; |
| 4206 | global.deleteGlobal(); | 4295 | llvm_global.deleteGlobal(); |
| 4207 | global = new_global; | 4296 | llvm_global = new_global; |
| 4208 | } | 4297 | } |
| 4209 | } | 4298 | } |
| 4210 | | 4299 | |
| ... | @@ -4216,7 +4305,7 @@ pub const DeclGen = struct { | ... | @@ -4216,7 +4305,7 @@ pub const DeclGen = struct { |
| 4216 | const di_global = dib.createGlobalVariableExpression( | 4305 | const di_global = dib.createGlobalVariableExpression( |
| 4217 | di_file.toScope(), | 4306 | di_file.toScope(), |
| 4218 | mod.intern_pool.stringToSlice(decl.name), | 4307 | mod.intern_pool.stringToSlice(decl.name), |
| 4219 | global.getValueName(), | 4308 | llvm_global.getValueName(), |
| 4220 | di_file, | 4309 | di_file, |
| 4221 | line_number, | 4310 | line_number, |
| 4222 | try o.lowerDebugType(decl.ty, .full), | 4311 | try o.lowerDebugType(decl.ty, .full), |
| ... | @@ -4224,7 +4313,7 @@ pub const DeclGen = struct { | ... | @@ -4224,7 +4313,7 @@ pub const DeclGen = struct { |
| 4224 | ); | 4313 | ); |
| 4225 | | 4314 | |
| 4226 | try o.di_map.put(o.gpa, dg.decl, di_global.getVariable().toNode()); | 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,7 +4707,7 @@ pub const FuncGen = struct { |
| 4618 | defer llvm_args.deinit(); | 4707 | defer llvm_args.deinit(); |
| 4619 | | 4708 | |
| 4620 | const ret_ptr = if (!sret) null else blk: { | 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 | const ret_ptr = self.buildAlloca(llvm_ret_ty, return_type.abiAlignment(mod)); | 4711 | const ret_ptr = self.buildAlloca(llvm_ret_ty, return_type.abiAlignment(mod)); |
| 4623 | try llvm_args.append(ret_ptr); | 4712 | try llvm_args.append(ret_ptr); |
| 4624 | break :blk ret_ptr; | 4713 | break :blk ret_ptr; |
| ... | @@ -4637,7 +4726,7 @@ pub const FuncGen = struct { | ... | @@ -4637,7 +4726,7 @@ pub const FuncGen = struct { |
| 4637 | const arg = args[it.zig_index - 1]; | 4726 | const arg = args[it.zig_index - 1]; |
| 4638 | const param_ty = self.typeOf(arg); | 4727 | const param_ty = self.typeOf(arg); |
| 4639 | const llvm_arg = try self.resolveInst(arg); | 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 | if (isByRef(param_ty, mod)) { | 4730 | if (isByRef(param_ty, mod)) { |
| 4642 | const alignment = param_ty.abiAlignment(mod); | 4731 | const alignment = param_ty.abiAlignment(mod); |
| 4643 | const load_inst = self.builder.buildLoad(llvm_param_ty, llvm_arg, ""); | 4732 | const load_inst = self.builder.buildLoad(llvm_param_ty, llvm_arg, ""); |
| ... | @@ -4668,7 +4757,7 @@ pub const FuncGen = struct { | ... | @@ -4668,7 +4757,7 @@ pub const FuncGen = struct { |
| 4668 | const llvm_arg = try self.resolveInst(arg); | 4757 | const llvm_arg = try self.resolveInst(arg); |
| 4669 | | 4758 | |
| 4670 | const alignment = param_ty.abiAlignment(mod); | 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 | const arg_ptr = self.buildAlloca(param_llvm_ty, alignment); | 4761 | const arg_ptr = self.buildAlloca(param_llvm_ty, alignment); |
| 4673 | if (isByRef(param_ty, mod)) { | 4762 | if (isByRef(param_ty, mod)) { |
| 4674 | const load_inst = self.builder.buildLoad(param_llvm_ty, llvm_arg, ""); | 4763 | const load_inst = self.builder.buildLoad(param_llvm_ty, llvm_arg, ""); |
| ... | @@ -4759,7 +4848,7 @@ pub const FuncGen = struct { | ... | @@ -4759,7 +4848,7 @@ pub const FuncGen = struct { |
| 4759 | llvm_arg = store_inst; | 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 | const array_llvm_ty = float_ty.arrayType(count); | 4852 | const array_llvm_ty = float_ty.arrayType(count); |
| 4764 | | 4853 | |
| 4765 | const alignment = arg_ty.abiAlignment(mod); | 4854 | const alignment = arg_ty.abiAlignment(mod); |
| ... | @@ -4788,7 +4877,7 @@ pub const FuncGen = struct { | ... | @@ -4788,7 +4877,7 @@ pub const FuncGen = struct { |
| 4788 | }; | 4877 | }; |
| 4789 | | 4878 | |
| 4790 | const call = self.builder.buildCall( | 4879 | const call = self.builder.buildCall( |
| 4791 | try o.lowerType(zig_fn_ty), | 4880 | try o.lowerLlvmType(zig_fn_ty), |
| 4792 | llvm_fn, | 4881 | llvm_fn, |
| 4793 | llvm_args.items.ptr, | 4882 | llvm_args.items.ptr, |
| 4794 | @as(c_uint, @intCast(llvm_args.items.len)), | 4883 | @as(c_uint, @intCast(llvm_args.items.len)), |
| ... | @@ -4813,7 +4902,7 @@ pub const FuncGen = struct { | ... | @@ -4813,7 +4902,7 @@ pub const FuncGen = struct { |
| 4813 | .byref => { | 4902 | .byref => { |
| 4814 | const param_index = it.zig_index - 1; | 4903 | const param_index = it.zig_index - 1; |
| 4815 | const param_ty = fn_info.param_types.get(ip)[param_index].toType(); | 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 | const alignment = param_ty.abiAlignment(mod); | 4906 | const alignment = param_ty.abiAlignment(mod); |
| 4818 | o.addByRefParamAttrs(call, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty); | 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,7 +4951,7 @@ pub const FuncGen = struct { |
| 4862 | return null; | 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 | if (ret_ptr) |rp| { | 4956 | if (ret_ptr) |rp| { |
| 4868 | call.setCallSret(llvm_ret_ty); | 4957 | call.setCallSret(llvm_ret_ty); |
| ... | @@ -4939,8 +5028,8 @@ pub const FuncGen = struct { | ... | @@ -4939,8 +5028,8 @@ pub const FuncGen = struct { |
| 4939 | const fn_info = mod.typeToFunc(panic_decl.ty).?; | 5028 | const fn_info = mod.typeToFunc(panic_decl.ty).?; |
| 4940 | const panic_global = try o.resolveLlvmFunction(panic_func.owner_decl); | 5029 | const panic_global = try o.resolveLlvmFunction(panic_func.owner_decl); |
| 4941 | _ = fg.builder.buildCall( | 5030 | _ = fg.builder.buildCall( |
| 4942 | try o.lowerType(panic_decl.ty), | 5031 | try o.lowerLlvmType(panic_decl.ty), |
| 4943 | panic_global, | 5032 | panic_global.toLlvm(&o.builder), |
| 4944 | &args, | 5033 | &args, |
| 4945 | args.len, | 5034 | args.len, |
| 4946 | toLlvmCallConv(fn_info.cc, target), | 5035 | toLlvmCallConv(fn_info.cc, target), |
| ... | @@ -4968,7 +5057,7 @@ pub const FuncGen = struct { | ... | @@ -4968,7 +5057,7 @@ pub const FuncGen = struct { |
| 4968 | // Functions with an empty error set are emitted with an error code | 5057 | // Functions with an empty error set are emitted with an error code |
| 4969 | // return type and return zero so they can be function pointers coerced | 5058 | // return type and return zero so they can be function pointers coerced |
| 4970 | // to functions that return anyerror. | 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 | _ = self.builder.buildRet(err_int.constInt(0, .False)); | 5061 | _ = self.builder.buildRet(err_int.constInt(0, .False)); |
| 4973 | } else { | 5062 | } else { |
| 4974 | _ = self.builder.buildRetVoid(); | 5063 | _ = self.builder.buildRetVoid(); |
| ... | @@ -5016,7 +5105,7 @@ pub const FuncGen = struct { | ... | @@ -5016,7 +5105,7 @@ pub const FuncGen = struct { |
| 5016 | // Functions with an empty error set are emitted with an error code | 5105 | // Functions with an empty error set are emitted with an error code |
| 5017 | // return type and return zero so they can be function pointers coerced | 5106 | // return type and return zero so they can be function pointers coerced |
| 5018 | // to functions that return anyerror. | 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 | _ = self.builder.buildRet(err_int.constInt(0, .False)); | 5109 | _ = self.builder.buildRet(err_int.constInt(0, .False)); |
| 5021 | } else { | 5110 | } else { |
| 5022 | _ = self.builder.buildRetVoid(); | 5111 | _ = self.builder.buildRetVoid(); |
| ... | @@ -5040,7 +5129,7 @@ pub const FuncGen = struct { | ... | @@ -5040,7 +5129,7 @@ pub const FuncGen = struct { |
| 5040 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 5129 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 5041 | const list = try self.resolveInst(ty_op.operand); | 5130 | const list = try self.resolveInst(ty_op.operand); |
| 5042 | const arg_ty = self.air.getRefType(ty_op.ty); | 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 | return self.builder.buildVAArg(list, llvm_arg_ty, ""); | 5134 | return self.builder.buildVAArg(list, llvm_arg_ty, ""); |
| 5046 | } | 5135 | } |
| ... | @@ -5050,7 +5139,7 @@ pub const FuncGen = struct { | ... | @@ -5050,7 +5139,7 @@ pub const FuncGen = struct { |
| 5050 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 5139 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 5051 | const src_list = try self.resolveInst(ty_op.operand); | 5140 | const src_list = try self.resolveInst(ty_op.operand); |
| 5052 | const va_list_ty = self.air.getRefType(ty_op.ty); | 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 | const mod = o.module; | 5143 | const mod = o.module; |
| 5055 | | 5144 | |
| 5056 | const result_alignment = va_list_ty.abiAlignment(mod); | 5145 | const result_alignment = va_list_ty.abiAlignment(mod); |
| ... | @@ -5098,7 +5187,7 @@ pub const FuncGen = struct { | ... | @@ -5098,7 +5187,7 @@ pub const FuncGen = struct { |
| 5098 | const o = self.dg.object; | 5187 | const o = self.dg.object; |
| 5099 | const mod = o.module; | 5188 | const mod = o.module; |
| 5100 | const va_list_ty = self.typeOfIndex(inst); | 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 | const result_alignment = va_list_ty.abiAlignment(mod); | 5192 | const result_alignment = va_list_ty.abiAlignment(mod); |
| 5104 | const list = self.buildAlloca(llvm_va_list_ty, result_alignment); | 5193 | const list = self.buildAlloca(llvm_va_list_ty, result_alignment); |
| ... | @@ -5177,7 +5266,7 @@ pub const FuncGen = struct { | ... | @@ -5177,7 +5266,7 @@ pub const FuncGen = struct { |
| 5177 | // We need to emit instructions to check for equality/inequality | 5266 | // We need to emit instructions to check for equality/inequality |
| 5178 | // of optionals that are not pointers. | 5267 | // of optionals that are not pointers. |
| 5179 | const is_by_ref = isByRef(scalar_ty, mod); | 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 | const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref); | 5270 | const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref); |
| 5182 | const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref); | 5271 | const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref); |
| 5183 | const llvm_i2 = self.context.intType(2); | 5272 | const llvm_i2 = self.context.intType(2); |
| ... | @@ -5287,7 +5376,7 @@ pub const FuncGen = struct { | ... | @@ -5287,7 +5376,7 @@ pub const FuncGen = struct { |
| 5287 | const is_body = inst_ty.zigTypeTag(mod) == .Fn; | 5376 | const is_body = inst_ty.zigTypeTag(mod) == .Fn; |
| 5288 | if (!is_body and !inst_ty.hasRuntimeBitsIgnoreComptime(mod)) return null; | 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 | const llvm_ty = ty: { | 5381 | const llvm_ty = ty: { |
| 5293 | // If the zig tag type is a function, this represents an actual function body; not | 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,11 +5481,11 @@ pub const FuncGen = struct { |
| 5392 | const mod = o.module; | 5481 | const mod = o.module; |
| 5393 | const payload_ty = err_union_ty.errorUnionPayload(mod); | 5482 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| 5394 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod); | 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 | if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { | 5486 | if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { |
| 5398 | const is_err = err: { | 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 | const zero = err_set_ty.constNull(); | 5489 | const zero = err_set_ty.constNull(); |
| 5401 | if (!payload_has_bits) { | 5490 | if (!payload_has_bits) { |
| 5402 | // TODO add alignment to this load | 5491 | // TODO add alignment to this load |
| ... | @@ -5531,9 +5620,9 @@ pub const FuncGen = struct { | ... | @@ -5531,9 +5620,9 @@ pub const FuncGen = struct { |
| 5531 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 5620 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 5532 | const operand_ty = self.typeOf(ty_op.operand); | 5621 | const operand_ty = self.typeOf(ty_op.operand); |
| 5533 | const array_ty = operand_ty.childType(mod); | 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 | const len = llvm_usize.constInt(array_ty.arrayLen(mod), .False); | 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 | const operand = try self.resolveInst(ty_op.operand); | 5626 | const operand = try self.resolveInst(ty_op.operand); |
| 5538 | if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 5627 | if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 5539 | const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), operand, 0, ""); | 5628 | const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), operand, 0, ""); |
| ... | @@ -5542,7 +5631,7 @@ pub const FuncGen = struct { | ... | @@ -5542,7 +5631,7 @@ pub const FuncGen = struct { |
| 5542 | const indices: [2]*llvm.Value = .{ | 5631 | const indices: [2]*llvm.Value = .{ |
| 5543 | llvm_usize.constNull(), llvm_usize.constNull(), | 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 | const ptr = self.builder.buildInBoundsGEP(array_llvm_ty, operand, &indices, indices.len, ""); | 5635 | const ptr = self.builder.buildInBoundsGEP(array_llvm_ty, operand, &indices, indices.len, ""); |
| 5547 | const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, ""); | 5636 | const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, ""); |
| 5548 | return self.builder.buildInsertValue(partial, len, 1, ""); | 5637 | return self.builder.buildInsertValue(partial, len, 1, ""); |
| ... | @@ -5559,7 +5648,7 @@ pub const FuncGen = struct { | ... | @@ -5559,7 +5648,7 @@ pub const FuncGen = struct { |
| 5559 | | 5648 | |
| 5560 | const dest_ty = self.typeOfIndex(inst); | 5649 | const dest_ty = self.typeOfIndex(inst); |
| 5561 | const dest_scalar_ty = dest_ty.scalarType(mod); | 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 | const target = mod.getTarget(); | 5652 | const target = mod.getTarget(); |
| 5564 | | 5653 | |
| 5565 | if (intrinsicsAllowed(dest_scalar_ty, target)) { | 5654 | if (intrinsicsAllowed(dest_scalar_ty, target)) { |
| ... | @@ -5600,7 +5689,7 @@ pub const FuncGen = struct { | ... | @@ -5600,7 +5689,7 @@ pub const FuncGen = struct { |
| 5600 | param_types = [1]*llvm.Type{v2i64}; | 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 | const params = [1]*llvm.Value{extended}; | 5693 | const params = [1]*llvm.Value{extended}; |
| 5605 | | 5694 | |
| 5606 | return self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, ""); | 5695 | return self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, ""); |
| ... | @@ -5620,7 +5709,7 @@ pub const FuncGen = struct { | ... | @@ -5620,7 +5709,7 @@ pub const FuncGen = struct { |
| 5620 | | 5709 | |
| 5621 | const dest_ty = self.typeOfIndex(inst); | 5710 | const dest_ty = self.typeOfIndex(inst); |
| 5622 | const dest_scalar_ty = dest_ty.scalarType(mod); | 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 | if (intrinsicsAllowed(operand_scalar_ty, target)) { | 5714 | if (intrinsicsAllowed(operand_scalar_ty, target)) { |
| 5626 | // TODO set fast math flag | 5715 | // TODO set fast math flag |
| ... | @@ -5652,9 +5741,9 @@ pub const FuncGen = struct { | ... | @@ -5652,9 +5741,9 @@ pub const FuncGen = struct { |
| 5652 | compiler_rt_dest_abbrev, | 5741 | compiler_rt_dest_abbrev, |
| 5653 | }) catch unreachable; | 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 | const param_types = [1]*llvm.Type{operand_llvm_ty}; | 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 | const params = [1]*llvm.Value{operand}; | 5747 | const params = [1]*llvm.Value{operand}; |
| 5659 | | 5748 | |
| 5660 | var result = self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, ""); | 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,7 +5851,7 @@ pub const FuncGen = struct { |
| 5762 | const array_ty = self.typeOf(bin_op.lhs); | 5851 | const array_ty = self.typeOf(bin_op.lhs); |
| 5763 | const array_llvm_val = try self.resolveInst(bin_op.lhs); | 5852 | const array_llvm_val = try self.resolveInst(bin_op.lhs); |
| 5764 | const rhs = try self.resolveInst(bin_op.rhs); | 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 | const elem_ty = array_ty.childType(mod); | 5855 | const elem_ty = array_ty.childType(mod); |
| 5767 | if (isByRef(array_ty, mod)) { | 5856 | if (isByRef(array_ty, mod)) { |
| 5768 | const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs }; | 5857 | const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs }; |
| ... | @@ -5773,7 +5862,7 @@ pub const FuncGen = struct { | ... | @@ -5773,7 +5862,7 @@ pub const FuncGen = struct { |
| 5773 | | 5862 | |
| 5774 | return self.loadByRef(elem_ptr, elem_ty, elem_ty.abiAlignment(mod), false); | 5863 | return self.loadByRef(elem_ptr, elem_ty, elem_ty.abiAlignment(mod), false); |
| 5775 | } else { | 5864 | } else { |
| 5776 | const elem_llvm_ty = try o.lowerType(elem_ty); | 5865 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); |
| 5777 | if (Air.refToIndex(bin_op.lhs)) |lhs_index| { | 5866 | if (Air.refToIndex(bin_op.lhs)) |lhs_index| { |
| 5778 | if (self.air.instructions.items(.tag)[lhs_index] == .load) { | 5867 | if (self.air.instructions.items(.tag)[lhs_index] == .load) { |
| 5779 | const load_data = self.air.instructions.items(.data)[lhs_index]; | 5868 | const load_data = self.air.instructions.items(.data)[lhs_index]; |
| ... | @@ -5898,7 +5987,7 @@ pub const FuncGen = struct { | ... | @@ -5898,7 +5987,7 @@ pub const FuncGen = struct { |
| 5898 | const containing_int = struct_llvm_val; | 5987 | const containing_int = struct_llvm_val; |
| 5899 | const shift_amt = containing_int.typeOf().constInt(bit_offset, .False); | 5988 | const shift_amt = containing_int.typeOf().constInt(bit_offset, .False); |
| 5900 | const shifted_value = self.builder.buildLShr(containing_int, shift_amt, ""); | 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 | if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) { | 5991 | if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) { |
| 5903 | const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod))); | 5992 | const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod))); |
| 5904 | const same_size_int = self.context.intType(elem_bits); | 5993 | const same_size_int = self.context.intType(elem_bits); |
| ... | @@ -5920,7 +6009,7 @@ pub const FuncGen = struct { | ... | @@ -5920,7 +6009,7 @@ pub const FuncGen = struct { |
| 5920 | .Union => { | 6009 | .Union => { |
| 5921 | assert(struct_ty.containerLayout(mod) == .Packed); | 6010 | assert(struct_ty.containerLayout(mod) == .Packed); |
| 5922 | const containing_int = struct_llvm_val; | 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 | if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) { | 6013 | if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) { |
| 5925 | const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod))); | 6014 | const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod))); |
| 5926 | const same_size_int = self.context.intType(elem_bits); | 6015 | const same_size_int = self.context.intType(elem_bits); |
| ... | @@ -5942,7 +6031,7 @@ pub const FuncGen = struct { | ... | @@ -5942,7 +6031,7 @@ pub const FuncGen = struct { |
| 5942 | .Struct => { | 6031 | .Struct => { |
| 5943 | assert(struct_ty.containerLayout(mod) != .Packed); | 6032 | assert(struct_ty.containerLayout(mod) != .Packed); |
| 5944 | const llvm_field = llvmField(struct_ty, field_index, mod).?; | 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 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field.index, ""); | 6035 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field.index, ""); |
| 5947 | const field_ptr_ty = try mod.ptrType(.{ | 6036 | const field_ptr_ty = try mod.ptrType(.{ |
| 5948 | .child = llvm_field.ty.toIntern(), | 6037 | .child = llvm_field.ty.toIntern(), |
| ... | @@ -5961,11 +6050,11 @@ pub const FuncGen = struct { | ... | @@ -5961,11 +6050,11 @@ pub const FuncGen = struct { |
| 5961 | } | 6050 | } |
| 5962 | }, | 6051 | }, |
| 5963 | .Union => { | 6052 | .Union => { |
| 5964 | const union_llvm_ty = try o.lowerType(struct_ty); | 6053 | const union_llvm_ty = try o.lowerLlvmType(struct_ty); |
| 5965 | const layout = struct_ty.unionGetLayout(mod); | 6054 | const layout = struct_ty.unionGetLayout(mod); |
| 5966 | const payload_index = @intFromBool(layout.tag_align >= layout.payload_align); | 6055 | const payload_index = @intFromBool(layout.tag_align >= layout.payload_align); |
| 5967 | const field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, ""); | 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 | if (isByRef(field_ty, mod)) { | 6058 | if (isByRef(field_ty, mod)) { |
| 5970 | if (canElideLoad(self, body_tail)) | 6059 | if (canElideLoad(self, body_tail)) |
| 5971 | return field_ptr; | 6060 | return field_ptr; |
| ... | @@ -5991,7 +6080,7 @@ pub const FuncGen = struct { | ... | @@ -5991,7 +6080,7 @@ pub const FuncGen = struct { |
| 5991 | const parent_ty = self.air.getRefType(ty_pl.ty).childType(mod); | 6080 | const parent_ty = self.air.getRefType(ty_pl.ty).childType(mod); |
| 5992 | const field_offset = parent_ty.structFieldOffset(extra.field_index, mod); | 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 | if (field_offset == 0) { | 6084 | if (field_offset == 0) { |
| 5996 | return field_ptr; | 6085 | return field_ptr; |
| 5997 | } | 6086 | } |
| ... | @@ -6273,7 +6362,7 @@ pub const FuncGen = struct { | ... | @@ -6273,7 +6362,7 @@ pub const FuncGen = struct { |
| 6273 | } | 6362 | } |
| 6274 | } else { | 6363 | } else { |
| 6275 | const ret_ty = self.typeOfIndex(inst); | 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 | llvm_ret_i += 1; | 6366 | llvm_ret_i += 1; |
| 6278 | } | 6367 | } |
| 6279 | | 6368 | |
| ... | @@ -6316,7 +6405,7 @@ pub const FuncGen = struct { | ... | @@ -6316,7 +6405,7 @@ pub const FuncGen = struct { |
| 6316 | llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf(); | 6405 | llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf(); |
| 6317 | } else { | 6406 | } else { |
| 6318 | const alignment = arg_ty.abiAlignment(mod); | 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 | const load_inst = self.builder.buildLoad(arg_llvm_ty, arg_llvm_value, ""); | 6409 | const load_inst = self.builder.buildLoad(arg_llvm_ty, arg_llvm_value, ""); |
| 6321 | load_inst.setAlignment(alignment); | 6410 | load_inst.setAlignment(alignment); |
| 6322 | llvm_param_values[llvm_param_i] = load_inst; | 6411 | llvm_param_values[llvm_param_i] = load_inst; |
| ... | @@ -6554,7 +6643,7 @@ pub const FuncGen = struct { | ... | @@ -6554,7 +6643,7 @@ pub const FuncGen = struct { |
| 6554 | const operand = try self.resolveInst(un_op); | 6643 | const operand = try self.resolveInst(un_op); |
| 6555 | const operand_ty = self.typeOf(un_op); | 6644 | const operand_ty = self.typeOf(un_op); |
| 6556 | const optional_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; | 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 | const payload_ty = optional_ty.optionalChild(mod); | 6647 | const payload_ty = optional_ty.optionalChild(mod); |
| 6559 | if (optional_ty.optionalReprIsPayload(mod)) { | 6648 | if (optional_ty.optionalReprIsPayload(mod)) { |
| 6560 | const loaded = if (operand_is_ptr) | 6649 | const loaded = if (operand_is_ptr) |
| ... | @@ -6563,7 +6652,7 @@ pub const FuncGen = struct { | ... | @@ -6563,7 +6652,7 @@ pub const FuncGen = struct { |
| 6563 | operand; | 6652 | operand; |
| 6564 | if (payload_ty.isSlice(mod)) { | 6653 | if (payload_ty.isSlice(mod)) { |
| 6565 | const slice_ptr = self.builder.buildExtractValue(loaded, 0, ""); | 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 | return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), ""); | 6656 | return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), ""); |
| 6568 | } | 6657 | } |
| 6569 | return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), ""); | 6658 | return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), ""); |
| ... | @@ -6602,7 +6691,7 @@ pub const FuncGen = struct { | ... | @@ -6602,7 +6691,7 @@ pub const FuncGen = struct { |
| 6602 | const operand_ty = self.typeOf(un_op); | 6691 | const operand_ty = self.typeOf(un_op); |
| 6603 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; | 6692 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; |
| 6604 | const payload_ty = err_union_ty.errorUnionPayload(mod); | 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 | const zero = err_set_ty.constNull(); | 6695 | const zero = err_set_ty.constNull(); |
| 6607 | | 6696 | |
| 6608 | if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { | 6697 | if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { |
| ... | @@ -6616,7 +6705,7 @@ pub const FuncGen = struct { | ... | @@ -6616,7 +6705,7 @@ pub const FuncGen = struct { |
| 6616 | | 6705 | |
| 6617 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 6706 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 6618 | const loaded = if (operand_is_ptr) | 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 | else | 6709 | else |
| 6621 | operand; | 6710 | operand; |
| 6622 | return self.builder.buildICmp(op, loaded, zero, ""); | 6711 | return self.builder.buildICmp(op, loaded, zero, ""); |
| ... | @@ -6625,7 +6714,7 @@ pub const FuncGen = struct { | ... | @@ -6625,7 +6714,7 @@ pub const FuncGen = struct { |
| 6625 | const err_field_index = errUnionErrorOffset(payload_ty, mod); | 6714 | const err_field_index = errUnionErrorOffset(payload_ty, mod); |
| 6626 | | 6715 | |
| 6627 | if (operand_is_ptr or isByRef(err_union_ty, mod)) { | 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 | const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, err_field_index, ""); | 6718 | const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, err_field_index, ""); |
| 6630 | const loaded = self.builder.buildLoad(err_set_ty, err_field_ptr, ""); | 6719 | const loaded = self.builder.buildLoad(err_set_ty, err_field_ptr, ""); |
| 6631 | return self.builder.buildICmp(op, loaded, zero, ""); | 6720 | return self.builder.buildICmp(op, loaded, zero, ""); |
| ... | @@ -6651,7 +6740,7 @@ pub const FuncGen = struct { | ... | @@ -6651,7 +6740,7 @@ pub const FuncGen = struct { |
| 6651 | // The payload and the optional are the same value. | 6740 | // The payload and the optional are the same value. |
| 6652 | return operand; | 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 | return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, ""); | 6744 | return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, ""); |
| 6656 | } | 6745 | } |
| 6657 | | 6746 | |
| ... | @@ -6677,7 +6766,7 @@ pub const FuncGen = struct { | ... | @@ -6677,7 +6766,7 @@ pub const FuncGen = struct { |
| 6677 | } | 6766 | } |
| 6678 | | 6767 | |
| 6679 | // First set the non-null bit. | 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 | const non_null_ptr = self.builder.buildStructGEP(optional_llvm_ty, operand, 1, ""); | 6770 | const non_null_ptr = self.builder.buildStructGEP(optional_llvm_ty, operand, 1, ""); |
| 6682 | // TODO set alignment on this store | 6771 | // TODO set alignment on this store |
| 6683 | _ = self.builder.buildStore(non_null_bit, non_null_ptr); | 6772 | _ = self.builder.buildStore(non_null_bit, non_null_ptr); |
| ... | @@ -6704,7 +6793,7 @@ pub const FuncGen = struct { | ... | @@ -6704,7 +6793,7 @@ pub const FuncGen = struct { |
| 6704 | return operand; | 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 | const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false; | 6797 | const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false; |
| 6709 | return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load); | 6798 | return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load); |
| 6710 | } | 6799 | } |
| ... | @@ -6728,7 +6817,7 @@ pub const FuncGen = struct { | ... | @@ -6728,7 +6817,7 @@ pub const FuncGen = struct { |
| 6728 | return if (operand_is_ptr) operand else null; | 6817 | return if (operand_is_ptr) operand else null; |
| 6729 | } | 6818 | } |
| 6730 | const offset = errUnionPayloadOffset(payload_ty, mod); | 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 | if (operand_is_ptr) { | 6821 | if (operand_is_ptr) { |
| 6733 | return self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, ""); | 6822 | return self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, ""); |
| 6734 | } else if (isByRef(err_union_ty, mod)) { | 6823 | } else if (isByRef(err_union_ty, mod)) { |
| ... | @@ -6758,7 +6847,7 @@ pub const FuncGen = struct { | ... | @@ -6758,7 +6847,7 @@ pub const FuncGen = struct { |
| 6758 | const operand_ty = self.typeOf(ty_op.operand); | 6847 | const operand_ty = self.typeOf(ty_op.operand); |
| 6759 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; | 6848 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; |
| 6760 | if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { | 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 | if (operand_is_ptr) { | 6851 | if (operand_is_ptr) { |
| 6763 | return operand; | 6852 | return operand; |
| 6764 | } else { | 6853 | } else { |
| ... | @@ -6766,7 +6855,7 @@ pub const FuncGen = struct { | ... | @@ -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 | const payload_ty = err_union_ty.errorUnionPayload(mod); | 6860 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| 6772 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 6861 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| ... | @@ -6777,7 +6866,7 @@ pub const FuncGen = struct { | ... | @@ -6777,7 +6866,7 @@ pub const FuncGen = struct { |
| 6777 | const offset = errUnionErrorOffset(payload_ty, mod); | 6866 | const offset = errUnionErrorOffset(payload_ty, mod); |
| 6778 | | 6867 | |
| 6779 | if (operand_is_ptr or isByRef(err_union_ty, mod)) { | 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 | const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, ""); | 6870 | const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, ""); |
| 6782 | return self.builder.buildLoad(err_set_llvm_ty, err_field_ptr, ""); | 6871 | return self.builder.buildLoad(err_set_llvm_ty, err_field_ptr, ""); |
| 6783 | } | 6872 | } |
| ... | @@ -6798,7 +6887,7 @@ pub const FuncGen = struct { | ... | @@ -6798,7 +6887,7 @@ pub const FuncGen = struct { |
| 6798 | _ = self.builder.buildStore(non_error_val, operand); | 6887 | _ = self.builder.buildStore(non_error_val, operand); |
| 6799 | return operand; | 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 | const error_offset = errUnionErrorOffset(payload_ty, mod); | 6892 | const error_offset = errUnionErrorOffset(payload_ty, mod); |
| 6804 | // First set the non-error value. | 6893 | // First set the non-error value. |
| ... | @@ -6834,7 +6923,7 @@ pub const FuncGen = struct { | ... | @@ -6834,7 +6923,7 @@ pub const FuncGen = struct { |
| 6834 | | 6923 | |
| 6835 | const mod = o.module; | 6924 | const mod = o.module; |
| 6836 | const llvm_field = llvmField(struct_ty, field_index, mod).?; | 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 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field.index, ""); | 6927 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field.index, ""); |
| 6839 | const field_ptr_ty = try mod.ptrType(.{ | 6928 | const field_ptr_ty = try mod.ptrType(.{ |
| 6840 | .child = llvm_field.ty.toIntern(), | 6929 | .child = llvm_field.ty.toIntern(), |
| ... | @@ -6858,7 +6947,7 @@ pub const FuncGen = struct { | ... | @@ -6858,7 +6947,7 @@ pub const FuncGen = struct { |
| 6858 | if (optional_ty.optionalReprIsPayload(mod)) { | 6947 | if (optional_ty.optionalReprIsPayload(mod)) { |
| 6859 | return operand; | 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 | if (isByRef(optional_ty, mod)) { | 6951 | if (isByRef(optional_ty, mod)) { |
| 6863 | const optional_ptr = self.buildAlloca(llvm_optional_ty, optional_ty.abiAlignment(mod)); | 6952 | const optional_ptr = self.buildAlloca(llvm_optional_ty, optional_ty.abiAlignment(mod)); |
| 6864 | const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, ""); | 6953 | const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, ""); |
| ... | @@ -6882,8 +6971,8 @@ pub const FuncGen = struct { | ... | @@ -6882,8 +6971,8 @@ pub const FuncGen = struct { |
| 6882 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 6971 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 6883 | return operand; | 6972 | return operand; |
| 6884 | } | 6973 | } |
| 6885 | const ok_err_code = (try o.lowerType(Type.anyerror)).constNull(); | 6974 | const ok_err_code = (try o.lowerLlvmType(Type.anyerror)).constNull(); |
| 6886 | const err_un_llvm_ty = try o.lowerType(err_un_ty); | 6975 | const err_un_llvm_ty = try o.lowerLlvmType(err_un_ty); |
| 6887 | | 6976 | |
| 6888 | const payload_offset = errUnionPayloadOffset(payload_ty, mod); | 6977 | const payload_offset = errUnionPayloadOffset(payload_ty, mod); |
| 6889 | const error_offset = errUnionErrorOffset(payload_ty, mod); | 6978 | const error_offset = errUnionErrorOffset(payload_ty, mod); |
| ... | @@ -6912,7 +7001,7 @@ pub const FuncGen = struct { | ... | @@ -6912,7 +7001,7 @@ pub const FuncGen = struct { |
| 6912 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 7001 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 6913 | return operand; | 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 | const payload_offset = errUnionPayloadOffset(payload_ty, mod); | 7006 | const payload_offset = errUnionPayloadOffset(payload_ty, mod); |
| 6918 | const error_offset = errUnionErrorOffset(payload_ty, mod); | 7007 | const error_offset = errUnionErrorOffset(payload_ty, mod); |
| ... | @@ -6968,7 +7057,7 @@ pub const FuncGen = struct { | ... | @@ -6968,7 +7057,7 @@ pub const FuncGen = struct { |
| 6968 | const operand = try self.resolveInst(extra.rhs); | 7057 | const operand = try self.resolveInst(extra.rhs); |
| 6969 | | 7058 | |
| 6970 | const loaded_vector = blk: { | 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 | const load_inst = self.builder.buildLoad(elem_llvm_ty, vector_ptr, ""); | 7061 | const load_inst = self.builder.buildLoad(elem_llvm_ty, vector_ptr, ""); |
| 6973 | load_inst.setAlignment(vector_ptr_ty.ptrAlignment(mod)); | 7062 | load_inst.setAlignment(vector_ptr_ty.ptrAlignment(mod)); |
| 6974 | load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr(mod))); | 7063 | load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr(mod))); |
| ... | @@ -7012,7 +7101,7 @@ pub const FuncGen = struct { | ... | @@ -7012,7 +7101,7 @@ pub const FuncGen = struct { |
| 7012 | const ptr = try self.resolveInst(bin_op.lhs); | 7101 | const ptr = try self.resolveInst(bin_op.lhs); |
| 7013 | const len = try self.resolveInst(bin_op.rhs); | 7102 | const len = try self.resolveInst(bin_op.rhs); |
| 7014 | const inst_ty = self.typeOfIndex(inst); | 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 | // In case of slicing a global, the result type looks something like `{ i8*, i64 }` | 7106 | // In case of slicing a global, the result type looks something like `{ i8*, i64 }` |
| 7018 | // but `ptr` is pointing to the global directly. | 7107 | // but `ptr` is pointing to the global directly. |
| ... | @@ -7056,7 +7145,7 @@ pub const FuncGen = struct { | ... | @@ -7056,7 +7145,7 @@ pub const FuncGen = struct { |
| 7056 | true => signed_intrinsic, | 7145 | true => signed_intrinsic, |
| 7057 | false => unsigned_intrinsic, | 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 | const llvm_fn = fg.getIntrinsic(intrinsic_name, &.{llvm_inst_ty}); | 7149 | const llvm_fn = fg.getIntrinsic(intrinsic_name, &.{llvm_inst_ty}); |
| 7061 | const result_struct = fg.builder.buildCall( | 7150 | const result_struct = fg.builder.buildCall( |
| 7062 | llvm_fn.globalGetValueType(), | 7151 | llvm_fn.globalGetValueType(), |
| ... | @@ -7229,11 +7318,11 @@ pub const FuncGen = struct { | ... | @@ -7229,11 +7318,11 @@ pub const FuncGen = struct { |
| 7229 | return self.buildFloatOp(.floor, inst_ty, 1, .{result}); | 7318 | return self.buildFloatOp(.floor, inst_ty, 1, .{result}); |
| 7230 | } | 7319 | } |
| 7231 | if (scalar_ty.isSignedInt(mod)) { | 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 | const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1; | 7322 | const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1; |
| 7234 | const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: { | 7323 | const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: { |
| 7235 | const vec_len = inst_ty.vectorLen(mod); | 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 | const shifts = try self.gpa.alloc(*llvm.Value, vec_len); | 7327 | const shifts = try self.gpa.alloc(*llvm.Value, vec_len); |
| 7239 | defer self.gpa.free(shifts); | 7328 | defer self.gpa.free(shifts); |
| ... | @@ -7295,7 +7384,7 @@ pub const FuncGen = struct { | ... | @@ -7295,7 +7384,7 @@ pub const FuncGen = struct { |
| 7295 | const lhs = try self.resolveInst(bin_op.lhs); | 7384 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7296 | const rhs = try self.resolveInst(bin_op.rhs); | 7385 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7297 | const inst_ty = self.typeOfIndex(inst); | 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 | const scalar_ty = inst_ty.scalarType(mod); | 7388 | const scalar_ty = inst_ty.scalarType(mod); |
| 7300 | | 7389 | |
| 7301 | if (scalar_ty.isRuntimeFloat()) { | 7390 | if (scalar_ty.isRuntimeFloat()) { |
| ... | @@ -7310,7 +7399,7 @@ pub const FuncGen = struct { | ... | @@ -7310,7 +7399,7 @@ pub const FuncGen = struct { |
| 7310 | const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1; | 7399 | const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1; |
| 7311 | const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: { | 7400 | const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: { |
| 7312 | const vec_len = inst_ty.vectorLen(mod); | 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 | const shifts = try self.gpa.alloc(*llvm.Value, vec_len); | 7404 | const shifts = try self.gpa.alloc(*llvm.Value, vec_len); |
| 7316 | defer self.gpa.free(shifts); | 7405 | defer self.gpa.free(shifts); |
| ... | @@ -7408,8 +7497,8 @@ pub const FuncGen = struct { | ... | @@ -7408,8 +7497,8 @@ pub const FuncGen = struct { |
| 7408 | | 7497 | |
| 7409 | const intrinsic_name = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic; | 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); | 7500 | const llvm_lhs_ty = try o.lowerLlvmType(lhs_ty); |
| 7412 | const llvm_dest_ty = try o.lowerType(dest_ty); | 7501 | const llvm_dest_ty = try o.lowerLlvmType(dest_ty); |
| 7413 | | 7502 | |
| 7414 | const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty}); | 7503 | const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty}); |
| 7415 | const result_struct = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &[_]*llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, ""); | 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,15 +7561,30 @@ pub const FuncGen = struct { |
| 7472 | fn_name: [:0]const u8, | 7561 | fn_name: [:0]const u8, |
| 7473 | param_types: []const *llvm.Type, | 7562 | param_types: []const *llvm.Type, |
| 7474 | return_type: *llvm.Type, | 7563 | return_type: *llvm.Type, |
| 7475 | ) *llvm.Value { | 7564 | ) Allocator.Error!*llvm.Value { |
| 7476 | const o = self.dg.object; | 7565 | const o = self.dg.object; |
| 7477 | return o.llvm_module.getNamedFunction(fn_name.ptr) orelse b: { | 7566 | return o.llvm_module.getNamedFunction(fn_name.ptr) orelse b: { |
| 7478 | const alias = o.llvm_module.getNamedGlobalAlias(fn_name.ptr, fn_name.len); | 7567 | const alias = o.llvm_module.getNamedGlobalAlias(fn_name.ptr, fn_name.len); |
| 7479 | break :b if (alias) |a| a.getAliasee() else null; | 7568 | break :b if (alias) |a| a.getAliasee() else null; |
| 7480 | } orelse b: { | 7569 | } orelse b: { |
| | 7570 | const name = try o.builder.string(fn_name); |
| | 7571 | |
| 7481 | const params_len = @as(c_uint, @intCast(param_types.len)); | 7572 | const params_len = @as(c_uint, @intCast(param_types.len)); |
| 7482 | const fn_type = llvm.functionType(return_type, param_types.ptr, params_len, .False); | 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 | break :b f; | 7588 | break :b f; |
| 7485 | }; | 7589 | }; |
| 7486 | } | 7590 | } |
| ... | @@ -7497,7 +7601,7 @@ pub const FuncGen = struct { | ... | @@ -7497,7 +7601,7 @@ pub const FuncGen = struct { |
| 7497 | const mod = o.module; | 7601 | const mod = o.module; |
| 7498 | const target = o.module.getTarget(); | 7602 | const target = o.module.getTarget(); |
| 7499 | const scalar_ty = ty.scalarType(mod); | 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 | if (intrinsicsAllowed(scalar_ty, target)) { | 7606 | if (intrinsicsAllowed(scalar_ty, target)) { |
| 7503 | const llvm_predicate: llvm.RealPredicate = switch (pred) { | 7607 | const llvm_predicate: llvm.RealPredicate = switch (pred) { |
| ... | @@ -7528,7 +7632,7 @@ pub const FuncGen = struct { | ... | @@ -7528,7 +7632,7 @@ pub const FuncGen = struct { |
| 7528 | | 7632 | |
| 7529 | const param_types = [2]*llvm.Type{ scalar_llvm_ty, scalar_llvm_ty }; | 7633 | const param_types = [2]*llvm.Type{ scalar_llvm_ty, scalar_llvm_ty }; |
| 7530 | const llvm_i32 = self.context.intType(32); | 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 | const zero = llvm_i32.constInt(0, .False); | 7637 | const zero = llvm_i32.constInt(0, .False); |
| 7534 | const int_pred: llvm.IntPredicate = switch (pred) { | 7638 | const int_pred: llvm.IntPredicate = switch (pred) { |
| ... | @@ -7600,8 +7704,8 @@ pub const FuncGen = struct { | ... | @@ -7600,8 +7704,8 @@ pub const FuncGen = struct { |
| 7600 | const mod = o.module; | 7704 | const mod = o.module; |
| 7601 | const target = mod.getTarget(); | 7705 | const target = mod.getTarget(); |
| 7602 | const scalar_ty = ty.scalarType(mod); | 7706 | const scalar_ty = ty.scalarType(mod); |
| 7603 | const llvm_ty = try o.lowerType(ty); | 7707 | const llvm_ty = try o.lowerLlvmType(ty); |
| 7604 | const scalar_llvm_ty = try o.lowerType(scalar_ty); | 7708 | const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty); |
| 7605 | | 7709 | |
| 7606 | const intrinsics_allowed = op != .tan and intrinsicsAllowed(scalar_ty, target); | 7710 | const intrinsics_allowed = op != .tan and intrinsicsAllowed(scalar_ty, target); |
| 7607 | var fn_name_buf: [64]u8 = undefined; | 7711 | var fn_name_buf: [64]u8 = undefined; |
| ... | @@ -7672,7 +7776,7 @@ pub const FuncGen = struct { | ... | @@ -7672,7 +7776,7 @@ pub const FuncGen = struct { |
| 7672 | .intrinsic => |fn_name| self.getIntrinsic(fn_name, &.{llvm_ty}), | 7776 | .intrinsic => |fn_name| self.getIntrinsic(fn_name, &.{llvm_ty}), |
| 7673 | .libc => |fn_name| b: { | 7777 | .libc => |fn_name| b: { |
| 7674 | const param_types = [3]*llvm.Type{ scalar_llvm_ty, scalar_llvm_ty, scalar_llvm_ty }; | 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 | if (ty.zigTypeTag(mod) == .Vector) { | 7780 | if (ty.zigTypeTag(mod) == .Vector) { |
| 7677 | const result = llvm_ty.getUndef(); | 7781 | const result = llvm_ty.getUndef(); |
| 7678 | return self.buildElementwiseCall(libc_fn, &params, result, ty.vectorLen(mod)); | 7782 | return self.buildElementwiseCall(libc_fn, &params, result, ty.vectorLen(mod)); |
| ... | @@ -7711,10 +7815,10 @@ pub const FuncGen = struct { | ... | @@ -7711,10 +7815,10 @@ pub const FuncGen = struct { |
| 7711 | const rhs_scalar_ty = rhs_ty.scalarType(mod); | 7815 | const rhs_scalar_ty = rhs_ty.scalarType(mod); |
| 7712 | | 7816 | |
| 7713 | const dest_ty = self.typeOfIndex(inst); | 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 | const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod)) | 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 | else | 7822 | else |
| 7719 | rhs; | 7823 | rhs; |
| 7720 | | 7824 | |
| ... | @@ -7785,7 +7889,7 @@ pub const FuncGen = struct { | ... | @@ -7785,7 +7889,7 @@ pub const FuncGen = struct { |
| 7785 | const rhs_scalar_ty = rhs_ty.scalarType(mod); | 7889 | const rhs_scalar_ty = rhs_ty.scalarType(mod); |
| 7786 | | 7890 | |
| 7787 | const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod)) | 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 | else | 7893 | else |
| 7790 | rhs; | 7894 | rhs; |
| 7791 | if (lhs_scalar_ty.isSignedInt(mod)) return self.builder.buildNSWShl(lhs, casted_rhs, ""); | 7895 | if (lhs_scalar_ty.isSignedInt(mod)) return self.builder.buildNSWShl(lhs, casted_rhs, ""); |
| ... | @@ -7806,7 +7910,7 @@ pub const FuncGen = struct { | ... | @@ -7806,7 +7910,7 @@ pub const FuncGen = struct { |
| 7806 | const rhs_scalar_ty = rhs_type.scalarType(mod); | 7910 | const rhs_scalar_ty = rhs_type.scalarType(mod); |
| 7807 | | 7911 | |
| 7808 | const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod)) | 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 | else | 7914 | else |
| 7811 | rhs; | 7915 | rhs; |
| 7812 | return self.builder.buildShl(lhs, casted_rhs, ""); | 7916 | return self.builder.buildShl(lhs, casted_rhs, ""); |
| ... | @@ -7841,7 +7945,7 @@ pub const FuncGen = struct { | ... | @@ -7841,7 +7945,7 @@ pub const FuncGen = struct { |
| 7841 | // poison value." | 7945 | // poison value." |
| 7842 | // However Zig semantics says that saturating shift left can never produce | 7946 | // However Zig semantics says that saturating shift left can never produce |
| 7843 | // undefined; instead it saturates. | 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 | const bits = lhs_scalar_llvm_ty.constInt(lhs_bits, .False); | 7949 | const bits = lhs_scalar_llvm_ty.constInt(lhs_bits, .False); |
| 7846 | const lhs_max = lhs_scalar_llvm_ty.constAllOnes(); | 7950 | const lhs_max = lhs_scalar_llvm_ty.constAllOnes(); |
| 7847 | if (rhs_ty.zigTypeTag(mod) == .Vector) { | 7951 | if (rhs_ty.zigTypeTag(mod) == .Vector) { |
| ... | @@ -7870,7 +7974,7 @@ pub const FuncGen = struct { | ... | @@ -7870,7 +7974,7 @@ pub const FuncGen = struct { |
| 7870 | const rhs_scalar_ty = rhs_ty.scalarType(mod); | 7974 | const rhs_scalar_ty = rhs_ty.scalarType(mod); |
| 7871 | | 7975 | |
| 7872 | const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod)) | 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 | else | 7978 | else |
| 7875 | rhs; | 7979 | rhs; |
| 7876 | const is_signed_int = lhs_scalar_ty.isSignedInt(mod); | 7980 | const is_signed_int = lhs_scalar_ty.isSignedInt(mod); |
| ... | @@ -7896,7 +8000,7 @@ pub const FuncGen = struct { | ... | @@ -7896,7 +8000,7 @@ pub const FuncGen = struct { |
| 7896 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 8000 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 7897 | const dest_ty = self.typeOfIndex(inst); | 8001 | const dest_ty = self.typeOfIndex(inst); |
| 7898 | const dest_info = dest_ty.intInfo(mod); | 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 | const operand = try self.resolveInst(ty_op.operand); | 8004 | const operand = try self.resolveInst(ty_op.operand); |
| 7901 | const operand_ty = self.typeOf(ty_op.operand); | 8005 | const operand_ty = self.typeOf(ty_op.operand); |
| 7902 | const operand_info = operand_ty.intInfo(mod); | 8006 | const operand_info = operand_ty.intInfo(mod); |
| ... | @@ -7917,7 +8021,7 @@ pub const FuncGen = struct { | ... | @@ -7917,7 +8021,7 @@ pub const FuncGen = struct { |
| 7917 | const o = self.dg.object; | 8021 | const o = self.dg.object; |
| 7918 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 8022 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 7919 | const operand = try self.resolveInst(ty_op.operand); | 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 | return self.builder.buildTrunc(operand, dest_llvm_ty, ""); | 8025 | return self.builder.buildTrunc(operand, dest_llvm_ty, ""); |
| 7922 | } | 8026 | } |
| 7923 | | 8027 | |
| ... | @@ -7933,11 +8037,11 @@ pub const FuncGen = struct { | ... | @@ -7933,11 +8037,11 @@ pub const FuncGen = struct { |
| 7933 | const src_bits = operand_ty.floatBits(target); | 8037 | const src_bits = operand_ty.floatBits(target); |
| 7934 | | 8038 | |
| 7935 | if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) { | 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 | return self.builder.buildFPTrunc(operand, dest_llvm_ty, ""); | 8041 | return self.builder.buildFPTrunc(operand, dest_llvm_ty, ""); |
| 7938 | } else { | 8042 | } else { |
| 7939 | const operand_llvm_ty = try o.lowerType(operand_ty); | 8043 | const operand_llvm_ty = try o.lowerLlvmType(operand_ty); |
| 7940 | const dest_llvm_ty = try o.lowerType(dest_ty); | 8044 | const dest_llvm_ty = try o.lowerLlvmType(dest_ty); |
| 7941 | | 8045 | |
| 7942 | var fn_name_buf: [64]u8 = undefined; | 8046 | var fn_name_buf: [64]u8 = undefined; |
| 7943 | const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__trunc{s}f{s}f2", .{ | 8047 | const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__trunc{s}f{s}f2", .{ |
| ... | @@ -7946,7 +8050,7 @@ pub const FuncGen = struct { | ... | @@ -7946,7 +8050,7 @@ pub const FuncGen = struct { |
| 7946 | | 8050 | |
| 7947 | const params = [1]*llvm.Value{operand}; | 8051 | const params = [1]*llvm.Value{operand}; |
| 7948 | const param_types = [1]*llvm.Type{operand_llvm_ty}; | 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 | return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .C, .Auto, ""); | 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,11 +8068,11 @@ pub const FuncGen = struct { |
| 7964 | const src_bits = operand_ty.floatBits(target); | 8068 | const src_bits = operand_ty.floatBits(target); |
| 7965 | | 8069 | |
| 7966 | if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) { | 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 | return self.builder.buildFPExt(operand, dest_llvm_ty, ""); | 8072 | return self.builder.buildFPExt(operand, dest_llvm_ty, ""); |
| 7969 | } else { | 8073 | } else { |
| 7970 | const operand_llvm_ty = try o.lowerType(operand_ty); | 8074 | const operand_llvm_ty = try o.lowerLlvmType(operand_ty); |
| 7971 | const dest_llvm_ty = try o.lowerType(dest_ty); | 8075 | const dest_llvm_ty = try o.lowerLlvmType(dest_ty); |
| 7972 | | 8076 | |
| 7973 | var fn_name_buf: [64]u8 = undefined; | 8077 | var fn_name_buf: [64]u8 = undefined; |
| 7974 | const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__extend{s}f{s}f2", .{ | 8078 | const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__extend{s}f{s}f2", .{ |
| ... | @@ -7977,7 +8081,7 @@ pub const FuncGen = struct { | ... | @@ -7977,7 +8081,7 @@ pub const FuncGen = struct { |
| 7977 | | 8081 | |
| 7978 | const params = [1]*llvm.Value{operand}; | 8082 | const params = [1]*llvm.Value{operand}; |
| 7979 | const param_types = [1]*llvm.Type{operand_llvm_ty}; | 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 | return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .C, .Auto, ""); | 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,7 +8093,7 @@ pub const FuncGen = struct { |
| 7989 | const operand = try self.resolveInst(un_op); | 8093 | const operand = try self.resolveInst(un_op); |
| 7990 | const ptr_ty = self.typeOf(un_op); | 8094 | const ptr_ty = self.typeOf(un_op); |
| 7991 | const operand_ptr = self.sliceOrArrayPtr(operand, ptr_ty); | 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 | return self.builder.buildPtrToInt(operand_ptr, dest_llvm_ty, ""); | 8097 | return self.builder.buildPtrToInt(operand_ptr, dest_llvm_ty, ""); |
| 7994 | } | 8098 | } |
| 7995 | | 8099 | |
| ... | @@ -8006,7 +8110,7 @@ pub const FuncGen = struct { | ... | @@ -8006,7 +8110,7 @@ pub const FuncGen = struct { |
| 8006 | const mod = o.module; | 8110 | const mod = o.module; |
| 8007 | const operand_is_ref = isByRef(operand_ty, mod); | 8111 | const operand_is_ref = isByRef(operand_ty, mod); |
| 8008 | const result_is_ref = isByRef(inst_ty, mod); | 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 | if (operand_is_ref and result_is_ref) { | 8115 | if (operand_is_ref and result_is_ref) { |
| 8012 | // They are both pointers, so just return the same opaque pointer :) | 8116 | // They are both pointers, so just return the same opaque pointer :) |
| ... | @@ -8036,7 +8140,7 @@ pub const FuncGen = struct { | ... | @@ -8036,7 +8140,7 @@ pub const FuncGen = struct { |
| 8036 | } else { | 8140 | } else { |
| 8037 | // If the ABI size of the element type is not evenly divisible by size in bits; | 8141 | // If the ABI size of the element type is not evenly divisible by size in bits; |
| 8038 | // a simple bitcast will not work, and we fall back to extractelement. | 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 | const llvm_u32 = self.context.intType(32); | 8144 | const llvm_u32 = self.context.intType(32); |
| 8041 | const zero = llvm_usize.constNull(); | 8145 | const zero = llvm_usize.constNull(); |
| 8042 | const vector_len = operand_ty.arrayLen(mod); | 8146 | const vector_len = operand_ty.arrayLen(mod); |
| ... | @@ -8053,7 +8157,7 @@ pub const FuncGen = struct { | ... | @@ -8053,7 +8157,7 @@ pub const FuncGen = struct { |
| 8053 | return array_ptr; | 8157 | return array_ptr; |
| 8054 | } else if (operand_ty.zigTypeTag(mod) == .Array and inst_ty.zigTypeTag(mod) == .Vector) { | 8158 | } else if (operand_ty.zigTypeTag(mod) == .Array and inst_ty.zigTypeTag(mod) == .Vector) { |
| 8055 | const elem_ty = operand_ty.childType(mod); | 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 | if (!operand_is_ref) { | 8161 | if (!operand_is_ref) { |
| 8058 | return self.dg.todo("implement bitcast non-ref array to vector", .{}); | 8162 | return self.dg.todo("implement bitcast non-ref array to vector", .{}); |
| 8059 | } | 8163 | } |
| ... | @@ -8068,9 +8172,9 @@ pub const FuncGen = struct { | ... | @@ -8068,9 +8172,9 @@ pub const FuncGen = struct { |
| 8068 | } else { | 8172 | } else { |
| 8069 | // If the ABI size of the element type is not evenly divisible by size in bits; | 8173 | // If the ABI size of the element type is not evenly divisible by size in bits; |
| 8070 | // a simple bitcast will not work, and we fall back to extractelement. | 8174 | // a simple bitcast will not work, and we fall back to extractelement. |
| 8071 | const array_llvm_ty = try o.lowerType(operand_ty); | 8175 | const array_llvm_ty = try o.lowerLlvmType(operand_ty); |
| 8072 | const elem_llvm_ty = try o.lowerType(elem_ty); | 8176 | const elem_llvm_ty = try o.lowerLlvmType(elem_ty); |
| 8073 | const llvm_usize = try o.lowerType(Type.usize); | 8177 | const llvm_usize = try o.lowerLlvmType(Type.usize); |
| 8074 | const llvm_u32 = self.context.intType(32); | 8178 | const llvm_u32 = self.context.intType(32); |
| 8075 | const zero = llvm_usize.constNull(); | 8179 | const zero = llvm_usize.constNull(); |
| 8076 | const vector_len = operand_ty.arrayLen(mod); | 8180 | const vector_len = operand_ty.arrayLen(mod); |
| ... | @@ -8179,7 +8283,7 @@ pub const FuncGen = struct { | ... | @@ -8179,7 +8283,7 @@ pub const FuncGen = struct { |
| 8179 | if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) | 8283 | if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) |
| 8180 | return o.lowerPtrToVoid(ptr_ty); | 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 | const alignment = ptr_ty.ptrAlignment(mod); | 8287 | const alignment = ptr_ty.ptrAlignment(mod); |
| 8184 | return self.buildAlloca(pointee_llvm_ty, alignment); | 8288 | return self.buildAlloca(pointee_llvm_ty, alignment); |
| 8185 | } | 8289 | } |
| ... | @@ -8191,7 +8295,7 @@ pub const FuncGen = struct { | ... | @@ -8191,7 +8295,7 @@ pub const FuncGen = struct { |
| 8191 | const ret_ty = ptr_ty.childType(mod); | 8295 | const ret_ty = ptr_ty.childType(mod); |
| 8192 | if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return o.lowerPtrToVoid(ptr_ty); | 8296 | if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return o.lowerPtrToVoid(ptr_ty); |
| 8193 | if (self.ret_ptr) |ret_ptr| return ret_ptr; | 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 | return self.buildAlloca(ret_llvm_ty, ptr_ty.ptrAlignment(mod)); | 8299 | return self.buildAlloca(ret_llvm_ty, ptr_ty.ptrAlignment(mod)); |
| 8196 | } | 8300 | } |
| 8197 | | 8301 | |
| ... | @@ -8223,7 +8327,7 @@ pub const FuncGen = struct { | ... | @@ -8223,7 +8327,7 @@ pub const FuncGen = struct { |
| 8223 | else | 8327 | else |
| 8224 | u8_llvm_ty.getUndef(); | 8328 | u8_llvm_ty.getUndef(); |
| 8225 | const operand_size = operand_ty.abiSize(mod); | 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 | const len = usize_llvm_ty.constInt(operand_size, .False); | 8331 | const len = usize_llvm_ty.constInt(operand_size, .False); |
| 8228 | const dest_ptr_align = ptr_ty.ptrAlignment(mod); | 8332 | const dest_ptr_align = ptr_ty.ptrAlignment(mod); |
| 8229 | _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr(mod)); | 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,7 +8400,7 @@ pub const FuncGen = struct { |
| 8296 | _ = inst; | 8400 | _ = inst; |
| 8297 | const o = self.dg.object; | 8401 | const o = self.dg.object; |
| 8298 | const mod = o.module; | 8402 | const mod = o.module; |
| 8299 | const llvm_usize = try o.lowerType(Type.usize); | 8403 | const llvm_usize = try o.lowerLlvmType(Type.usize); |
| 8300 | const target = mod.getTarget(); | 8404 | const target = mod.getTarget(); |
| 8301 | if (!target_util.supportsReturnAddress(target)) { | 8405 | if (!target_util.supportsReturnAddress(target)) { |
| 8302 | // https://github.com/ziglang/zig/issues/11946 | 8406 | // https://github.com/ziglang/zig/issues/11946 |
| ... | @@ -8324,7 +8428,7 @@ pub const FuncGen = struct { | ... | @@ -8324,7 +8428,7 @@ pub const FuncGen = struct { |
| 8324 | | 8428 | |
| 8325 | const params = [_]*llvm.Value{llvm_i32.constNull()}; | 8429 | const params = [_]*llvm.Value{llvm_i32.constNull()}; |
| 8326 | const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, ""); | 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 | return self.builder.buildPtrToInt(ptr_val, llvm_usize, ""); | 8432 | return self.builder.buildPtrToInt(ptr_val, llvm_usize, ""); |
| 8329 | } | 8433 | } |
| 8330 | | 8434 | |
| ... | @@ -8370,7 +8474,7 @@ pub const FuncGen = struct { | ... | @@ -8370,7 +8474,7 @@ pub const FuncGen = struct { |
| 8370 | | 8474 | |
| 8371 | var payload = self.builder.buildExtractValue(result, 0, ""); | 8475 | var payload = self.builder.buildExtractValue(result, 0, ""); |
| 8372 | if (opt_abi_ty != null) { | 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 | const success_bit = self.builder.buildExtractValue(result, 1, ""); | 8479 | const success_bit = self.builder.buildExtractValue(result, 1, ""); |
| 8376 | | 8480 | |
| ... | @@ -8415,7 +8519,7 @@ pub const FuncGen = struct { | ... | @@ -8415,7 +8519,7 @@ pub const FuncGen = struct { |
| 8415 | ordering, | 8519 | ordering, |
| 8416 | single_threaded, | 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 | if (is_float) { | 8523 | if (is_float) { |
| 8420 | return self.builder.buildBitCast(uncasted_result, operand_llvm_ty, ""); | 8524 | return self.builder.buildBitCast(uncasted_result, operand_llvm_ty, ""); |
| 8421 | } else { | 8525 | } else { |
| ... | @@ -8428,7 +8532,7 @@ pub const FuncGen = struct { | ... | @@ -8428,7 +8532,7 @@ pub const FuncGen = struct { |
| 8428 | } | 8532 | } |
| 8429 | | 8533 | |
| 8430 | // It's a pointer but we need to treat it as an int. | 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 | const casted_operand = self.builder.buildPtrToInt(operand, usize_llvm_ty, ""); | 8536 | const casted_operand = self.builder.buildPtrToInt(operand, usize_llvm_ty, ""); |
| 8433 | const uncasted_result = self.builder.buildAtomicRmw( | 8537 | const uncasted_result = self.builder.buildAtomicRmw( |
| 8434 | op, | 8538 | op, |
| ... | @@ -8437,7 +8541,7 @@ pub const FuncGen = struct { | ... | @@ -8437,7 +8541,7 @@ pub const FuncGen = struct { |
| 8437 | ordering, | 8541 | ordering, |
| 8438 | single_threaded, | 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 | return self.builder.buildIntToPtr(uncasted_result, operand_llvm_ty, ""); | 8545 | return self.builder.buildIntToPtr(uncasted_result, operand_llvm_ty, ""); |
| 8442 | } | 8546 | } |
| 8443 | | 8547 | |
| ... | @@ -8456,7 +8560,7 @@ pub const FuncGen = struct { | ... | @@ -8456,7 +8560,7 @@ pub const FuncGen = struct { |
| 8456 | const ptr_alignment = @as(u32, @intCast(ptr_info.flags.alignment.toByteUnitsOptional() orelse | 8560 | const ptr_alignment = @as(u32, @intCast(ptr_info.flags.alignment.toByteUnitsOptional() orelse |
| 8457 | ptr_info.child.toType().abiAlignment(mod))); | 8561 | ptr_info.child.toType().abiAlignment(mod))); |
| 8458 | const ptr_volatile = llvm.Bool.fromBool(ptr_info.flags.is_volatile); | 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 | if (opt_abi_llvm_ty) |abi_llvm_ty| { | 8565 | if (opt_abi_llvm_ty) |abi_llvm_ty| { |
| 8462 | // operand needs widening and truncating | 8566 | // operand needs widening and truncating |
| ... | @@ -8606,7 +8710,7 @@ pub const FuncGen = struct { | ... | @@ -8606,7 +8710,7 @@ pub const FuncGen = struct { |
| 8606 | .One => llvm_usize_ty.constInt(ptr_ty.childType(mod).arrayLen(mod), .False), | 8710 | .One => llvm_usize_ty.constInt(ptr_ty.childType(mod).arrayLen(mod), .False), |
| 8607 | .Many, .C => unreachable, | 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 | const len_gep = [_]*llvm.Value{len}; | 8714 | const len_gep = [_]*llvm.Value{len}; |
| 8611 | const end_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, dest_ptr, &len_gep, len_gep.len, ""); | 8715 | const end_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, dest_ptr, &len_gep, len_gep.len, ""); |
| 8612 | _ = self.builder.buildBr(loop_block); | 8716 | _ = self.builder.buildBr(loop_block); |
| ... | @@ -8731,7 +8835,7 @@ pub const FuncGen = struct { | ... | @@ -8731,7 +8835,7 @@ pub const FuncGen = struct { |
| 8731 | _ = self.builder.buildStore(new_tag, union_ptr); | 8835 | _ = self.builder.buildStore(new_tag, union_ptr); |
| 8732 | return null; | 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 | const tag_index = @intFromBool(layout.tag_align < layout.payload_align); | 8839 | const tag_index = @intFromBool(layout.tag_align < layout.payload_align); |
| 8736 | const tag_field_ptr = self.builder.buildStructGEP(un_llvm_ty, union_ptr, tag_index, ""); | 8840 | const tag_field_ptr = self.builder.buildStructGEP(un_llvm_ty, union_ptr, tag_index, ""); |
| 8737 | // TODO alignment on this store | 8841 | // TODO alignment on this store |
| ... | @@ -8748,7 +8852,7 @@ pub const FuncGen = struct { | ... | @@ -8748,7 +8852,7 @@ pub const FuncGen = struct { |
| 8748 | if (layout.tag_size == 0) return null; | 8852 | if (layout.tag_size == 0) return null; |
| 8749 | const union_handle = try self.resolveInst(ty_op.operand); | 8853 | const union_handle = try self.resolveInst(ty_op.operand); |
| 8750 | if (isByRef(un_ty, mod)) { | 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 | if (layout.payload_size == 0) { | 8856 | if (layout.payload_size == 0) { |
| 8753 | return self.builder.buildLoad(llvm_un_ty, union_handle, ""); | 8857 | return self.builder.buildLoad(llvm_un_ty, union_handle, ""); |
| 8754 | } | 8858 | } |
| ... | @@ -8790,13 +8894,13 @@ pub const FuncGen = struct { | ... | @@ -8790,13 +8894,13 @@ pub const FuncGen = struct { |
| 8790 | const operand = try self.resolveInst(ty_op.operand); | 8894 | const operand = try self.resolveInst(ty_op.operand); |
| 8791 | | 8895 | |
| 8792 | const llvm_i1 = self.context.intType(1); | 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 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); | 8898 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); |
| 8795 | | 8899 | |
| 8796 | const params = [_]*llvm.Value{ operand, llvm_i1.constNull() }; | 8900 | const params = [_]*llvm.Value{ operand, llvm_i1.constNull() }; |
| 8797 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); | 8901 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); |
| 8798 | const result_ty = self.typeOfIndex(inst); | 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 | const bits = operand_ty.intInfo(mod).bits; | 8905 | const bits = operand_ty.intInfo(mod).bits; |
| 8802 | const result_bits = result_ty.intInfo(mod).bits; | 8906 | const result_bits = result_ty.intInfo(mod).bits; |
| ... | @@ -8817,12 +8921,12 @@ pub const FuncGen = struct { | ... | @@ -8817,12 +8921,12 @@ pub const FuncGen = struct { |
| 8817 | const operand = try self.resolveInst(ty_op.operand); | 8921 | const operand = try self.resolveInst(ty_op.operand); |
| 8818 | | 8922 | |
| 8819 | const params = [_]*llvm.Value{operand}; | 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 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); | 8925 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); |
| 8822 | | 8926 | |
| 8823 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); | 8927 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); |
| 8824 | const result_ty = self.typeOfIndex(inst); | 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 | const bits = operand_ty.intInfo(mod).bits; | 8931 | const bits = operand_ty.intInfo(mod).bits; |
| 8828 | const result_bits = result_ty.intInfo(mod).bits; | 8932 | const result_bits = result_ty.intInfo(mod).bits; |
| ... | @@ -8844,7 +8948,7 @@ pub const FuncGen = struct { | ... | @@ -8844,7 +8948,7 @@ pub const FuncGen = struct { |
| 8844 | assert(bits % 8 == 0); | 8948 | assert(bits % 8 == 0); |
| 8845 | | 8949 | |
| 8846 | var operand = try self.resolveInst(ty_op.operand); | 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 | if (bits % 16 == 8) { | 8953 | if (bits % 16 == 8) { |
| 8850 | // If not an even byte-multiple, we need zero-extend + shift-left 1 byte | 8954 | // If not an even byte-multiple, we need zero-extend + shift-left 1 byte |
| ... | @@ -8878,7 +8982,7 @@ pub const FuncGen = struct { | ... | @@ -8878,7 +8982,7 @@ pub const FuncGen = struct { |
| 8878 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); | 8982 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); |
| 8879 | | 8983 | |
| 8880 | const result_ty = self.typeOfIndex(inst); | 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 | const result_bits = result_ty.intInfo(mod).bits; | 8986 | const result_bits = result_ty.intInfo(mod).bits; |
| 8883 | if (bits > result_bits) { | 8987 | if (bits > result_bits) { |
| 8884 | return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, ""); | 8988 | return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, ""); |
| ... | @@ -8957,9 +9061,9 @@ pub const FuncGen = struct { | ... | @@ -8957,9 +9061,9 @@ pub const FuncGen = struct { |
| 8957 | const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod); | 9061 | const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod); |
| 8958 | const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{}", .{fqn.fmt(&mod.intern_pool)}); | 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 | const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False); | 9067 | const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False); |
| 8964 | const fn_val = o.llvm_module.addFunction(llvm_fn_name, fn_type); | 9068 | const fn_val = o.llvm_module.addFunction(llvm_fn_name, fn_type); |
| 8965 | fn_val.setLinkage(.Internal); | 9069 | fn_val.setLinkage(.Internal); |
| ... | @@ -9020,29 +9124,32 @@ pub const FuncGen = struct { | ... | @@ -9020,29 +9124,32 @@ pub const FuncGen = struct { |
| 9020 | | 9124 | |
| 9021 | // TODO: detect when the type changes and re-emit this function. | 9125 | // TODO: detect when the type changes and re-emit this function. |
| 9022 | const gop = try o.decl_map.getOrPut(o.gpa, enum_type.decl); | 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 | errdefer assert(o.decl_map.remove(enum_type.decl)); | 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 | const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod); | 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 | const slice_ty = Type.slice_const_u8_sentinel_0; | 9133 | const slice_ty = Type.slice_const_u8_sentinel_0; |
| 9034 | const llvm_ret_ty = try o.lowerType(slice_ty); | 9134 | const llvm_ret_ty = try o.lowerLlvmType(slice_ty); |
| 9035 | const usize_llvm_ty = try o.lowerType(Type.usize); | 9135 | const usize_llvm_ty = try o.lowerLlvmType(Type.usize); |
| 9036 | const slice_alignment = slice_ty.abiAlignment(mod); | 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 | const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False); | 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 | fn_val.setLinkage(.Internal); | 9142 | fn_val.setLinkage(.Internal); |
| 9043 | fn_val.setFunctionCallConv(.Fast); | 9143 | fn_val.setFunctionCallConv(.Fast); |
| 9044 | o.addCommonFnAttributes(fn_val); | 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 | const prev_block = self.builder.getInsertBlock(); | 9154 | const prev_block = self.builder.getInsertBlock(); |
| 9048 | const prev_debug_location = self.builder.getCurrentDebugLocation2(); | 9155 | const prev_debug_location = self.builder.getCurrentDebugLocation2(); |
| ... | @@ -9104,6 +9211,10 @@ pub const FuncGen = struct { | ... | @@ -9104,6 +9211,10 @@ pub const FuncGen = struct { |
| 9104 | | 9211 | |
| 9105 | self.builder.positionBuilderAtEnd(bad_value_block); | 9212 | self.builder.positionBuilderAtEnd(bad_value_block); |
| 9106 | _ = self.builder.buildUnreachable(); | 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 | return fn_val; | 9218 | return fn_val; |
| 9108 | } | 9219 | } |
| 9109 | | 9220 | |
| ... | @@ -9116,8 +9227,8 @@ pub const FuncGen = struct { | ... | @@ -9116,8 +9227,8 @@ pub const FuncGen = struct { |
| 9116 | | 9227 | |
| 9117 | // Function signature: fn (anyerror) bool | 9228 | // Function signature: fn (anyerror) bool |
| 9118 | | 9229 | |
| 9119 | const ret_llvm_ty = try o.lowerType(Type.bool); | 9230 | const ret_llvm_ty = try o.lowerLlvmType(Type.bool); |
| 9120 | const anyerror_llvm_ty = try o.lowerType(Type.anyerror); | 9231 | const anyerror_llvm_ty = try o.lowerLlvmType(Type.anyerror); |
| 9121 | const param_types = [_]*llvm.Type{anyerror_llvm_ty}; | 9232 | const param_types = [_]*llvm.Type{anyerror_llvm_ty}; |
| 9122 | | 9233 | |
| 9123 | const fn_type = llvm.functionType(ret_llvm_ty, &param_types, param_types.len, .False); | 9234 | const fn_type = llvm.functionType(ret_llvm_ty, &param_types, param_types.len, .False); |
| ... | @@ -9133,7 +9244,7 @@ pub const FuncGen = struct { | ... | @@ -9133,7 +9244,7 @@ pub const FuncGen = struct { |
| 9133 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 9244 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 9134 | const operand = try self.resolveInst(un_op); | 9245 | const operand = try self.resolveInst(un_op); |
| 9135 | const slice_ty = self.typeOfIndex(inst); | 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 | const error_name_table_ptr = try self.getErrorNameTable(); | 9249 | const error_name_table_ptr = try self.getErrorNameTable(); |
| 9139 | const ptr_slice_llvm_ty = self.context.pointerType(0); | 9250 | const ptr_slice_llvm_ty = self.context.pointerType(0); |
| ... | @@ -9219,7 +9330,7 @@ pub const FuncGen = struct { | ... | @@ -9219,7 +9330,7 @@ pub const FuncGen = struct { |
| 9219 | accum_init: *llvm.Value, | 9330 | accum_init: *llvm.Value, |
| 9220 | ) !*llvm.Value { | 9331 | ) !*llvm.Value { |
| 9221 | const o = self.dg.object; | 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 | const llvm_vector_len = llvm_usize_ty.constInt(vector_len, .False); | 9334 | const llvm_vector_len = llvm_usize_ty.constInt(vector_len, .False); |
| 9224 | const llvm_result_ty = accum_init.typeOf(); | 9335 | const llvm_result_ty = accum_init.typeOf(); |
| 9225 | | 9336 | |
| ... | @@ -9296,7 +9407,7 @@ pub const FuncGen = struct { | ... | @@ -9296,7 +9407,7 @@ pub const FuncGen = struct { |
| 9296 | .Add => switch (scalar_ty.zigTypeTag(mod)) { | 9407 | .Add => switch (scalar_ty.zigTypeTag(mod)) { |
| 9297 | .Int => return self.builder.buildAddReduce(operand), | 9408 | .Int => return self.builder.buildAddReduce(operand), |
| 9298 | .Float => if (intrinsicsAllowed(scalar_ty, target)) { | 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 | const neutral_value = scalar_llvm_ty.constReal(-0.0); | 9411 | const neutral_value = scalar_llvm_ty.constReal(-0.0); |
| 9301 | return self.builder.buildFPAddReduce(neutral_value, operand); | 9412 | return self.builder.buildFPAddReduce(neutral_value, operand); |
| 9302 | }, | 9413 | }, |
| ... | @@ -9305,7 +9416,7 @@ pub const FuncGen = struct { | ... | @@ -9305,7 +9416,7 @@ pub const FuncGen = struct { |
| 9305 | .Mul => switch (scalar_ty.zigTypeTag(mod)) { | 9416 | .Mul => switch (scalar_ty.zigTypeTag(mod)) { |
| 9306 | .Int => return self.builder.buildMulReduce(operand), | 9417 | .Int => return self.builder.buildMulReduce(operand), |
| 9307 | .Float => if (intrinsicsAllowed(scalar_ty, target)) { | 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 | const neutral_value = scalar_llvm_ty.constReal(1.0); | 9420 | const neutral_value = scalar_llvm_ty.constReal(1.0); |
| 9310 | return self.builder.buildFPMulReduce(neutral_value, operand); | 9421 | return self.builder.buildFPMulReduce(neutral_value, operand); |
| 9311 | }, | 9422 | }, |
| ... | @@ -9333,9 +9444,9 @@ pub const FuncGen = struct { | ... | @@ -9333,9 +9444,9 @@ pub const FuncGen = struct { |
| 9333 | else => unreachable, | 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 | const param_types = [2]*llvm.Type{ param_llvm_ty, param_llvm_ty }; | 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 | const init_value = try o.lowerValue(.{ | 9450 | const init_value = try o.lowerValue(.{ |
| 9340 | .ty = scalar_ty, | 9451 | .ty = scalar_ty, |
| 9341 | .val = try mod.floatValue(scalar_ty, switch (reduce.operation) { | 9452 | .val = try mod.floatValue(scalar_ty, switch (reduce.operation) { |
| ... | @@ -9356,7 +9467,7 @@ pub const FuncGen = struct { | ... | @@ -9356,7 +9467,7 @@ pub const FuncGen = struct { |
| 9356 | const result_ty = self.typeOfIndex(inst); | 9467 | const result_ty = self.typeOfIndex(inst); |
| 9357 | const len = @as(usize, @intCast(result_ty.arrayLen(mod))); | 9468 | const len = @as(usize, @intCast(result_ty.arrayLen(mod))); |
| 9358 | const elements = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[ty_pl.payload..][0..len])); | 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 | switch (result_ty.zigTypeTag(mod)) { | 9472 | switch (result_ty.zigTypeTag(mod)) { |
| 9362 | .Vector => { | 9473 | .Vector => { |
| ... | @@ -9444,7 +9555,7 @@ pub const FuncGen = struct { | ... | @@ -9444,7 +9555,7 @@ pub const FuncGen = struct { |
| 9444 | .Array => { | 9555 | .Array => { |
| 9445 | assert(isByRef(result_ty, mod)); | 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 | const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod)); | 9559 | const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod)); |
| 9449 | | 9560 | |
| 9450 | const array_info = result_ty.arrayInfo(mod); | 9561 | const array_info = result_ty.arrayInfo(mod); |
| ... | @@ -9487,7 +9598,7 @@ pub const FuncGen = struct { | ... | @@ -9487,7 +9598,7 @@ pub const FuncGen = struct { |
| 9487 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 9598 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 9488 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; | 9599 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| 9489 | const union_ty = self.typeOfIndex(inst); | 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 | const layout = union_ty.unionGetLayout(mod); | 9602 | const layout = union_ty.unionGetLayout(mod); |
| 9492 | const union_obj = mod.typeToUnion(union_ty).?; | 9603 | const union_obj = mod.typeToUnion(union_ty).?; |
| 9493 | | 9604 | |
| ... | @@ -9529,7 +9640,7 @@ pub const FuncGen = struct { | ... | @@ -9529,7 +9640,7 @@ pub const FuncGen = struct { |
| 9529 | const llvm_payload = try self.resolveInst(extra.init); | 9640 | const llvm_payload = try self.resolveInst(extra.init); |
| 9530 | assert(union_obj.haveFieldTypes()); | 9641 | assert(union_obj.haveFieldTypes()); |
| 9531 | const field = union_obj.fields.values()[extra.field_index]; | 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 | const field_size = field.ty.abiSize(mod); | 9644 | const field_size = field.ty.abiSize(mod); |
| 9534 | const field_align = field.normalAlignment(mod); | 9645 | const field_align = field.normalAlignment(mod); |
| 9535 | | 9646 | |
| ... | @@ -9552,7 +9663,7 @@ pub const FuncGen = struct { | ... | @@ -9552,7 +9663,7 @@ pub const FuncGen = struct { |
| 9552 | const fields: [1]*llvm.Type = .{payload}; | 9663 | const fields: [1]*llvm.Type = .{payload}; |
| 9553 | break :t self.context.structType(&fields, fields.len, .False); | 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 | var fields: [3]*llvm.Type = undefined; | 9667 | var fields: [3]*llvm.Type = undefined; |
| 9557 | var fields_len: c_uint = 2; | 9668 | var fields_len: c_uint = 2; |
| 9558 | if (layout.tag_align >= layout.payload_align) { | 9669 | if (layout.tag_align >= layout.payload_align) { |
| ... | @@ -9605,7 +9716,7 @@ pub const FuncGen = struct { | ... | @@ -9605,7 +9716,7 @@ pub const FuncGen = struct { |
| 9605 | index_type.constInt(@intFromBool(layout.tag_align < layout.payload_align), .False), | 9716 | index_type.constInt(@intFromBool(layout.tag_align < layout.payload_align), .False), |
| 9606 | }; | 9717 | }; |
| 9607 | const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, indices.len, ""); | 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 | const llvm_tag = tag_llvm_ty.constInt(tag_int, .False); | 9720 | const llvm_tag = tag_llvm_ty.constInt(tag_int, .False); |
| 9610 | const store_inst = self.builder.buildStore(llvm_tag, field_ptr); | 9721 | const store_inst = self.builder.buildStore(llvm_tag, field_ptr); |
| 9611 | store_inst.setAlignment(union_obj.tag_ty.abiAlignment(mod)); | 9722 | store_inst.setAlignment(union_obj.tag_ty.abiAlignment(mod)); |
| ... | @@ -9687,7 +9798,7 @@ pub const FuncGen = struct { | ... | @@ -9687,7 +9798,7 @@ pub const FuncGen = struct { |
| 9687 | const inst_ty = self.typeOfIndex(inst); | 9798 | const inst_ty = self.typeOfIndex(inst); |
| 9688 | const operand = try self.resolveInst(ty_op.operand); | 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 | return self.builder.buildAddrSpaceCast(operand, llvm_dest_ty, ""); | 9802 | return self.builder.buildAddrSpaceCast(operand, llvm_dest_ty, ""); |
| 9692 | } | 9803 | } |
| 9693 | | 9804 | |
| ... | @@ -9821,7 +9932,7 @@ pub const FuncGen = struct { | ... | @@ -9821,7 +9932,7 @@ pub const FuncGen = struct { |
| 9821 | | 9932 | |
| 9822 | return fg.loadByRef(payload_ptr, payload_ty, payload_alignment, false); | 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 | const load_inst = fg.builder.buildLoad(payload_llvm_ty, payload_ptr, ""); | 9936 | const load_inst = fg.builder.buildLoad(payload_llvm_ty, payload_ptr, ""); |
| 9826 | load_inst.setAlignment(payload_alignment); | 9937 | load_inst.setAlignment(payload_alignment); |
| 9827 | return load_inst; | 9938 | return load_inst; |
| ... | @@ -9838,7 +9949,7 @@ pub const FuncGen = struct { | ... | @@ -9838,7 +9949,7 @@ pub const FuncGen = struct { |
| 9838 | non_null_bit: *llvm.Value, | 9949 | non_null_bit: *llvm.Value, |
| 9839 | ) !?*llvm.Value { | 9950 | ) !?*llvm.Value { |
| 9840 | const o = self.dg.object; | 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 | const non_null_field = self.builder.buildZExt(non_null_bit, self.context.intType(8), ""); | 9953 | const non_null_field = self.builder.buildZExt(non_null_bit, self.context.intType(8), ""); |
| 9843 | const mod = o.module; | 9954 | const mod = o.module; |
| 9844 | | 9955 | |
| ... | @@ -9893,7 +10004,7 @@ pub const FuncGen = struct { | ... | @@ -9893,7 +10004,7 @@ pub const FuncGen = struct { |
| 9893 | const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, mod); | 10004 | const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, mod); |
| 9894 | if (byte_offset == 0) return struct_ptr; | 10005 | if (byte_offset == 0) return struct_ptr; |
| 9895 | const byte_llvm_ty = self.context.intType(8); | 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 | const llvm_index = llvm_usize.constInt(byte_offset, .False); | 10008 | const llvm_index = llvm_usize.constInt(byte_offset, .False); |
| 9898 | const indices: [1]*llvm.Value = .{llvm_index}; | 10009 | const indices: [1]*llvm.Value = .{llvm_index}; |
| 9899 | return self.builder.buildInBoundsGEP(byte_llvm_ty, struct_ptr, &indices, indices.len, ""); | 10010 | return self.builder.buildInBoundsGEP(byte_llvm_ty, struct_ptr, &indices, indices.len, ""); |
| ... | @@ -9919,7 +10030,7 @@ pub const FuncGen = struct { | ... | @@ -9919,7 +10030,7 @@ pub const FuncGen = struct { |
| 9919 | const layout = struct_ty.unionGetLayout(mod); | 10030 | const layout = struct_ty.unionGetLayout(mod); |
| 9920 | if (layout.payload_size == 0 or struct_ty.containerLayout(mod) == .Packed) return struct_ptr; | 10031 | if (layout.payload_size == 0 or struct_ty.containerLayout(mod) == .Packed) return struct_ptr; |
| 9921 | const payload_index = @intFromBool(layout.tag_align >= layout.payload_align); | 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 | const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_ptr, payload_index, ""); | 10034 | const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_ptr, payload_index, ""); |
| 9924 | return union_field_ptr; | 10035 | return union_field_ptr; |
| 9925 | }, | 10036 | }, |
| ... | @@ -9944,7 +10055,7 @@ pub const FuncGen = struct { | ... | @@ -9944,7 +10055,7 @@ pub const FuncGen = struct { |
| 9944 | ) !*llvm.Value { | 10055 | ) !*llvm.Value { |
| 9945 | const o = fg.dg.object; | 10056 | const o = fg.dg.object; |
| 9946 | const mod = o.module; | 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 | const result_align = @max(ptr_alignment, pointee_type.abiAlignment(mod)); | 10059 | const result_align = @max(ptr_alignment, pointee_type.abiAlignment(mod)); |
| 9949 | const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align); | 10060 | const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align); |
| 9950 | const llvm_usize = fg.context.intType(Type.usize.intInfo(mod).bits); | 10061 | const llvm_usize = fg.context.intType(Type.usize.intInfo(mod).bits); |
| ... | @@ -9977,7 +10088,7 @@ pub const FuncGen = struct { | ... | @@ -9977,7 +10088,7 @@ pub const FuncGen = struct { |
| 9977 | assert(info.flags.vector_index != .runtime); | 10088 | assert(info.flags.vector_index != .runtime); |
| 9978 | if (info.flags.vector_index != .none) { | 10089 | if (info.flags.vector_index != .none) { |
| 9979 | const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False); | 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 | const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size); | 10092 | const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size); |
| 9982 | | 10093 | |
| 9983 | const loaded_vector = self.builder.buildLoad(vec_ty, ptr, ""); | 10094 | const loaded_vector = self.builder.buildLoad(vec_ty, ptr, ""); |
| ... | @@ -9991,7 +10102,7 @@ pub const FuncGen = struct { | ... | @@ -9991,7 +10102,7 @@ pub const FuncGen = struct { |
| 9991 | if (isByRef(elem_ty, mod)) { | 10102 | if (isByRef(elem_ty, mod)) { |
| 9992 | return self.loadByRef(ptr, elem_ty, ptr_alignment, info.flags.is_volatile); | 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 | const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, ""); | 10106 | const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, ""); |
| 9996 | llvm_inst.setAlignment(ptr_alignment); | 10107 | llvm_inst.setAlignment(ptr_alignment); |
| 9997 | llvm_inst.setVolatile(ptr_volatile); | 10108 | llvm_inst.setVolatile(ptr_volatile); |
| ... | @@ -10006,7 +10117,7 @@ pub const FuncGen = struct { | ... | @@ -10006,7 +10117,7 @@ pub const FuncGen = struct { |
| 10006 | const elem_bits = @as(c_uint, @intCast(ptr_ty.childType(mod).bitSize(mod))); | 10117 | const elem_bits = @as(c_uint, @intCast(ptr_ty.childType(mod).bitSize(mod))); |
| 10007 | const shift_amt = containing_int.typeOf().constInt(info.packed_offset.bit_offset, .False); | 10118 | const shift_amt = containing_int.typeOf().constInt(info.packed_offset.bit_offset, .False); |
| 10008 | const shifted_value = self.builder.buildLShr(containing_int, shift_amt, ""); | 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 | if (isByRef(elem_ty, mod)) { | 10122 | if (isByRef(elem_ty, mod)) { |
| 10012 | const result_align = elem_ty.abiAlignment(mod); | 10123 | const result_align = elem_ty.abiAlignment(mod); |
| ... | @@ -10054,7 +10165,7 @@ pub const FuncGen = struct { | ... | @@ -10054,7 +10165,7 @@ pub const FuncGen = struct { |
| 10054 | assert(info.flags.vector_index != .runtime); | 10165 | assert(info.flags.vector_index != .runtime); |
| 10055 | if (info.flags.vector_index != .none) { | 10166 | if (info.flags.vector_index != .none) { |
| 10056 | const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False); | 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 | const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size); | 10169 | const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size); |
| 10059 | | 10170 | |
| 10060 | const loaded_vector = self.builder.buildLoad(vec_ty, ptr, ""); | 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,7 +10813,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { |
| 10702 | // anyerror return type instead, so that it can be coerced into a function | 10813 | // anyerror return type instead, so that it can be coerced into a function |
| 10703 | // pointer type which has anyerror as the return type. | 10814 | // pointer type which has anyerror as the return type. |
| 10704 | if (return_type.isError(mod)) { | 10815 | if (return_type.isError(mod)) { |
| 10705 | return o.lowerType(Type.anyerror); | 10816 | return o.lowerLlvmType(Type.anyerror); |
| 10706 | } else { | 10817 | } else { |
| 10707 | return o.context.voidType(); | 10818 | return o.context.voidType(); |
| 10708 | } | 10819 | } |
| ... | @@ -10713,19 +10824,19 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { | ... | @@ -10713,19 +10824,19 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { |
| 10713 | if (isByRef(return_type, mod)) { | 10824 | if (isByRef(return_type, mod)) { |
| 10714 | return o.context.voidType(); | 10825 | return o.context.voidType(); |
| 10715 | } else { | 10826 | } else { |
| 10716 | return o.lowerType(return_type); | 10827 | return o.lowerLlvmType(return_type); |
| 10717 | } | 10828 | } |
| 10718 | }, | 10829 | }, |
| 10719 | .C => { | 10830 | .C => { |
| 10720 | switch (target.cpu.arch) { | 10831 | switch (target.cpu.arch) { |
| 10721 | .mips, .mipsel => return o.lowerType(return_type), | 10832 | .mips, .mipsel => return o.lowerLlvmType(return_type), |
| 10722 | .x86_64 => switch (target.os.tag) { | 10833 | .x86_64 => switch (target.os.tag) { |
| 10723 | .windows => return lowerWin64FnRetTy(o, fn_info), | 10834 | .windows => return lowerWin64FnRetTy(o, fn_info), |
| 10724 | else => return lowerSystemVFnRetTy(o, fn_info), | 10835 | else => return lowerSystemVFnRetTy(o, fn_info), |
| 10725 | }, | 10836 | }, |
| 10726 | .wasm32 => { | 10837 | .wasm32 => { |
| 10727 | if (isScalar(mod, return_type)) { | 10838 | if (isScalar(mod, return_type)) { |
| 10728 | return o.lowerType(return_type); | 10839 | return o.lowerLlvmType(return_type); |
| 10729 | } | 10840 | } |
| 10730 | const classes = wasm_c_abi.classifyType(return_type, mod); | 10841 | const classes = wasm_c_abi.classifyType(return_type, mod); |
| 10731 | if (classes[0] == .indirect or classes[0] == .none) { | 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,8 +10851,8 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { |
| 10740 | .aarch64, .aarch64_be => { | 10851 | .aarch64, .aarch64_be => { |
| 10741 | switch (aarch64_c_abi.classifyType(return_type, mod)) { | 10852 | switch (aarch64_c_abi.classifyType(return_type, mod)) { |
| 10742 | .memory => return o.context.voidType(), | 10853 | .memory => return o.context.voidType(), |
| 10743 | .float_array => return o.lowerType(return_type), | 10854 | .float_array => return o.lowerLlvmType(return_type), |
| 10744 | .byval => return o.lowerType(return_type), | 10855 | .byval => return o.lowerLlvmType(return_type), |
| 10745 | .integer => { | 10856 | .integer => { |
| 10746 | const bit_size = return_type.bitSize(mod); | 10857 | const bit_size = return_type.bitSize(mod); |
| 10747 | return o.context.intType(@as(c_uint, @intCast(bit_size))); | 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,7 +10868,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { |
| 10757 | } else { | 10868 | } else { |
| 10758 | return o.context.voidType(); | 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 | .riscv32, .riscv64 => { | 10874 | .riscv32, .riscv64 => { |
| ... | @@ -10774,23 +10885,23 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { | ... | @@ -10774,23 +10885,23 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { |
| 10774 | }; | 10885 | }; |
| 10775 | return o.context.structType(&llvm_types_buffer, 2, .False); | 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 | // TODO investigate C ABI for other architectures | 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 | .Win64 => return lowerWin64FnRetTy(o, fn_info), | 10895 | .Win64 => return lowerWin64FnRetTy(o, fn_info), |
| 10785 | .SysV => return lowerSystemVFnRetTy(o, fn_info), | 10896 | .SysV => return lowerSystemVFnRetTy(o, fn_info), |
| 10786 | .Stdcall => { | 10897 | .Stdcall => { |
| 10787 | if (isScalar(mod, return_type)) { | 10898 | if (isScalar(mod, return_type)) { |
| 10788 | return o.lowerType(return_type); | 10899 | return o.lowerLlvmType(return_type); |
| 10789 | } else { | 10900 | } else { |
| 10790 | return o.context.voidType(); | 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,7 +10911,7 @@ fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { |
| 10800 | switch (x86_64_abi.classifyWindows(return_type, mod)) { | 10911 | switch (x86_64_abi.classifyWindows(return_type, mod)) { |
| 10801 | .integer => { | 10912 | .integer => { |
| 10802 | if (isScalar(mod, return_type)) { | 10913 | if (isScalar(mod, return_type)) { |
| 10803 | return o.lowerType(return_type); | 10914 | return o.lowerLlvmType(return_type); |
| 10804 | } else { | 10915 | } else { |
| 10805 | const abi_size = return_type.abiSize(mod); | 10916 | const abi_size = return_type.abiSize(mod); |
| 10806 | return o.context.intType(@as(c_uint, @intCast(abi_size * 8))); | 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,7 +10919,7 @@ fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type { |
| 10808 | }, | 10919 | }, |
| 10809 | .win_i128 => return o.context.intType(64).vectorType(2), | 10920 | .win_i128 => return o.context.intType(64).vectorType(2), |
| 10810 | .memory => return o.context.voidType(), | 10921 | .memory => return o.context.voidType(), |
| 10811 | .sse => return o.lowerType(return_type), | 10922 | .sse => return o.lowerLlvmType(return_type), |
| 10812 | else => unreachable, | 10923 | else => unreachable, |
| 10813 | } | 10924 | } |
| 10814 | } | 10925 | } |
| ... | @@ -10817,7 +10928,7 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type | ... | @@ -10817,7 +10928,7 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type |
| 10817 | const mod = o.module; | 10928 | const mod = o.module; |
| 10818 | const return_type = fn_info.return_type.toType(); | 10929 | const return_type = fn_info.return_type.toType(); |
| 10819 | if (isScalar(mod, return_type)) { | 10930 | if (isScalar(mod, return_type)) { |
| 10820 | return o.lowerType(return_type); | 10931 | return o.lowerLlvmType(return_type); |
| 10821 | } | 10932 | } |
| 10822 | const classes = x86_64_abi.classifySystemV(return_type, mod, .ret); | 10933 | const classes = x86_64_abi.classifySystemV(return_type, mod, .ret); |
| 10823 | if (classes[0] == .memory) { | 10934 | if (classes[0] == .memory) { |
| ... | @@ -10847,7 +10958,7 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type | ... | @@ -10847,7 +10958,7 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type |
| 10847 | if (llvm_types_index != 0 or classes[2] != .none) { | 10958 | if (llvm_types_index != 0 or classes[2] != .none) { |
| 10848 | return o.context.voidType(); | 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 | llvm_types_index += 1; | 10962 | llvm_types_index += 1; |
| 10852 | }, | 10963 | }, |
| 10853 | .x87up => continue, | 10964 | .x87up => continue, |