authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-06 02:52:25-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-19 23:38:40-04:00
logd195173ba2c06b56c1bf5554ebf0736795798c91
treee358fa6f170400ce6a07ba00a032548a4f1263e8
parent996eb01746498e0ec5e162ed40d1f3c913891150

llvm: start tracking more things without relying on the llvm api


6 files changed, 1324 insertions(+), 331 deletions(-)

src/Compilation.zig+5-1
...@@ -538,6 +538,7 @@ pub const InitOptions = struct {...@@ -538,6 +538,7 @@ pub const InitOptions = struct {
538 want_lto: ?bool = null,538 want_lto: ?bool = null,
539 want_unwind_tables: ?bool = null,539 want_unwind_tables: ?bool = null,
540 use_llvm: ?bool = null,540 use_llvm: ?bool = null,
541 use_lib_llvm: ?bool = null,
541 use_lld: ?bool = null,542 use_lld: ?bool = null,
542 use_clang: ?bool = null,543 use_clang: ?bool = null,
543 single_threaded: ?bool = null,544 single_threaded: ?bool = null,
...@@ -753,7 +754,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -753,7 +754,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
753 const root_name = try arena.dupeZ(u8, options.root_name);754 const root_name = try arena.dupeZ(u8, options.root_name);
754755
755 // Make a decision on whether to use LLVM or our own backend.756 // Make a decision on whether to use LLVM or our own backend.
756 const use_llvm = build_options.have_llvm and blk: {757 const use_lib_llvm = options.use_lib_llvm orelse build_options.have_llvm;
758 const use_llvm = blk: {
757 if (options.use_llvm) |explicit|759 if (options.use_llvm) |explicit|
758 break :blk explicit;760 break :blk explicit;
759761
...@@ -1161,6 +1163,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1161,6 +1163,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1161 hash.add(valgrind);1163 hash.add(valgrind);
1162 hash.add(single_threaded);1164 hash.add(single_threaded);
1163 hash.add(use_llvm);1165 hash.add(use_llvm);
1166 hash.add(use_lib_llvm);
1164 hash.add(dll_export_fns);1167 hash.add(dll_export_fns);
1165 hash.add(options.is_test);1168 hash.add(options.is_test);
1166 hash.add(options.test_evented_io);1169 hash.add(options.test_evented_io);
...@@ -1444,6 +1447,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1444,6 +1447,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1444 .optimize_mode = options.optimize_mode,1447 .optimize_mode = options.optimize_mode,
1445 .use_lld = use_lld,1448 .use_lld = use_lld,
1446 .use_llvm = use_llvm,1449 .use_llvm = use_llvm,
1450 .use_lib_llvm = use_lib_llvm,
1447 .link_libc = link_libc,1451 .link_libc = link_libc,
1448 .link_libcpp = link_libcpp,1452 .link_libcpp = link_libcpp,
1449 .link_libunwind = link_libunwind,1453 .link_libunwind = link_libunwind,
src/codegen/llvm.zig+438-327
...@@ -7,6 +7,7 @@ const math = std.math;...@@ -7,6 +7,7 @@ const math = std.math;
7const native_endian = builtin.cpu.arch.endian();7const native_endian = builtin.cpu.arch.endian();
8const DW = std.dwarf;8const DW = std.dwarf;
99
10const Builder = @import("llvm/Builder.zig");
10const llvm = @import("llvm/bindings.zig");11const llvm = @import("llvm/bindings.zig");
11const link = @import("../link.zig");12const link = @import("../link.zig");
12const Compilation = @import("../Compilation.zig");13const 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 {
338339
339pub const Object = struct {340pub 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 of368 /// 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 }
395398
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();
399408
400 initializeLLVMTarget(options.target.cpu.arch);409 initializeLLVMTarget(options.target.cpu.arch);
401410
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();
404413
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 }
416425
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();
420429
...@@ -422,10 +431,10 @@ pub const Object = struct {...@@ -422,10 +431,10 @@ pub const Object = struct {
422431
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;
430439
431 // Don't use the version string here; LLVM misparses it when it440 // 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();
510519
511 llvm_module.setModuleDataLayout(target_data);520 builder.llvm_module.setModuleDataLayout(target_data);
512521
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);
516525
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 }
520529
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 }
558579
...@@ -671,34 +692,36 @@ pub const Object = struct {...@@ -671,34 +692,36 @@ pub const Object = struct {
671692
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;
680702
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();
686708
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 such713 // 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;
695716
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;
698720
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 that725 // Problem: now we need to replace in the decl_map that
703 // the extern decl index points to this new global. However we don't726 // 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 });
815838
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 };
886915
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);
888919
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 {
932963
933 const builder = o.context.createBuilder();964 const builder = o.context.createBuilder();
934965
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);
937969
...@@ -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);
9941026
...@@ -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);
10131045
...@@ -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;
10321064
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;
10771109
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;
11211153
...@@ -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;
11391171
...@@ -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 }
12451277
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 call1285 // 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);
12691293
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 }
12801301
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);
12841304
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 }
13871416
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 }
13921421
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 has2489 /// 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;
24692498
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);
24742503
2475 const fn_type = try o.lowerType(zig_fn_type);2504 const fn_type = try o.lowerLlvmType(zig_fn_type);
24762505
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)));
24792508
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 };
24832519
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 02536 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");
25022538
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 }
25062542
...@@ -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 }
25782614
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 }
25812620
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 }
26242663
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));
26292668
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 ));
26332674
2634 const target = mod.getTarget();2675 const target = mod.getTarget();
26352676
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);
26382679
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;
26452698
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 }
26642725
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 }
26672731
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 type2733 // 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 means2734 // 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 possible2735 // 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 }
26762740
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 }
26952763
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);
27252793
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);
27902858
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);
28602928
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 {
28862954
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 }
28932961
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);
28952966
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 calls2968 gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
28982969
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);
29293000
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 }
29633034
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 calls3044 gop.value_ptr.* = llvm_union_ty; // must be done before any recursive calls
29743045
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);
29773048
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);
29993070
3000 // Put the tag before or after the payload depending on which one's3071 // 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 }
30323103
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 }
30523133
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 else3153 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);
30763157
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 }
31083189
3109 /// Use this instead of lowerType when you want to handle correctly the case of elem_ty3190 /// 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 else3203 else
3123 o.context.intType(8);3204 o.context.intType(8);
31243205
...@@ -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 }
31413222
...@@ -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 values3250 => 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;
32323315
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);
35403623
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);
38333916
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 }
38903973
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);
39504033
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 else4036 else
3954 try o.resolveGlobalDecl(decl_index);4037 (try o.resolveGlobalDecl(decl_index)).toLlvm(&o.builder);
39554038
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;
39634046
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` annotation4059 // The value cannot be undefined, because we use the `nonnull` annotation
3977 // for non-optional pointers. We also need to respect the alignment, even though4060 // 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 must4266 // 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 }
42104299
...@@ -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 );
42254314
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();
46194708
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);
46694758
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 }
47614850
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);
47644853
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 };
47894878
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 }
48644953
4865 const llvm_ret_ty = try o.lowerType(return_type);4954 const llvm_ret_ty = try o.lowerLlvmType(return_type);
48664955
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 code5057 // Functions with an empty error set are emitted with an error code
4969 // return type and return zero so they can be function pointers coerced5058 // 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 code5105 // Functions with an empty error set are emitted with an error code
5017 // return type and return zero so they can be function pointers coerced5106 // 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);
50445133
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;
50555144
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);
51025191
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/inequality5266 // 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;
52895378
5290 const raw_llvm_ty = try o.lowerType(inst_ty);5379 const raw_llvm_ty = try o.lowerLlvmType(inst_ty);
52915380
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; not5382 // 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);
53965485
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 load5491 // 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 {
55595648
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();
55645653
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 }
56025691
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};
56055694
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 {
56205709
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);
56245713
5625 if (intrinsicsAllowed(operand_scalar_ty, target)) {5714 if (intrinsicsAllowed(operand_scalar_ty, target)) {
5626 // TODO set fast math flag5715 // 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;
56545743
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};
56595748
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 {
57735862
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);
59936082
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 }
62796368
...@@ -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();
66076696
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 {
66166705
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 else6709 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);
66266715
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 }
66576746
...@@ -6677,7 +6766,7 @@ pub const FuncGen = struct {...@@ -6677,7 +6766,7 @@ pub const FuncGen = struct {
6677 }6766 }
66786767
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 store6771 // 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 }
67066795
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 }
67686857
6769 const err_set_llvm_ty = try o.lowerType(Type.anyerror);6858 const err_set_llvm_ty = try o.lowerLlvmType(Type.anyerror);
67706859
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);
67786867
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 {
68346923
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);
68876976
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);
69167005
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);
69697058
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);
70167105
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);
72377326
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);
73007389
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);
73147403
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 {
74087497
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;
74107499
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);
74137502
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);
75017605
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 {
75287632
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);
75327636
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);
76057709
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);
77127816
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);
77157819
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 else7822 else
7719 rhs;7823 rhs;
77207824
...@@ -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);
77867890
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 else7893 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);
78077911
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 else7914 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 produce7946 // 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);
78717975
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 else7978 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 }
79238027
...@@ -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);
79348038
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);
79418045
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 {
79468050
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);
79508054
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);
79658069
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);
79728076
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 {
79778081
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);
79818085
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 }
79958099
...@@ -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);
80108114
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);
81818285
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 }
81978301
...@@ -8223,7 +8327,7 @@ pub const FuncGen = struct {...@@ -8223,7 +8327,7 @@ pub const FuncGen = struct {
8223 else8327 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/119468406 // https://github.com/ziglang/zig/issues/11946
...@@ -8324,7 +8428,7 @@ pub const FuncGen = struct {...@@ -8324,7 +8428,7 @@ pub const FuncGen = struct {
83248428
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 }
83308434
...@@ -8370,7 +8474,7 @@ pub const FuncGen = struct {...@@ -8370,7 +8474,7 @@ pub const FuncGen = struct {
83708474
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, "");
83768480
...@@ -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 }
84298533
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 }
84438547
...@@ -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() orelse8560 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);
84608564
8461 if (opt_abi_llvm_ty) |abi_llvm_ty| {8565 if (opt_abi_llvm_ty) |abi_llvm_ty| {
8462 // operand needs widening and truncating8566 // 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 store8841 // 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);
87918895
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});
87958899
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);
88008904
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);
88188922
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});
88228926
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);
88268930
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);
88458949
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);
88488952
8849 if (bits % 16 == 8) {8953 if (bits % 16 == 8) {
8850 // If not an even byte-multiple, we need zero-extend + shift-left 1 byte8954 // 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, "");
88798983
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)});
89599063
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())};
89619065
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 {
90209124
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));
90259129
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)});
90329132
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);
90379137
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())};
90399139
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 };
90469153
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 {
91049211
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 }
91099220
...@@ -9116,8 +9227,8 @@ pub const FuncGen = struct {...@@ -9116,8 +9227,8 @@ pub const FuncGen = struct {
91169227
9117 // Function signature: fn (anyerror) bool9228 // Function signature: fn (anyerror) bool
91189229
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};
91229233
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);
91379248
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();
92259336
...@@ -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 };
93359446
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);
93609471
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));
94469557
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));
94499560
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).?;
94939604
...@@ -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);
95359646
...@@ -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);
96899800
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 }
96939804
...@@ -9821,7 +9932,7 @@ pub const FuncGen = struct {...@@ -9821,7 +9932,7 @@ pub const FuncGen = struct {
98219932
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;
98449955
...@@ -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);
998210093
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);
1001010121
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);
1005910170
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 function10813 // 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 architectures10891 // 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}
1079610907
...@@ -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,
src/codegen/llvm/Builder.zig created+845
...@@ -0,0 +1,845 @@
1gpa: Allocator,
2use_lib_llvm: bool,
3
4llvm_context: *llvm.Context,
5llvm_module: *llvm.Module,
6di_builder: ?*llvm.DIBuilder = null,
7llvm_types: std.ArrayListUnmanaged(*llvm.Type) = .{},
8llvm_globals: std.ArrayListUnmanaged(*llvm.Value) = .{},
9
10source_filename: String = .none,
11data_layout: String = .none,
12target_triple: String = .none,
13
14string_map: std.AutoArrayHashMapUnmanaged(void, void) = .{},
15string_bytes: std.ArrayListUnmanaged(u8) = .{},
16string_indices: std.ArrayListUnmanaged(u32) = .{},
17
18types: std.AutoArrayHashMapUnmanaged(String, Type) = .{},
19next_unnamed_type: String = @enumFromInt(0),
20type_map: std.AutoArrayHashMapUnmanaged(void, void) = .{},
21type_data: std.ArrayListUnmanaged(Type.Data) = .{},
22type_extra: std.ArrayListUnmanaged(u32) = .{},
23
24globals: std.AutoArrayHashMapUnmanaged(String, Global) = .{},
25next_unnamed_global: String = @enumFromInt(0),
26next_unique_global_id: std.AutoHashMapUnmanaged(String, u32) = .{},
27aliases: std.ArrayListUnmanaged(Alias) = .{},
28objects: std.ArrayListUnmanaged(Object) = .{},
29functions: std.ArrayListUnmanaged(Function) = .{},
30
31pub const String = enum(u32) {
32 none = std.math.maxInt(u31),
33 empty,
34 debugme,
35 _,
36
37 pub fn toSlice(self: String, b: *const Builder) ?[:0]const u8 {
38 const index = self.toIndex() orelse return null;
39 const start = b.string_indices.items[index];
40 const end = b.string_indices.items[index + 1];
41 return b.string_bytes.items[start .. end - 1 :0];
42 }
43
44 const FormatData = struct {
45 string: String,
46 builder: *const Builder,
47 };
48 fn format(
49 data: FormatData,
50 comptime fmt_str: []const u8,
51 _: std.fmt.FormatOptions,
52 writer: anytype,
53 ) @TypeOf(writer).Error!void {
54 assert(data.string != .none);
55 const slice = data.string.toSlice(data.builder) orelse
56 return writer.print("{d}", .{@intFromEnum(data.string)});
57 const need_quotes = if (comptime std.mem.eql(u8, fmt_str, ""))
58 !isValidIdentifier(slice)
59 else if (comptime std.mem.eql(u8, fmt_str, "\""))
60 true
61 else
62 @compileError("invalid format string: '" ++ fmt_str ++ "'");
63 if (need_quotes) try writer.writeByte('\"');
64 for (slice) |c| switch (c) {
65 '\\' => try writer.writeAll("\\\\"),
66 ' '...'"' - 1, '"' + 1...'\\' - 1, '\\' + 1...'~' => try writer.writeByte(c),
67 else => try writer.print("\\{X:0>2}", .{c}),
68 };
69 if (need_quotes) try writer.writeByte('\"');
70 }
71 pub fn fmt(self: String, builder: *const Builder) std.fmt.Formatter(format) {
72 return .{ .data = .{ .string = self, .builder = builder } };
73 }
74
75 fn fromIndex(index: ?usize) String {
76 return @enumFromInt(@as(u32, @intCast((index orelse return .none) +
77 @intFromEnum(String.empty))));
78 }
79 fn toIndex(self: String) ?usize {
80 return std.math.sub(u32, @intFromEnum(self), @intFromEnum(String.empty)) catch null;
81 }
82
83 const Adapter = struct {
84 builder: *const Builder,
85 pub fn hash(_: Adapter, key: []const u8) u32 {
86 return @truncate(std.hash.Wyhash.hash(0, key));
87 }
88 pub fn eql(ctx: Adapter, lhs: []const u8, _: void, rhs_index: usize) bool {
89 return std.mem.eql(u8, lhs, String.fromIndex(rhs_index).toSlice(ctx.builder).?);
90 }
91 };
92};
93
94pub const Type = enum(u32) {
95 void,
96 half,
97 bfloat,
98 float,
99 double,
100 fp128,
101 x86_fp80,
102 ppc_fp128,
103 x86_amx,
104 x86_mmx,
105 label,
106 token,
107 metadata,
108
109 i1,
110 i8,
111 i16,
112 i32,
113 i64,
114 i128,
115 ptr,
116
117 none = std.math.maxInt(u32),
118 _,
119
120 const Tag = enum(u4) {
121 simple,
122 function,
123 integer,
124 pointer,
125 target,
126 vector,
127 vscale_vector,
128 array,
129 structure,
130 packed_structure,
131 named_structure,
132 };
133
134 const Simple = enum {
135 void,
136 half,
137 bfloat,
138 float,
139 double,
140 fp128,
141 x86_fp80,
142 ppc_fp128,
143 x86_amx,
144 x86_mmx,
145 label,
146 token,
147 metadata,
148 };
149
150 const NamedStructure = struct {
151 id: String,
152 child: Type,
153 };
154
155 const Data = packed struct(u32) {
156 tag: Tag,
157 data: ExtraIndex,
158 };
159
160 const ExtraIndex = u28;
161
162 const FormatData = struct {
163 type: Type,
164 builder: *const Builder,
165 };
166 fn format(
167 data: FormatData,
168 comptime fmt_str: []const u8,
169 fmt_opts: std.fmt.FormatOptions,
170 writer: anytype,
171 ) @TypeOf(writer).Error!void {
172 assert(data.type != .none);
173 if (std.enums.tagName(Type, data.type)) |name| return writer.writeAll(name);
174 const type_data = data.builder.type_data.items[@intFromEnum(data.type)];
175 switch (type_data.tag) {
176 .named_structure => {
177 const extra = data.builder.typeExtraData(NamedStructure, type_data.data);
178 if (comptime std.mem.eql(u8, fmt_str, "")) try writer.print("%{}", .{
179 extra.id.fmt(data.builder),
180 }) else if (comptime std.mem.eql(u8, fmt_str, "+")) switch (extra.child) {
181 .none => try writer.writeAll("opaque"),
182 else => try format(.{
183 .type = extra.child,
184 .builder = data.builder,
185 }, fmt_str, fmt_opts, writer),
186 } else @compileError("invalid format string: '" ++ fmt_str ++ "'");
187 },
188 else => try writer.print("<type 0x{X}>", .{@intFromEnum(data.type)}),
189 }
190 }
191 pub fn fmt(self: Type, builder: *const Builder) std.fmt.Formatter(format) {
192 return .{ .data = .{ .type = self, .builder = builder } };
193 }
194};
195
196pub const Linkage = enum {
197 default,
198 private,
199 internal,
200 available_externally,
201 linkonce,
202 weak,
203 common,
204 appending,
205 extern_weak,
206 linkonce_odr,
207 weak_odr,
208 external,
209
210 pub fn format(
211 self: Linkage,
212 comptime _: []const u8,
213 _: std.fmt.FormatOptions,
214 writer: anytype,
215 ) @TypeOf(writer).Error!void {
216 if (self == .default) return;
217 try writer.writeAll(@tagName(self));
218 try writer.writeByte(' ');
219 }
220};
221
222pub const Preemption = enum {
223 none,
224 dso_preemptable,
225 dso_local,
226
227 pub fn format(
228 self: Preemption,
229 comptime _: []const u8,
230 _: std.fmt.FormatOptions,
231 writer: anytype,
232 ) @TypeOf(writer).Error!void {
233 if (self == .none) return;
234 try writer.writeAll(@tagName(self));
235 try writer.writeByte(' ');
236 }
237};
238
239pub const Visibility = enum {
240 default,
241 hidden,
242 protected,
243
244 pub fn format(
245 self: Visibility,
246 comptime _: []const u8,
247 _: std.fmt.FormatOptions,
248 writer: anytype,
249 ) @TypeOf(writer).Error!void {
250 if (self == .default) return;
251 try writer.writeAll(@tagName(self));
252 try writer.writeByte(' ');
253 }
254};
255
256pub const DllStorageClass = enum {
257 default,
258 dllimport,
259 dllexport,
260
261 pub fn format(
262 self: DllStorageClass,
263 comptime _: []const u8,
264 _: std.fmt.FormatOptions,
265 writer: anytype,
266 ) @TypeOf(writer).Error!void {
267 if (self == .default) return;
268 try writer.writeAll(@tagName(self));
269 try writer.writeByte(' ');
270 }
271};
272
273pub const ThreadLocal = enum {
274 none,
275 generaldynamic,
276 localdynamic,
277 initialexec,
278 localexec,
279
280 pub fn format(
281 self: ThreadLocal,
282 comptime _: []const u8,
283 _: std.fmt.FormatOptions,
284 writer: anytype,
285 ) @TypeOf(writer).Error!void {
286 if (self == .none) return;
287 try writer.writeAll("thread_local");
288 if (self != .generaldynamic) {
289 try writer.writeByte('(');
290 try writer.writeAll(@tagName(self));
291 try writer.writeByte(')');
292 }
293 try writer.writeByte(' ');
294 }
295};
296
297pub const UnnamedAddr = enum {
298 none,
299 unnamed_addr,
300 local_unnamed_addr,
301
302 pub fn format(
303 self: UnnamedAddr,
304 comptime _: []const u8,
305 _: std.fmt.FormatOptions,
306 writer: anytype,
307 ) @TypeOf(writer).Error!void {
308 if (self == .none) return;
309 try writer.writeAll(@tagName(self));
310 try writer.writeByte(' ');
311 }
312};
313
314pub const AddrSpace = enum(u24) {
315 none,
316 _,
317
318 pub fn format(
319 self: AddrSpace,
320 comptime _: []const u8,
321 _: std.fmt.FormatOptions,
322 writer: anytype,
323 ) @TypeOf(writer).Error!void {
324 if (self == .none) return;
325 try writer.print("addrspace({d}) ", .{@intFromEnum(self)});
326 }
327};
328
329pub const ExternallyInitialized = enum {
330 none,
331 externally_initialized,
332
333 pub fn format(
334 self: ExternallyInitialized,
335 comptime _: []const u8,
336 _: std.fmt.FormatOptions,
337 writer: anytype,
338 ) @TypeOf(writer).Error!void {
339 if (self == .none) return;
340 try writer.writeAll(@tagName(self));
341 try writer.writeByte(' ');
342 }
343};
344
345pub const Alignment = enum(u6) {
346 default = std.math.maxInt(u6),
347 _,
348
349 pub fn fromByteUnits(bytes: u64) Alignment {
350 if (bytes == 0) return .default;
351 assert(std.math.isPowerOfTwo(bytes));
352 assert(bytes <= 1 << 32);
353 return @enumFromInt(@ctz(bytes));
354 }
355
356 pub fn toByteUnits(self: Alignment) ?u64 {
357 return if (self == .default) null else @as(u64, 1) << @intFromEnum(self);
358 }
359
360 pub fn format(
361 self: Alignment,
362 comptime prefix: []const u8,
363 _: std.fmt.FormatOptions,
364 writer: anytype,
365 ) @TypeOf(writer).Error!void {
366 try writer.print("{s} align {d}", .{ prefix, self.toByteUnits() orelse return });
367 }
368};
369
370pub const Global = struct {
371 linkage: Linkage = .default,
372 preemption: Preemption = .none,
373 visibility: Visibility = .default,
374 dll_storage_class: DllStorageClass = .default,
375 unnamed_addr: UnnamedAddr = .none,
376 addr_space: AddrSpace = .none,
377 externally_initialized: ExternallyInitialized = .none,
378 type: Type,
379 alignment: Alignment = .default,
380 kind: union(enum) {
381 alias: Alias.Index,
382 object: Object.Index,
383 function: Function.Index,
384 },
385
386 pub const Index = enum(u32) {
387 _,
388
389 pub fn ptr(self: Index, builder: *Builder) *Global {
390 return &builder.globals.values()[@intFromEnum(self)];
391 }
392
393 pub fn ptrConst(self: Index, builder: *const Builder) *const Global {
394 return &builder.globals.values()[@intFromEnum(self)];
395 }
396
397 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
398 return builder.llvm_globals.items[@intFromEnum(self)];
399 }
400
401 pub fn rename(self: Index, builder: *Builder, name: String) Allocator.Error!void {
402 try builder.ensureUnusedCapacityGlobal(name);
403 self.renameAssumeCapacity(builder, name);
404 }
405
406 pub fn renameAssumeCapacity(self: Index, builder: *Builder, name: String) void {
407 const index = @intFromEnum(self);
408 if (builder.globals.keys()[index] == name) return;
409 if (builder.useLibLlvm()) builder.llvm_globals.appendAssumeCapacity(builder.llvm_globals.items[index]);
410 _ = builder.addGlobalAssumeCapacity(name, builder.globals.values()[index]);
411 if (builder.useLibLlvm()) _ = builder.llvm_globals.pop();
412 builder.globals.swapRemoveAt(index);
413 self.updateName(builder);
414 }
415
416 pub fn takeName(self: Index, builder: *Builder, other: Index) Allocator.Error!void {
417 try builder.ensureUnusedCapacityGlobal(.empty);
418 self.takeNameAssumeCapacity(builder, other);
419 }
420
421 pub fn takeNameAssumeCapacity(self: Index, builder: *Builder, other: Index) void {
422 const other_name = builder.globals.keys()[@intFromEnum(other)];
423 other.renameAssumeCapacity(builder, .none);
424 self.renameAssumeCapacity(builder, other_name);
425 }
426
427 fn updateName(self: Index, builder: *const Builder) void {
428 if (!builder.useLibLlvm()) return;
429 const index = @intFromEnum(self);
430 const slice = builder.globals.keys()[index].toSlice(builder) orelse "";
431 builder.llvm_globals.items[index].setValueName2(slice.ptr, slice.len);
432 }
433 };
434
435 fn deinit(self: *Global, _: Allocator) void {
436 self.* = undefined;
437 }
438};
439
440pub const Alias = struct {
441 global: Global.Index,
442
443 pub const Index = enum(u32) {
444 _,
445
446 pub fn ptr(self: Index, builder: *Builder) *Alias {
447 return &builder.aliases.items[@intFromEnum(self)];
448 }
449
450 pub fn ptrConst(self: Index, builder: *const Builder) *const Alias {
451 return &builder.aliases.items[@intFromEnum(self)];
452 }
453
454 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
455 return self.ptrConst(builder).global.toLlvm(builder);
456 }
457 };
458};
459
460pub const Object = struct {
461 global: Global.Index,
462 thread_local: ThreadLocal = .none,
463 mutability: enum { global, constant } = .global,
464 init: void = {},
465
466 pub const Index = enum(u32) {
467 _,
468
469 pub fn ptr(self: Index, builder: *Builder) *Object {
470 return &builder.objects.items[@intFromEnum(self)];
471 }
472
473 pub fn ptrConst(self: Index, builder: *const Builder) *const Object {
474 return &builder.objects.items[@intFromEnum(self)];
475 }
476
477 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
478 return self.ptrConst(builder).global.toLlvm(builder);
479 }
480 };
481};
482
483pub const Function = struct {
484 global: Global.Index,
485 body: ?void = null,
486
487 fn deinit(self: *Function, _: Allocator) void {
488 self.* = undefined;
489 }
490
491 pub const Index = enum(u32) {
492 _,
493
494 pub fn ptr(self: Index, builder: *Builder) *Function {
495 return &builder.functions.items[@intFromEnum(self)];
496 }
497
498 pub fn ptrConst(self: Index, builder: *const Builder) *const Function {
499 return &builder.functions.items[@intFromEnum(self)];
500 }
501
502 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
503 return self.ptrConst(builder).global.toLlvm(builder);
504 }
505 };
506};
507
508pub fn init(self: *Builder) Allocator.Error!void {
509 try self.string_indices.append(self.gpa, 0);
510 assert(try self.string("") == .empty);
511 assert(try self.string("debugme") == .debugme);
512
513 {
514 const static_len = @typeInfo(Type).Enum.fields.len - 1;
515 try self.type_map.ensureTotalCapacity(self.gpa, static_len);
516 try self.type_data.ensureTotalCapacity(self.gpa, static_len);
517 if (self.useLibLlvm()) try self.llvm_types.ensureTotalCapacity(self.gpa, static_len);
518 inline for (@typeInfo(Type.Simple).Enum.fields) |simple_field| {
519 const result = self.typeNoExtraAssumeCapacity(.{
520 .tag = .simple,
521 .data = simple_field.value,
522 });
523 assert(result.new and result.type == @field(Type, simple_field.name));
524 if (self.useLibLlvm()) self.llvm_types.appendAssumeCapacity(
525 @field(llvm.Context, simple_field.name ++ "Type")(self.llvm_context),
526 );
527 }
528 inline for (.{ 1, 8, 16, 32, 64, 128 }) |bits| assert(self.intTypeAssumeCapacity(bits) ==
529 @field(Type, std.fmt.comptimePrint("i{d}", .{bits})));
530 inline for (.{0}) |addr_space|
531 assert(self.pointerTypeAssumeCapacity(@enumFromInt(addr_space)) == .ptr);
532 }
533}
534
535pub fn deinit(self: *Builder) void {
536 self.llvm_types.deinit(self.gpa);
537 self.llvm_globals.deinit(self.gpa);
538
539 self.string_map.deinit(self.gpa);
540 self.string_bytes.deinit(self.gpa);
541 self.string_indices.deinit(self.gpa);
542
543 self.types.deinit(self.gpa);
544 self.type_map.deinit(self.gpa);
545 self.type_data.deinit(self.gpa);
546 self.type_extra.deinit(self.gpa);
547
548 self.globals.deinit(self.gpa);
549 self.next_unique_global_id.deinit(self.gpa);
550 self.aliases.deinit(self.gpa);
551 self.objects.deinit(self.gpa);
552 self.functions.deinit(self.gpa);
553
554 self.* = undefined;
555}
556
557pub fn string(self: *Builder, bytes: []const u8) Allocator.Error!String {
558 try self.string_bytes.ensureUnusedCapacity(self.gpa, bytes.len + 1);
559 try self.string_indices.ensureUnusedCapacity(self.gpa, 1);
560 try self.string_map.ensureUnusedCapacity(self.gpa, 1);
561
562 const gop = self.string_map.getOrPutAssumeCapacityAdapted(bytes, String.Adapter{ .builder = self });
563 if (!gop.found_existing) {
564 self.string_bytes.appendSliceAssumeCapacity(bytes);
565 self.string_bytes.appendAssumeCapacity(0);
566 self.string_indices.appendAssumeCapacity(@intCast(self.string_bytes.items.len));
567 }
568 return String.fromIndex(gop.index);
569}
570
571pub fn stringIfExists(self: *const Builder, bytes: []const u8) ?String {
572 return String.fromIndex(
573 self.string_map.getIndexAdapted(bytes, String.Adapter{ .builder = self }) orelse return null,
574 );
575}
576
577pub fn fmt(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) Allocator.Error!String {
578 try self.string_map.ensureUnusedCapacity(self.gpa, 1);
579 try self.string_bytes.ensureUnusedCapacity(self.gpa, std.fmt.count(fmt_str ++ .{0}, fmt_args));
580 try self.string_indices.ensureUnusedCapacity(self.gpa, 1);
581 return self.fmtAssumeCapacity(fmt_str, fmt_args);
582}
583
584pub fn fmtAssumeCapacity(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) String {
585 const start = self.string_bytes.items.len;
586 self.string_bytes.writer(self.gpa).print(fmt_str ++ .{0}, fmt_args) catch unreachable;
587 const bytes: []const u8 = self.string_bytes.items[start .. self.string_bytes.items.len - 1];
588
589 const gop = self.string_map.getOrPutAssumeCapacityAdapted(bytes, String.Adapter{ .builder = self });
590 if (gop.found_existing) {
591 self.string_bytes.shrinkRetainingCapacity(start);
592 } else {
593 self.string_indices.appendAssumeCapacity(@intCast(self.string_bytes.items.len));
594 }
595 return String.fromIndex(gop.index);
596}
597
598pub fn opaqueType(self: *Builder, name: String) Allocator.Error!Type {
599 try self.types.ensureUnusedCapacity(self.gpa, 1);
600 try self.ensureUnusedCapacityTypes(1, Type.NamedStructure);
601 return self.opaqueTypeAssumeCapacity(name);
602}
603
604pub fn intType(self: *Builder, bits: u24) Allocator.Error!Type {
605 try self.ensureUnusedCapacityTypes(1);
606 return self.intTypeAssumeCapacity(bits);
607}
608
609pub fn pointerType(self: *Builder, addr_space: AddrSpace) Allocator.Error!Type {
610 try self.ensureUnusedCapacityTypes(1, null);
611 return self.pointerTypeAssumeCapacity(addr_space);
612}
613
614pub fn addGlobal(self: *Builder, name: String, global: Global) Allocator.Error!Global.Index {
615 try self.ensureUnusedCapacityGlobal(name);
616 return self.addGlobalAssumeCapacity(name, global);
617}
618
619pub fn addGlobalAssumeCapacity(self: *Builder, name: String, global: Global) Global.Index {
620 var id = name;
621 if (id == .none) {
622 id = self.next_unnamed_global;
623 self.next_unnamed_global = @enumFromInt(@intFromEnum(self.next_unnamed_global) + 1);
624 }
625 while (true) {
626 const global_gop = self.globals.getOrPutAssumeCapacity(id);
627 if (!global_gop.found_existing) {
628 global_gop.value_ptr.* = global;
629 const index: Global.Index = @enumFromInt(global_gop.index);
630 index.updateName(self);
631 return index;
632 }
633
634 const unique_gop = self.next_unique_global_id.getOrPutAssumeCapacity(name);
635 if (!unique_gop.found_existing) unique_gop.value_ptr.* = 2;
636 id = self.fmtAssumeCapacity("{s}.{d}", .{ name.toSlice(self).?, unique_gop.value_ptr.* });
637 unique_gop.value_ptr.* += 1;
638 }
639}
640
641pub fn getGlobal(self: *const Builder, name: String) ?Global.Index {
642 return @enumFromInt(self.globals.getIndex(name) orelse return null);
643}
644
645fn ensureUnusedCapacityGlobal(self: *Builder, name: String) Allocator.Error!void {
646 if (self.useLibLlvm()) try self.llvm_globals.ensureUnusedCapacity(self.gpa, 1);
647 try self.string_map.ensureUnusedCapacity(self.gpa, 1);
648 try self.string_bytes.ensureUnusedCapacity(self.gpa, name.toSlice(self).?.len +
649 comptime std.fmt.count("{d}" ++ .{0}, .{std.math.maxInt(u32)}));
650 try self.string_indices.ensureUnusedCapacity(self.gpa, 1);
651 try self.globals.ensureUnusedCapacity(self.gpa, 1);
652 try self.next_unique_global_id.ensureUnusedCapacity(self.gpa, 1);
653}
654
655fn addTypeExtraAssumeCapacity(self: *Builder, extra: anytype) Type.ExtraIndex {
656 const result: Type.ExtraIndex = @intCast(self.type_extra.items.len);
657 inline for (@typeInfo(@TypeOf(extra)).Struct.fields) |field| {
658 const value = @field(extra, field.name);
659 self.type_extra.appendAssumeCapacity(switch (field.type) {
660 String, Type => @intFromEnum(value),
661 else => @compileError("bad field type: " ++ @typeName(field.type)),
662 });
663 }
664 return result;
665}
666
667fn typeExtraDataTrail(
668 self: *const Builder,
669 comptime T: type,
670 index: Type.ExtraIndex,
671) struct { data: T, end: Type.ExtraIndex } {
672 var result: T = undefined;
673 const fields = @typeInfo(T).Struct.fields;
674 inline for (fields, self.type_extra.items[index..][0..fields.len]) |field, data|
675 @field(result, field.name) = switch (field.type) {
676 String, Type => @enumFromInt(data),
677 else => @compileError("bad field type: " ++ @typeName(field.type)),
678 };
679 return .{ .data = result, .end = index + @as(Type.ExtraIndex, @intCast(fields.len)) };
680}
681
682fn typeExtraData(self: *const Builder, comptime T: type, index: Type.ExtraIndex) T {
683 return self.typeExtraDataTrail(T, index).data;
684}
685
686fn opaqueTypeAssumeCapacity(self: *Builder, name: String) Type {
687 const Adapter = struct {
688 builder: *const Builder,
689 pub fn hash(_: @This(), key: String) u32 {
690 return std.hash.uint32(@intFromEnum(key));
691 }
692 pub fn eql(ctx: @This(), lhs: String, _: void, rhs_index: usize) bool {
693 const rhs_data = ctx.builder.type_data.items[rhs_index];
694 return rhs_data.tag == .named_structure and
695 lhs == ctx.builder.typeExtraData(Type.NamedStructure, rhs_data.data).id;
696 }
697 };
698 const id = if (name == .none) name: {
699 const next_name = self.next_unnamed_type;
700 assert(next_name != .none);
701 self.next_unnamed_type = @enumFromInt(@intFromEnum(next_name) + 1);
702 break :name next_name;
703 } else name: {
704 assert(name.toIndex() != null);
705 break :name name;
706 };
707 const gop = self.type_map.getOrPutAssumeCapacityAdapted(id, Adapter{ .builder = self });
708 if (!gop.found_existing) {
709 gop.key_ptr.* = {};
710 gop.value_ptr.* = {};
711 self.type_data.appendAssumeCapacity(.{
712 .tag = .named_structure,
713 .data = self.addTypeExtraAssumeCapacity(Type.NamedStructure{ .id = id, .child = .none }),
714 });
715 }
716 const result: Type = @enumFromInt(gop.index);
717 self.types.putAssumeCapacityNoClobber(id, result);
718 return result;
719}
720
721fn intTypeAssumeCapacity(self: *Builder, bits: u24) Type {
722 const result = self.typeNoExtraAssumeCapacity(.{ .tag = .integer, .data = bits });
723 if (self.useLibLlvm() and result.new)
724 self.llvm_types.appendAssumeCapacity(self.llvm_context.intType(bits));
725 return result.type;
726}
727
728fn pointerTypeAssumeCapacity(self: *Builder, addr_space: AddrSpace) Type {
729 const result = self.typeNoExtraAssumeCapacity(.{ .tag = .pointer, .data = @intFromEnum(addr_space) });
730 if (self.useLibLlvm() and result.new)
731 self.llvm_types.appendAssumeCapacity(self.llvm_context.pointerType(@intFromEnum(addr_space)));
732 return result.type;
733}
734
735fn ensureUnusedCapacityTypes(self: *Builder, count: usize, comptime Extra: ?type) Allocator.Error!void {
736 try self.type_map.ensureUnusedCapacity(self.gpa, count);
737 try self.type_data.ensureUnusedCapacity(self.gpa, count);
738 if (Extra) |E|
739 try self.type_extra.ensureUnusedCapacity(self.gpa, count * @typeInfo(E).Struct.fields.len);
740 if (self.useLibLlvm()) try self.llvm_types.ensureUnusedCapacity(self.gpa, count);
741}
742
743fn typeNoExtraAssumeCapacity(self: *Builder, data: Type.Data) struct { new: bool, type: Type } {
744 const Adapter = struct {
745 builder: *const Builder,
746 pub fn hash(_: @This(), key: Type.Data) u32 {
747 return std.hash.uint32(@bitCast(key));
748 }
749 pub fn eql(ctx: @This(), lhs: Type.Data, _: void, rhs_index: usize) bool {
750 const lhs_bits: u32 = @bitCast(lhs);
751 const rhs_bits: u32 = @bitCast(ctx.builder.type_data.items[rhs_index]);
752 return lhs_bits == rhs_bits;
753 }
754 };
755 const gop = self.type_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
756 if (!gop.found_existing) {
757 gop.key_ptr.* = {};
758 gop.value_ptr.* = {};
759 self.type_data.appendAssumeCapacity(data);
760 }
761 return .{ .new = !gop.found_existing, .type = @enumFromInt(gop.index) };
762}
763
764fn isValidIdentifier(id: []const u8) bool {
765 for (id, 0..) |c, i| switch (c) {
766 '$', '-', '.', 'A'...'Z', '_', 'a'...'z' => {},
767 '0'...'9' => if (i == 0) return false,
768 else => return false,
769 };
770 return true;
771}
772
773pub fn dump(self: *Builder, writer: anytype) @TypeOf(writer).Error!void {
774 if (self.source_filename != .none) try writer.print(
775 \\; ModuleID = '{s}'
776 \\source_filename = {"}
777 \\
778 , .{ self.source_filename.toSlice(self).?, self.source_filename.fmt(self) });
779 if (self.data_layout != .none) try writer.print(
780 \\target datalayout = {"}
781 \\
782 , .{self.data_layout.fmt(self)});
783 if (self.target_triple != .none) try writer.print(
784 \\target triple = {"}
785 \\
786 , .{self.target_triple.fmt(self)});
787 try writer.writeByte('\n');
788 for (self.types.keys(), self.types.values()) |id, ty| try writer.print(
789 \\%{} = type {+}
790 \\
791 , .{ id.fmt(self), ty.fmt(self) });
792 try writer.writeByte('\n');
793 for (self.objects.items) |object| {
794 const global = self.globals.entries.get(@intFromEnum(object.global));
795 try writer.print(
796 \\@{} = {}{}{}{}{}{}{}{}{s} {}{,}
797 \\
798 , .{
799 global.key.fmt(self),
800 global.value.linkage,
801 global.value.preemption,
802 global.value.visibility,
803 global.value.dll_storage_class,
804 object.thread_local,
805 global.value.unnamed_addr,
806 global.value.addr_space,
807 global.value.externally_initialized,
808 @tagName(object.mutability),
809 global.value.type.fmt(self),
810 global.value.alignment,
811 });
812 }
813 try writer.writeByte('\n');
814 for (self.functions.items) |function| {
815 const global = self.globals.entries.get(@intFromEnum(function.global));
816 try writer.print(
817 \\{s} {}{}{}{}void @{}() {}{}{{
818 \\ ret void
819 \\}}
820 \\
821 , .{
822 if (function.body) |_| "define" else "declare",
823 global.value.linkage,
824 global.value.preemption,
825 global.value.visibility,
826 global.value.dll_storage_class,
827 global.key.fmt(self),
828 global.value.unnamed_addr,
829 global.value.alignment,
830 });
831 }
832 try writer.writeByte('\n');
833}
834
835inline fn useLibLlvm(self: *const Builder) bool {
836 return build_options.have_llvm and self.use_lib_llvm;
837}
838
839const assert = std.debug.assert;
840const build_options = @import("build_options");
841const llvm = @import("bindings.zig");
842const std = @import("std");
843
844const Allocator = std.mem.Allocator;
845const Builder = @This();
src/codegen/llvm/bindings.zig+27-3
...@@ -40,21 +40,42 @@ pub const Context = opaque {...@@ -40,21 +40,42 @@ pub const Context = opaque {
40 pub const halfType = LLVMHalfTypeInContext;40 pub const halfType = LLVMHalfTypeInContext;
41 extern fn LLVMHalfTypeInContext(C: *Context) *Type;41 extern fn LLVMHalfTypeInContext(C: *Context) *Type;
4242
43 pub const bfloatType = LLVMBFloatTypeInContext;
44 extern fn LLVMBFloatTypeInContext(C: *Context) *Type;
45
43 pub const floatType = LLVMFloatTypeInContext;46 pub const floatType = LLVMFloatTypeInContext;
44 extern fn LLVMFloatTypeInContext(C: *Context) *Type;47 extern fn LLVMFloatTypeInContext(C: *Context) *Type;
4548
46 pub const doubleType = LLVMDoubleTypeInContext;49 pub const doubleType = LLVMDoubleTypeInContext;
47 extern fn LLVMDoubleTypeInContext(C: *Context) *Type;50 extern fn LLVMDoubleTypeInContext(C: *Context) *Type;
4851
49 pub const x86FP80Type = LLVMX86FP80TypeInContext;
50 extern fn LLVMX86FP80TypeInContext(C: *Context) *Type;
51
52 pub const fp128Type = LLVMFP128TypeInContext;52 pub const fp128Type = LLVMFP128TypeInContext;
53 extern fn LLVMFP128TypeInContext(C: *Context) *Type;53 extern fn LLVMFP128TypeInContext(C: *Context) *Type;
5454
55 pub const x86_fp80Type = LLVMX86FP80TypeInContext;
56 extern fn LLVMX86FP80TypeInContext(C: *Context) *Type;
57
58 pub const ppc_fp128Type = LLVMPPCFP128TypeInContext;
59 extern fn LLVMPPCFP128TypeInContext(C: *Context) *Type;
60
61 pub const x86_amxType = LLVMX86AMXTypeInContext;
62 extern fn LLVMX86AMXTypeInContext(C: *Context) *Type;
63
64 pub const x86_mmxType = LLVMX86MMXTypeInContext;
65 extern fn LLVMX86MMXTypeInContext(C: *Context) *Type;
66
55 pub const voidType = LLVMVoidTypeInContext;67 pub const voidType = LLVMVoidTypeInContext;
56 extern fn LLVMVoidTypeInContext(C: *Context) *Type;68 extern fn LLVMVoidTypeInContext(C: *Context) *Type;
5769
70 pub const labelType = LLVMLabelTypeInContext;
71 extern fn LLVMLabelTypeInContext(C: *Context) *Type;
72
73 pub const tokenType = LLVMTokenTypeInContext;
74 extern fn LLVMTokenTypeInContext(C: *Context) *Type;
75
76 pub const metadataType = LLVMMetadataTypeInContext;
77 extern fn LLVMMetadataTypeInContext(C: *Context) *Type;
78
58 pub const structType = LLVMStructTypeInContext;79 pub const structType = LLVMStructTypeInContext;
59 extern fn LLVMStructTypeInContext(80 extern fn LLVMStructTypeInContext(
60 C: *Context,81 C: *Context,
...@@ -1071,6 +1092,9 @@ pub const TargetData = opaque {...@@ -1071,6 +1092,9 @@ pub const TargetData = opaque {
10711092
1072 pub const abiSizeOfType = LLVMABISizeOfType;1093 pub const abiSizeOfType = LLVMABISizeOfType;
1073 extern fn LLVMABISizeOfType(TD: *TargetData, Ty: *Type) c_ulonglong;1094 extern fn LLVMABISizeOfType(TD: *TargetData, Ty: *Type) c_ulonglong;
1095
1096 pub const stringRep = LLVMCopyStringRepOfTargetData;
1097 extern fn LLVMCopyStringRepOfTargetData(TD: *TargetData) [*:0]const u8;
1074};1098};
10751099
1076pub const CodeModel = enum(c_int) {1100pub const CodeModel = enum(c_int) {
src/link.zig+1
...@@ -110,6 +110,7 @@ pub const Options = struct {...@@ -110,6 +110,7 @@ pub const Options = struct {
110 /// other objects.110 /// other objects.
111 /// Otherwise (depending on `use_lld`) this link code directly outputs and updates the final binary.111 /// Otherwise (depending on `use_lld`) this link code directly outputs and updates the final binary.
112 use_llvm: bool,112 use_llvm: bool,
113 use_lib_llvm: bool,
113 link_libc: bool,114 link_libc: bool,
114 link_libcpp: bool,115 link_libcpp: bool,
115 link_libunwind: bool,116 link_libunwind: bool,
src/main.zig+8
...@@ -439,6 +439,8 @@ const usage_build_generic =...@@ -439,6 +439,8 @@ const usage_build_generic =
439 \\ -fno-unwind-tables Never produce unwind table entries439 \\ -fno-unwind-tables Never produce unwind table entries
440 \\ -fLLVM Force using LLVM as the codegen backend440 \\ -fLLVM Force using LLVM as the codegen backend
441 \\ -fno-LLVM Prevent using LLVM as the codegen backend441 \\ -fno-LLVM Prevent using LLVM as the codegen backend
442 \\ -flibLLVM Force using LLVM shared library apias the codegen backend
443 \\ -fno-libLLVM Prevent using LLVM as the codegen backend
442 \\ -fClang Force using Clang as the C/C++ compilation backend444 \\ -fClang Force using Clang as the C/C++ compilation backend
443 \\ -fno-Clang Prevent using Clang as the C/C++ compilation backend445 \\ -fno-Clang Prevent using Clang as the C/C++ compilation backend
444 \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error446 \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error
...@@ -821,6 +823,7 @@ fn buildOutputType(...@@ -821,6 +823,7 @@ fn buildOutputType(
821 var stack_size_override: ?u64 = null;823 var stack_size_override: ?u64 = null;
822 var image_base_override: ?u64 = null;824 var image_base_override: ?u64 = null;
823 var use_llvm: ?bool = null;825 var use_llvm: ?bool = null;
826 var use_lib_llvm: ?bool = null;
824 var use_lld: ?bool = null;827 var use_lld: ?bool = null;
825 var use_clang: ?bool = null;828 var use_clang: ?bool = null;
826 var link_eh_frame_hdr = false;829 var link_eh_frame_hdr = false;
...@@ -1261,6 +1264,10 @@ fn buildOutputType(...@@ -1261,6 +1264,10 @@ fn buildOutputType(
1261 use_llvm = true;1264 use_llvm = true;
1262 } else if (mem.eql(u8, arg, "-fno-LLVM")) {1265 } else if (mem.eql(u8, arg, "-fno-LLVM")) {
1263 use_llvm = false;1266 use_llvm = false;
1267 } else if (mem.eql(u8, arg, "-flibLLVM")) {
1268 use_lib_llvm = true;
1269 } else if (mem.eql(u8, arg, "-fno-libLLVM")) {
1270 use_lib_llvm = false;
1264 } else if (mem.eql(u8, arg, "-fLLD")) {1271 } else if (mem.eql(u8, arg, "-fLLD")) {
1265 use_lld = true;1272 use_lld = true;
1266 } else if (mem.eql(u8, arg, "-fno-LLD")) {1273 } else if (mem.eql(u8, arg, "-fno-LLD")) {
...@@ -3119,6 +3126,7 @@ fn buildOutputType(...@@ -3119,6 +3126,7 @@ fn buildOutputType(
3119 .want_tsan = want_tsan,3126 .want_tsan = want_tsan,
3120 .want_compiler_rt = want_compiler_rt,3127 .want_compiler_rt = want_compiler_rt,
3121 .use_llvm = use_llvm,3128 .use_llvm = use_llvm,
3129 .use_lib_llvm = use_lib_llvm,
3122 .use_lld = use_lld,3130 .use_lld = use_lld,
3123 .use_clang = use_clang,3131 .use_clang = use_clang,
3124 .hash_style = hash_style,3132 .hash_style = hash_style,