authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-02-24 22:18:30+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-02-24 22:18:30+01:00
logb344ff01d380d85256929b6be2428d3c022a8580
tree63d259f50f7f1571ade492df4a187da3c9e9903a
parent8d651f512bf5032e1255dd66750faff0152e2f84
parentedb6486b3bf7a1c333d7cc3348f88ab121b72830
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #19031 from antlilja/llvm-bc

Emit LLVM bitcode without using LLVM

10 files changed, 8605 insertions(+), 5425 deletions(-)

lib/std/meta.zig+4-5
......@@ -460,13 +460,12 @@ test "std.meta.FieldType" {
460460 try testing.expect(FieldType(U, .d) == *const u8);
461461}
462462
463pub fn fieldNames(comptime T: type) *const [fields(T).len][]const u8 {
463pub fn fieldNames(comptime T: type) *const [fields(T).len][:0]const u8 {
464464 return comptime blk: {
465465 const fieldInfos = fields(T);
466 var names: [fieldInfos.len][]const u8 = undefined;
467 for (fieldInfos, 0..) |field, i| {
468 names[i] = field.name;
469 }
466 var names: [fieldInfos.len][:0]const u8 = undefined;
467 // This concat can be removed with the next zig1 update.
468 for (&names, fieldInfos) |*name, field| name.* = field.name ++ "";
470469 break :blk &names;
471470 };
472471}
src/arch/x86_64/CodeGen.zig+31-23
......@@ -16683,36 +16683,44 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
1668316683 else => null,
1668416684 };
1668516685 defer if (elem_lock) |lock| self.register_manager.unlockReg(lock);
16686 const elem_reg = registerAlias(
16687 try self.copyToTmpRegister(elem_ty, mat_elem_mcv),
16688 elem_abi_size,
16689 );
16686
1669016687 const elem_extra_bits = self.regExtraBits(elem_ty);
16691 if (elem_bit_off < elem_extra_bits) {
16692 try self.truncateRegister(elem_ty, elem_reg);
16688 {
16689 const temp_reg = try self.copyToTmpRegister(elem_ty, mat_elem_mcv);
16690 const temp_alias = registerAlias(temp_reg, elem_abi_size);
16691 const temp_lock = self.register_manager.lockRegAssumeUnused(temp_reg);
16692 defer self.register_manager.unlockReg(temp_lock);
16693
16694 if (elem_bit_off < elem_extra_bits) {
16695 try self.truncateRegister(elem_ty, temp_alias);
16696 }
16697 if (elem_bit_off > 0) try self.genShiftBinOpMir(
16698 .{ ._l, .sh },
16699 elem_ty,
16700 .{ .register = temp_alias },
16701 Type.u8,
16702 .{ .immediate = elem_bit_off },
16703 );
16704 try self.genBinOpMir(
16705 .{ ._, .@"or" },
16706 elem_ty,
16707 .{ .load_frame = .{ .index = frame_index, .off = elem_byte_off } },
16708 .{ .register = temp_alias },
16709 );
1669316710 }
16694 if (elem_bit_off > 0) try self.genShiftBinOpMir(
16695 .{ ._l, .sh },
16696 elem_ty,
16697 .{ .register = elem_reg },
16698 Type.u8,
16699 .{ .immediate = elem_bit_off },
16700 );
16701 try self.genBinOpMir(
16702 .{ ._, .@"or" },
16703 elem_ty,
16704 .{ .load_frame = .{ .index = frame_index, .off = elem_byte_off } },
16705 .{ .register = elem_reg },
16706 );
1670716711 if (elem_bit_off > elem_extra_bits) {
16708 const reg = try self.copyToTmpRegister(elem_ty, mat_elem_mcv);
16712 const temp_reg = try self.copyToTmpRegister(elem_ty, mat_elem_mcv);
16713 const temp_alias = registerAlias(temp_reg, elem_abi_size);
16714 const temp_lock = self.register_manager.lockRegAssumeUnused(temp_reg);
16715 defer self.register_manager.unlockReg(temp_lock);
16716
1670916717 if (elem_extra_bits > 0) {
16710 try self.truncateRegister(elem_ty, registerAlias(reg, elem_abi_size));
16718 try self.truncateRegister(elem_ty, temp_alias);
1671116719 }
1671216720 try self.genShiftBinOpMir(
1671316721 .{ ._r, .sh },
1671416722 elem_ty,
16715 .{ .register = reg },
16723 .{ .register = temp_reg },
1671616724 Type.u8,
1671716725 .{ .immediate = elem_abi_bits - elem_bit_off },
1671816726 );
......@@ -16723,7 +16731,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
1672316731 .index = frame_index,
1672416732 .off = elem_byte_off + @as(i32, @intCast(elem_abi_size)),
1672516733 } },
16726 .{ .register = reg },
16734 .{ .register = temp_alias },
1672716735 );
1672816736 }
1672916737 }
src/codegen/llvm.zig+1280-1125
......@@ -770,37 +770,20 @@ pub const Object = struct {
770770 builder: Builder,
771771
772772 module: *Module,
773 di_builder: ?if (build_options.have_llvm) *llvm.DIBuilder else noreturn,
774 /// One of these mappings:
775 /// - *Module.File => *DIFile
776 /// - *Module.Decl (Fn) => *DISubprogram
777 /// - *Module.Decl (Non-Fn) => *DIGlobalVariable
778 di_map: if (build_options.have_llvm) std.AutoHashMapUnmanaged(*const anyopaque, *llvm.DINode) else struct {
779 const K = *const anyopaque;
780 const V = noreturn;
781773
782 const Self = @This();
774 debug_compile_unit: Builder.Metadata,
783775
784 metadata: ?noreturn = null,
785 size: Size = 0,
786 available: Size = 0,
776 debug_enums_fwd_ref: Builder.Metadata,
777 debug_globals_fwd_ref: Builder.Metadata,
787778
788 pub const Size = u0;
779 debug_enums: std.ArrayListUnmanaged(Builder.Metadata),
780 debug_globals: std.ArrayListUnmanaged(Builder.Metadata),
789781
790 pub fn deinit(self: *Self, allocator: Allocator) void {
791 _ = allocator;
792 self.* = undefined;
793 }
782 debug_file_map: std.AutoHashMapUnmanaged(*const Module.File, Builder.Metadata),
783 debug_type_map: std.AutoHashMapUnmanaged(Type, Builder.Metadata),
784
785 debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(InternPool.NamespaceIndex, Builder.Metadata),
794786
795 pub fn get(self: Self, key: K) ?V {
796 _ = self;
797 _ = key;
798 return null;
799 }
800 },
801 di_compile_unit: ?if (build_options.have_llvm) *llvm.DICompileUnit else noreturn,
802 target_machine: if (build_options.have_llvm) *llvm.TargetMachine else void,
803 target_data: if (build_options.have_llvm) *llvm.TargetData else void,
804787 target: std.Target,
805788 /// Ideally we would use `llvm_module.getNamedFunction` to go from *Decl to LLVM function,
806789 /// but that has some downsides:
......@@ -820,7 +803,6 @@ pub const Object = struct {
820803 /// TODO when InternPool garbage collection is implemented, this map needs
821804 /// to be garbage collected as well.
822805 type_map: TypeMap,
823 di_type_map: DITypeMap,
824806 /// The LLVM global table which holds the names corresponding to Zig errors.
825807 /// Note that the values are not added until `emit`, when all errors in
826808 /// the compilation are known.
......@@ -850,164 +832,144 @@ pub const Object = struct {
850832
851833 pub const TypeMap = std.AutoHashMapUnmanaged(InternPool.Index, Builder.Type);
852834
853 /// This is an ArrayHashMap as opposed to a HashMap because in `emit` we
854 /// want to iterate over it while adding entries to it.
855 pub const DITypeMap = std.AutoArrayHashMapUnmanaged(InternPool.Index, AnnotatedDITypePtr);
856
857835 pub fn create(arena: Allocator, comp: *Compilation) !*Object {
858836 if (build_options.only_c) unreachable;
859837 const gpa = comp.gpa;
860838 const target = comp.root_mod.resolved_target.result;
861839 const llvm_target_triple = try targetTriple(arena, target);
862840 const strip = comp.root_mod.strip;
863 const optimize_mode = comp.root_mod.optimize_mode;
864 const pic = comp.root_mod.pic;
865841
866842 var builder = try Builder.init(.{
867843 .allocator = gpa,
868 .use_lib_llvm = comp.config.use_lib_llvm,
869 .strip = strip or !comp.config.use_lib_llvm, // TODO
844 .strip = strip,
870845 .name = comp.root_name,
871846 .target = target,
872847 .triple = llvm_target_triple,
873848 });
874849 errdefer builder.deinit();
875850
876 var target_machine: if (build_options.have_llvm) *llvm.TargetMachine else void = undefined;
877 var target_data: if (build_options.have_llvm) *llvm.TargetData else void = undefined;
878 if (builder.useLibLlvm()) {
879 debug_info: {
880 switch (comp.config.debug_format) {
881 .strip => break :debug_info,
882 .code_view => builder.llvm.module.?.addModuleCodeViewFlag(),
883 .dwarf => |f| builder.llvm.module.?.addModuleDebugInfoFlag(f == .@"64"),
851 builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = target }});
852
853 const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref =
854 if (!builder.strip)
855 debug_info: {
856 // We fully resolve all paths at this point to avoid lack of
857 // source line info in stack traces or lack of debugging
858 // information which, if relative paths were used, would be
859 // very location dependent.
860 // TODO: the only concern I have with this is WASI as either host or target, should
861 // we leave the paths as relative then?
862 // TODO: This is totally wrong. In dwarf, paths are encoded as relative to
863 // a particular directory, and then the directory path is specified elsewhere.
864 // In the compiler frontend we have it stored correctly in this
865 // way already, but here we throw all that sweet information
866 // into the garbage can by converting into absolute paths. What
867 // a terrible tragedy.
868 const compile_unit_dir = blk: {
869 if (comp.module) |zcu| m: {
870 const d = try zcu.root_mod.root.joinString(arena, "");
871 if (d.len == 0) break :m;
872 if (std.fs.path.isAbsolute(d)) break :blk d;
873 break :blk std.fs.realpathAlloc(arena, d) catch break :blk d;
884874 }
885 builder.llvm.di_builder = builder.llvm.module.?.createDIBuilder(true);
875 break :blk try std.process.getCwdAlloc(arena);
876 };
877
878 const debug_file = try builder.debugFile(
879 try builder.metadataString(comp.root_name),
880 try builder.metadataString(compile_unit_dir),
881 );
886882
883 const debug_enums_fwd_ref = try builder.debugForwardReference();
884 const debug_globals_fwd_ref = try builder.debugForwardReference();
885
886 const debug_compile_unit = try builder.debugCompileUnit(
887 debug_file,
887888 // Don't use the version string here; LLVM misparses it when it
888889 // includes the git revision.
889 const producer = try builder.fmt("zig {d}.{d}.{d}", .{
890 try builder.metadataStringFmt("zig {d}.{d}.{d}", .{
890891 build_options.semver.major,
891892 build_options.semver.minor,
892893 build_options.semver.patch,
893 });
894
895 // We fully resolve all paths at this point to avoid lack of
896 // source line info in stack traces or lack of debugging
897 // information which, if relative paths were used, would be
898 // very location dependent.
899 // TODO: the only concern I have with this is WASI as either host or target, should
900 // we leave the paths as relative then?
901 // TODO: This is totally wrong. In dwarf, paths are encoded as relative to
902 // a particular directory, and then the directory path is specified elsewhere.
903 // In the compiler frontend we have it stored correctly in this
904 // way already, but here we throw all that sweet information
905 // into the garbage can by converting into absolute paths. What
906 // a terrible tragedy.
907 const compile_unit_dir_z = blk: {
908 if (comp.module) |zcu| m: {
909 const d = try zcu.root_mod.root.joinStringZ(arena, "");
910 if (d.len == 0) break :m;
911 if (std.fs.path.isAbsolute(d)) break :blk d;
912 const realpath = std.fs.realpathAlloc(arena, d) catch break :blk d;
913 break :blk try arena.dupeZ(u8, realpath);
914 }
915 const cwd = try std.process.getCwdAlloc(arena);
916 break :blk try arena.dupeZ(u8, cwd);
917 };
918
919 builder.llvm.di_compile_unit = builder.llvm.di_builder.?.createCompileUnit(
920 DW.LANG.C99,
921 builder.llvm.di_builder.?.createFile(comp.root_name, compile_unit_dir_z),
922 producer.slice(&builder).?,
923 optimize_mode != .Debug,
924 "", // flags
925 0, // runtime version
926 "", // split name
927 0, // dwo id
928 true, // emit debug info
929 );
930 }
931
932 const opt_level: llvm.CodeGenOptLevel = if (optimize_mode == .Debug)
933 .None
934 else
935 .Aggressive;
936
937 const reloc_mode: llvm.RelocMode = if (pic)
938 .PIC
939 else if (comp.config.link_mode == .Dynamic)
940 llvm.RelocMode.DynamicNoPIC
941 else
942 .Static;
943
944 const code_model: llvm.CodeModel = switch (comp.root_mod.code_model) {
945 .default => .Default,
946 .tiny => .Tiny,
947 .small => .Small,
948 .kernel => .Kernel,
949 .medium => .Medium,
950 .large => .Large,
951 };
952
953 // TODO handle float ABI better- it should depend on the ABI portion of std.Target
954 const float_abi: llvm.ABIType = .Default;
955
956 target_machine = llvm.TargetMachine.create(
957 builder.llvm.target.?,
958 builder.target_triple.slice(&builder).?,
959 if (target.cpu.model.llvm_name) |s| s.ptr else null,
960 comp.root_mod.resolved_target.llvm_cpu_features.?,
961 opt_level,
962 reloc_mode,
963 code_model,
964 comp.function_sections,
965 comp.data_sections,
966 float_abi,
967 if (target_util.llvmMachineAbi(target)) |s| s.ptr else null,
894 }),
895 debug_enums_fwd_ref,
896 debug_globals_fwd_ref,
897 .{ .optimized = comp.root_mod.optimize_mode != .Debug },
968898 );
969 errdefer target_machine.dispose();
970899
971 target_data = target_machine.createTargetDataLayout();
972 errdefer target_data.dispose();
973
974 builder.llvm.module.?.setModuleDataLayout(target_data);
975
976 if (pic) builder.llvm.module.?.setModulePICLevel();
977 if (comp.config.pie) builder.llvm.module.?.setModulePIELevel();
978 if (code_model != .Default) builder.llvm.module.?.setModuleCodeModel(code_model);
900 const i32_2 = try builder.intConst(.i32, 2);
901 const i32_3 = try builder.intConst(.i32, 3);
902 const debug_info_version = try builder.debugModuleFlag(
903 try builder.debugConstant(i32_2),
904 try builder.metadataString("Debug Info Version"),
905 try builder.debugConstant(i32_3),
906 );
979907
980 if (comp.llvm_opt_bisect_limit >= 0) {
981 builder.llvm.context.setOptBisectLimit(comp.llvm_opt_bisect_limit);
908 switch (comp.config.debug_format) {
909 .strip => unreachable,
910 .dwarf => |f| {
911 const i32_4 = try builder.intConst(.i32, 4);
912 const dwarf_version = try builder.debugModuleFlag(
913 try builder.debugConstant(i32_2),
914 try builder.metadataString("Dwarf Version"),
915 try builder.debugConstant(i32_4),
916 );
917 switch (f) {
918 .@"32" => {
919 try builder.debugNamed(try builder.metadataString("llvm.module.flags"), &.{
920 debug_info_version,
921 dwarf_version,
922 });
923 },
924 .@"64" => {
925 const dwarf64 = try builder.debugModuleFlag(
926 try builder.debugConstant(i32_2),
927 try builder.metadataString("DWARF64"),
928 try builder.debugConstant(.@"1"),
929 );
930 try builder.debugNamed(try builder.metadataString("llvm.module.flags"), &.{
931 debug_info_version,
932 dwarf_version,
933 dwarf64,
934 });
935 },
936 }
937 },
938 .code_view => {
939 const code_view = try builder.debugModuleFlag(
940 try builder.debugConstant(i32_2),
941 try builder.metadataString("CodeView"),
942 try builder.debugConstant(.@"1"),
943 );
944 try builder.debugNamed(try builder.metadataString("llvm.module.flags"), &.{
945 debug_info_version,
946 code_view,
947 });
948 },
982949 }
983950
984 builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = target }});
985 if (std.debug.runtime_safety) {
986 const rep = target_data.stringRep();
987 defer llvm.disposeMessage(rep);
988 std.testing.expectEqualStrings(
989 std.mem.span(rep),
990 builder.data_layout.slice(&builder).?,
991 ) catch unreachable;
992 }
993 }
951 try builder.debugNamed(try builder.metadataString("llvm.dbg.cu"), &.{debug_compile_unit});
952 break :debug_info .{ debug_compile_unit, debug_enums_fwd_ref, debug_globals_fwd_ref };
953 } else .{.none} ** 3;
994954
995955 const obj = try arena.create(Object);
996956 obj.* = .{
997957 .gpa = gpa,
998958 .builder = builder,
999959 .module = comp.module.?,
1000 .di_map = .{},
1001 .di_builder = if (builder.useLibLlvm()) builder.llvm.di_builder else null, // TODO
1002 .di_compile_unit = if (builder.useLibLlvm()) builder.llvm.di_compile_unit else null,
1003 .target_machine = target_machine,
1004 .target_data = target_data,
960 .debug_compile_unit = debug_compile_unit,
961 .debug_enums_fwd_ref = debug_enums_fwd_ref,
962 .debug_globals_fwd_ref = debug_globals_fwd_ref,
963 .debug_enums = .{},
964 .debug_globals = .{},
965 .debug_file_map = .{},
966 .debug_type_map = .{},
967 .debug_unresolved_namespace_scopes = .{},
1005968 .target = target,
1006969 .decl_map = .{},
1007970 .anon_decl_map = .{},
1008971 .named_enum_map = .{},
1009972 .type_map = .{},
1010 .di_type_map = .{},
1011973 .error_name_table = .none,
1012974 .extern_collisions = .{},
1013975 .null_opt_usize = .no_init,
......@@ -1018,12 +980,11 @@ pub const Object = struct {
1018980
1019981 pub fn deinit(self: *Object) void {
1020982 const gpa = self.gpa;
1021 self.di_map.deinit(gpa);
1022 self.di_type_map.deinit(gpa);
1023 if (self.builder.useLibLlvm()) {
1024 self.target_data.dispose();
1025 self.target_machine.dispose();
1026 }
983 self.debug_enums.deinit(gpa);
984 self.debug_globals.deinit(gpa);
985 self.debug_file_map.deinit(gpa);
986 self.debug_type_map.deinit(gpa);
987 self.debug_unresolved_namespace_scopes.deinit(gpa);
1027988 self.decl_map.deinit(gpa);
1028989 self.anon_decl_map.deinit(gpa);
1029990 self.named_enum_map.deinit(gpa);
......@@ -1052,8 +1013,8 @@ pub const Object = struct {
10521013
10531014 llvm_errors[0] = try o.builder.undefConst(llvm_slice_ty);
10541015 for (llvm_errors[1..], error_name_list[1..]) |*llvm_error, name| {
1055 const name_string = try o.builder.string(mod.intern_pool.stringToSlice(name));
1056 const name_init = try o.builder.stringNullConst(name_string);
1016 const name_string = try o.builder.stringNull(mod.intern_pool.stringToSlice(name));
1017 const name_init = try o.builder.stringConst(name_string);
10571018 const name_variable_index =
10581019 try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default);
10591020 try name_variable_index.setInitializer(name_init, &o.builder);
......@@ -1064,7 +1025,7 @@ pub const Object = struct {
10641025
10651026 llvm_error.* = try o.builder.structConst(llvm_slice_ty, &.{
10661027 name_variable_index.toConst(&o.builder),
1067 try o.builder.intConst(llvm_usize_ty, name_string.slice(&o.builder).?.len),
1028 try o.builder.intConst(llvm_usize_ty, name_string.slice(&o.builder).?.len - 1),
10681029 });
10691030 }
10701031
......@@ -1193,24 +1154,29 @@ pub const Object = struct {
11931154 try self.genCmpLtErrorsLenFunction();
11941155 try self.genModuleLevelAssembly();
11951156
1196 if (self.di_builder) |dib| {
1197 // When lowering debug info for pointers, we emitted the element types as
1198 // forward decls. Now we must go flesh those out.
1199 // Here we iterate over a hash map while modifying it but it is OK because
1200 // we never add or remove entries during this loop.
1201 var i: usize = 0;
1202 while (i < self.di_type_map.count()) : (i += 1) {
1203 const value_ptr = &self.di_type_map.values()[i];
1204 const annotated = value_ptr.*;
1205 if (!annotated.isFwdOnly()) continue;
1206 const entry: Object.DITypeMap.Entry = .{
1207 .key_ptr = &self.di_type_map.keys()[i],
1208 .value_ptr = value_ptr,
1209 };
1210 _ = try self.lowerDebugTypeImpl(entry, .full, annotated.toDIType());
1157 if (!self.builder.strip) {
1158 {
1159 var i: usize = 0;
1160 while (i < self.debug_unresolved_namespace_scopes.count()) : (i += 1) {
1161 const namespace_index = self.debug_unresolved_namespace_scopes.keys()[i];
1162 const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i];
1163
1164 const namespace = self.module.namespacePtr(namespace_index);
1165 const debug_type = try self.lowerDebugType(namespace.ty);
1166
1167 self.builder.debugForwardReferenceSetType(fwd_ref, debug_type);
1168 }
12111169 }
12121170
1213 dib.finalize();
1171 self.builder.debugForwardReferenceSetType(
1172 self.debug_enums_fwd_ref,
1173 try self.builder.debugTuple(self.debug_enums.items),
1174 );
1175
1176 self.builder.debugForwardReferenceSetType(
1177 self.debug_globals_fwd_ref,
1178 try self.builder.debugTuple(self.debug_globals.items),
1179 );
12141180 }
12151181
12161182 if (options.pre_ir_path) |path| {
......@@ -1221,10 +1187,21 @@ pub const Object = struct {
12211187 }
12221188 }
12231189
1224 if (options.pre_bc_path) |path| _ = try self.builder.writeBitcodeToFile(path);
1190 var bitcode_arena_allocator = std.heap.ArenaAllocator.init(
1191 std.heap.page_allocator,
1192 );
1193 errdefer bitcode_arena_allocator.deinit();
1194
1195 const bitcode = try self.builder.toBitcode(
1196 bitcode_arena_allocator.allocator(),
1197 );
1198
1199 if (options.pre_bc_path) |path| {
1200 var file = try std.fs.cwd().createFile(path, .{});
1201 defer file.close();
12251202
1226 if (std.debug.runtime_safety and !try self.builder.verify()) {
1227 @panic("LLVM module verification failed");
1203 const ptr: [*]const u8 = @ptrCast(bitcode.ptr);
1204 try file.writeAll(ptr[0..(bitcode.len * 4)]);
12281205 }
12291206
12301207 const emit_asm_msg = options.asm_path orelse "(none)";
......@@ -1238,16 +1215,116 @@ pub const Object = struct {
12381215 if (options.asm_path == null and options.bin_path == null and
12391216 options.post_ir_path == null and options.post_bc_path == null) return;
12401217
1241 if (!self.builder.useLibLlvm()) unreachable; // caught in Compilation.Config.resolve
1218 if (options.post_bc_path) |path| {
1219 var file = try std.fs.cwd().createFileZ(path, .{});
1220 defer file.close();
1221
1222 const ptr: [*]const u8 = @ptrCast(bitcode.ptr);
1223 try file.writeAll(ptr[0..(bitcode.len * 4)]);
1224 }
1225
1226 if (!build_options.have_llvm or !self.module.comp.config.use_lib_llvm) {
1227 log.err("emitting without libllvm not implemented", .{});
1228 return error.FailedToEmit;
1229 }
1230
1231 initializeLLVMTarget(self.module.comp.root_mod.resolved_target.result.cpu.arch);
1232
1233 const context: *llvm.Context = llvm.Context.create();
1234 defer context.dispose();
1235
1236 const module = blk: {
1237 const bitcode_memory_buffer = llvm.MemoryBuffer.createMemoryBufferWithMemoryRange(
1238 @ptrCast(bitcode.ptr),
1239 bitcode.len * 4,
1240 "BitcodeBuffer",
1241 llvm.Bool.False,
1242 );
1243 defer bitcode_memory_buffer.dispose();
1244
1245 var module: *llvm.Module = undefined;
1246 if (context.parseBitcodeInContext2(bitcode_memory_buffer, &module).toBool()) {
1247 std.debug.print("Failed to parse bitcode\n", .{});
1248 return error.FailedToEmit;
1249 }
1250
1251 break :blk module;
1252 };
1253 bitcode_arena_allocator.deinit();
1254
1255 const target_triple_sentinel =
1256 try self.gpa.dupeZ(u8, self.builder.target_triple.slice(&self.builder).?);
1257 defer self.gpa.free(target_triple_sentinel);
1258 var target: *llvm.Target = undefined;
1259 var error_message: [*:0]const u8 = undefined;
1260 if (llvm.Target.getFromTriple(target_triple_sentinel, &target, &error_message).toBool()) {
1261 defer llvm.disposeMessage(error_message);
1262
1263 log.err("LLVM failed to parse '{s}': {s}", .{
1264 self.builder.target_triple.slice(&self.builder).?,
1265 error_message,
1266 });
1267 @panic("Invalid LLVM triple");
1268 }
1269
1270 const optimize_mode = self.module.comp.root_mod.optimize_mode;
1271 const pic = self.module.comp.root_mod.pic;
1272
1273 const opt_level: llvm.CodeGenOptLevel = if (optimize_mode == .Debug)
1274 .None
1275 else
1276 .Aggressive;
1277
1278 const reloc_mode: llvm.RelocMode = if (pic)
1279 .PIC
1280 else if (self.module.comp.config.link_mode == .Dynamic)
1281 llvm.RelocMode.DynamicNoPIC
1282 else
1283 .Static;
1284
1285 const code_model: llvm.CodeModel = switch (self.module.comp.root_mod.code_model) {
1286 .default => .Default,
1287 .tiny => .Tiny,
1288 .small => .Small,
1289 .kernel => .Kernel,
1290 .medium => .Medium,
1291 .large => .Large,
1292 };
1293
1294 // TODO handle float ABI better- it should depend on the ABI portion of std.Target
1295 const float_abi: llvm.ABIType = .Default;
1296
1297 var target_machine = llvm.TargetMachine.create(
1298 target,
1299 target_triple_sentinel,
1300 if (self.module.comp.root_mod.resolved_target.result.cpu.model.llvm_name) |s| s.ptr else null,
1301 self.module.comp.root_mod.resolved_target.llvm_cpu_features.?,
1302 opt_level,
1303 reloc_mode,
1304 code_model,
1305 self.module.comp.function_sections,
1306 self.module.comp.data_sections,
1307 float_abi,
1308 if (target_util.llvmMachineAbi(self.module.comp.root_mod.resolved_target.result)) |s| s.ptr else null,
1309 );
1310 errdefer target_machine.dispose();
1311
1312 if (pic) module.setModulePICLevel();
1313 if (self.module.comp.config.pie) module.setModulePIELevel();
1314 if (code_model != .Default) module.setModuleCodeModel(code_model);
1315
1316 if (self.module.comp.llvm_opt_bisect_limit >= 0) {
1317 context.setOptBisectLimit(self.module.comp.llvm_opt_bisect_limit);
1318 }
12421319
12431320 // Unfortunately, LLVM shits the bed when we ask for both binary and assembly.
12441321 // So we call the entire pipeline multiple times if this is requested.
1245 var error_message: [*:0]const u8 = undefined;
1322 // var error_message: [*:0]const u8 = undefined;
12461323 var emit_bin_path = options.bin_path;
12471324 var post_ir_path = options.post_ir_path;
12481325 if (options.asm_path != null and options.bin_path != null) {
1249 if (self.target_machine.emitToFile(
1250 self.builder.llvm.module.?,
1326 if (target_machine.emitToFile(
1327 module,
12511328 &error_message,
12521329 options.is_debug,
12531330 options.is_small,
......@@ -1270,8 +1347,8 @@ pub const Object = struct {
12701347 post_ir_path = null;
12711348 }
12721349
1273 if (self.target_machine.emitToFile(
1274 self.builder.llvm.module.?,
1350 if (target_machine.emitToFile(
1351 module,
12751352 &error_message,
12761353 options.is_debug,
12771354 options.is_small,
......@@ -1281,7 +1358,7 @@ pub const Object = struct {
12811358 options.asm_path,
12821359 emit_bin_path,
12831360 post_ir_path,
1284 options.post_bc_path,
1361 null,
12851362 )) {
12861363 defer llvm.disposeMessage(error_message);
12871364
......@@ -1421,7 +1498,7 @@ pub const Object = struct {
14211498 if (isByRef(param_ty, zcu)) {
14221499 const alignment = param_ty.abiAlignment(zcu).toLlvm();
14231500 const param_llvm_ty = param.typeOfWip(&wip);
1424 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target);
1501 const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target);
14251502 _ = try wip.store(.normal, param, arg_ptr, alignment);
14261503 args.appendAssumeCapacity(arg_ptr);
14271504 } else {
......@@ -1469,7 +1546,7 @@ pub const Object = struct {
14691546
14701547 const param_llvm_ty = try o.lowerType(param_ty);
14711548 const alignment = param_ty.abiAlignment(zcu).toLlvm();
1472 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target);
1549 const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target);
14731550 _ = try wip.store(.normal, param, arg_ptr, alignment);
14741551
14751552 args.appendAssumeCapacity(if (isByRef(param_ty, zcu))
......@@ -1514,7 +1591,7 @@ pub const Object = struct {
15141591 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
15151592 const param_llvm_ty = try o.lowerType(param_ty);
15161593 const param_alignment = param_ty.abiAlignment(zcu).toLlvm();
1517 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, param_alignment, target);
1594 const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, param_alignment, target);
15181595 const llvm_ty = try o.builder.structType(.normal, field_types);
15191596 for (0..field_types.len) |field_i| {
15201597 const param = wip.arg(llvm_arg_i);
......@@ -1544,7 +1621,7 @@ pub const Object = struct {
15441621 llvm_arg_i += 1;
15451622
15461623 const alignment = param_ty.abiAlignment(zcu).toLlvm();
1547 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target);
1624 const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target);
15481625 _ = try wip.store(.normal, param, arg_ptr, alignment);
15491626
15501627 args.appendAssumeCapacity(if (isByRef(param_ty, zcu))
......@@ -1559,7 +1636,7 @@ pub const Object = struct {
15591636 llvm_arg_i += 1;
15601637
15611638 const alignment = param_ty.abiAlignment(zcu).toLlvm();
1562 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target);
1639 const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target);
15631640 _ = try wip.store(.normal, param, arg_ptr, alignment);
15641641
15651642 args.appendAssumeCapacity(if (isByRef(param_ty, zcu))
......@@ -1573,40 +1650,37 @@ pub const Object = struct {
15731650
15741651 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);
15751652
1576 var di_file: ?if (build_options.have_llvm) *llvm.DIFile else noreturn = null;
1577 var di_scope: ?if (build_options.have_llvm) *llvm.DIScope else noreturn = null;
1578
1579 if (o.di_builder) |dib| {
1580 di_file = try o.getDIFile(gpa, namespace.file_scope);
1653 const file, const subprogram = if (!o.builder.strip) debug_info: {
1654 const file = try o.getDebugFile(namespace.file_scope);
15811655
15821656 const line_number = decl.src_line + 1;
15831657 const is_internal_linkage = decl.val.getExternFunc(zcu) == null and
15841658 !zcu.decl_exports.contains(decl_index);
1585 const noret_bit: c_uint = if (fn_info.return_type == .noreturn_type)
1586 llvm.DIFlags.NoReturn
1587 else
1588 0;
1589 const decl_di_ty = try o.lowerDebugType(decl.ty, .full);
1590 const subprogram = dib.createFunction(
1591 di_file.?.toScope(),
1592 ip.stringToSlice(decl.name),
1593 function_index.name(&o.builder).slice(&o.builder).?,
1594 di_file.?,
1659 const debug_decl_type = try o.lowerDebugType(decl.ty);
1660
1661 const subprogram = try o.builder.debugSubprogram(
1662 file,
1663 try o.builder.metadataString(ip.stringToSlice(decl.name)),
1664 try o.builder.metadataStringFromString(function_index.name(&o.builder)),
15951665 line_number,
1596 decl_di_ty,
1597 is_internal_linkage,
1598 true, // is definition
1599 line_number + func.lbrace_line, // scope line
1600 llvm.DIFlags.StaticMember | noret_bit,
1601 owner_mod.optimize_mode != .Debug,
1602 null, // decl_subprogram
1666 line_number + func.lbrace_line,
1667 debug_decl_type,
1668 .{
1669 .di_flags = .{
1670 .StaticMember = true,
1671 .NoReturn = fn_info.return_type == .noreturn_type,
1672 },
1673 .sp_flags = .{
1674 .Optimized = owner_mod.optimize_mode != .Debug,
1675 .Definition = true,
1676 .LocalToUnit = is_internal_linkage,
1677 },
1678 },
1679 o.debug_compile_unit,
16031680 );
1604 try o.di_map.put(gpa, decl, subprogram.toNode());
1605
1606 function_index.toLlvm(&o.builder).fnSetSubprogram(subprogram);
1607
1608 di_scope = subprogram.toScope();
1609 }
1681 function_index.setSubprogram(subprogram, &o.builder);
1682 break :debug_info .{ file, subprogram };
1683 } else .{.none} ** 2;
16101684
16111685 var fg: FuncGen = .{
16121686 .gpa = gpa,
......@@ -1620,8 +1694,8 @@ pub const Object = struct {
16201694 .func_inst_table = .{},
16211695 .blocks = .{},
16221696 .sync_scope = if (owner_mod.single_threaded) .singlethread else .system,
1623 .di_scope = di_scope,
1624 .di_file = di_file,
1697 .file = file,
1698 .scope = subprogram,
16251699 .base_line = dg.decl.src_line,
16261700 .prev_dbg_line = 0,
16271701 .prev_dbg_column = 0,
......@@ -1707,26 +1781,7 @@ pub const Object = struct {
17071781 global_index.setUnnamedAddr(.default, &self.builder);
17081782 if (comp.config.dll_export_fns)
17091783 global_index.setDllStorageClass(.default, &self.builder);
1710 if (self.di_map.get(decl)) |di_node| {
1711 const decl_name_slice = decl_name.slice(&self.builder).?;
1712 if (try decl.isFunction(mod)) {
1713 const di_func: *llvm.DISubprogram = @ptrCast(di_node);
1714 const linkage_name = llvm.MDString.get(
1715 self.builder.llvm.context,
1716 decl_name_slice.ptr,
1717 decl_name_slice.len,
1718 );
1719 di_func.replaceLinkageName(linkage_name);
1720 } else {
1721 const di_global: *llvm.DIGlobalVariable = @ptrCast(di_node);
1722 const linkage_name = llvm.MDString.get(
1723 self.builder.llvm.context,
1724 decl_name_slice.ptr,
1725 decl_name_slice.len,
1726 );
1727 di_global.replaceLinkageName(linkage_name);
1728 }
1729 }
1784
17301785 if (decl.val.getVariable(mod)) |decl_var| {
17311786 global_index.ptrConst(&self.builder).kind.variable.setThreadLocal(
17321787 if (decl_var.is_threadlocal) .generaldynamic else .default,
......@@ -1740,27 +1795,6 @@ pub const Object = struct {
17401795 );
17411796 try global_index.rename(main_exp_name, &self.builder);
17421797
1743 if (self.di_map.get(decl)) |di_node| {
1744 const main_exp_name_slice = main_exp_name.slice(&self.builder).?;
1745 if (try decl.isFunction(mod)) {
1746 const di_func: *llvm.DISubprogram = @ptrCast(di_node);
1747 const linkage_name = llvm.MDString.get(
1748 self.builder.llvm.context,
1749 main_exp_name_slice.ptr,
1750 main_exp_name_slice.len,
1751 );
1752 di_func.replaceLinkageName(linkage_name);
1753 } else {
1754 const di_global: *llvm.DIGlobalVariable = @ptrCast(di_node);
1755 const linkage_name = llvm.MDString.get(
1756 self.builder.llvm.context,
1757 main_exp_name_slice.ptr,
1758 main_exp_name_slice.len,
1759 );
1760 di_global.replaceLinkageName(linkage_name);
1761 }
1762 }
1763
17641798 if (decl.val.getVariable(mod)) |decl_var| if (decl_var.is_threadlocal)
17651799 global_index.ptrConst(&self.builder).kind
17661800 .variable.setThreadLocal(.generaldynamic, &self.builder);
......@@ -1890,119 +1924,79 @@ pub const Object = struct {
18901924 global.delete(&self.builder);
18911925 }
18921926
1893 fn getDIFile(o: *Object, gpa: Allocator, file: *const Module.File) !*llvm.DIFile {
1894 const gop = try o.di_map.getOrPut(gpa, file);
1895 errdefer assert(o.di_map.remove(file));
1896 if (gop.found_existing) {
1897 return @ptrCast(gop.value_ptr.*);
1898 }
1899 const dir_path_z = d: {
1900 var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
1901 const sub_path = std.fs.path.dirname(file.sub_file_path) orelse "";
1902 const dir_path = try file.mod.root.joinStringZ(gpa, sub_path);
1903 if (std.fs.path.isAbsolute(dir_path)) break :d dir_path;
1904 const abs = std.fs.realpath(dir_path, &buffer) catch break :d dir_path;
1905 gpa.free(dir_path);
1906 break :d try gpa.dupeZ(u8, abs);
1907 };
1908 defer gpa.free(dir_path_z);
1909 const sub_file_path_z = try gpa.dupeZ(u8, std.fs.path.basename(file.sub_file_path));
1910 defer gpa.free(sub_file_path_z);
1911 const di_file = o.di_builder.?.createFile(sub_file_path_z, dir_path_z);
1912 gop.value_ptr.* = di_file.toNode();
1913 return di_file;
1927 fn getDebugFile(o: *Object, file: *const Module.File) Allocator.Error!Builder.Metadata {
1928 const gpa = o.gpa;
1929 const gop = try o.debug_file_map.getOrPut(gpa, file);
1930 errdefer assert(o.debug_file_map.remove(file));
1931 if (gop.found_existing) return gop.value_ptr.*;
1932 gop.value_ptr.* = try o.builder.debugFile(
1933 try o.builder.metadataString(std.fs.path.basename(file.sub_file_path)),
1934 dir_path: {
1935 const sub_path = std.fs.path.dirname(file.sub_file_path) orelse "";
1936 const dir_path = try file.mod.root.joinString(gpa, sub_path);
1937 defer gpa.free(dir_path);
1938 if (std.fs.path.isAbsolute(dir_path))
1939 break :dir_path try o.builder.metadataString(dir_path);
1940 var abs_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
1941 const abs_path = std.fs.realpath(dir_path, &abs_buffer) catch
1942 break :dir_path try o.builder.metadataString(dir_path);
1943 break :dir_path try o.builder.metadataString(abs_path);
1944 },
1945 );
1946 return gop.value_ptr.*;
19141947 }
19151948
1916 const DebugResolveStatus = enum { fwd, full };
1917
1918 /// In the implementation of this function, it is required to store a forward decl
1919 /// into `gop` before making any recursive calls (even directly).
1920 fn lowerDebugType(
1949 pub fn lowerDebugType(
19211950 o: *Object,
19221951 ty: Type,
1923 resolve: DebugResolveStatus,
1924 ) Allocator.Error!*llvm.DIType {
1925 const gpa = o.gpa;
1926 // Be careful not to reference this `gop` variable after any recursive calls
1927 // to `lowerDebugType`.
1928 const gop = try o.di_type_map.getOrPut(gpa, ty.toIntern());
1929 if (gop.found_existing) {
1930 const annotated = gop.value_ptr.*;
1931 switch (annotated) {
1932 // This type is currently attempting to be resolved fully, so make
1933 // sure a second recursion through the types uses forward resolution.
1934 .null => assert(resolve == .fwd),
1935 // This type already has at least forward resolution, only resolve
1936 // fully during full resolution.
1937 _ => {
1938 const di_type = annotated.toDIType();
1939 if (!annotated.isFwdOnly() or resolve == .fwd) {
1940 return di_type;
1941 }
1942 const entry: Object.DITypeMap.Entry = .{
1943 .key_ptr = gop.key_ptr,
1944 .value_ptr = gop.value_ptr,
1945 };
1946 return o.lowerDebugTypeImpl(entry, resolve, di_type);
1947 },
1948 }
1949 } else gop.value_ptr.* = .null;
1950 errdefer if (!gop.found_existing) assert(o.di_type_map.orderedRemove(ty.toIntern()));
1951 const entry: Object.DITypeMap.Entry = .{
1952 .key_ptr = gop.key_ptr,
1953 .value_ptr = gop.value_ptr,
1954 };
1955 return o.lowerDebugTypeImpl(entry, resolve, null);
1956 }
1952 ) Allocator.Error!Builder.Metadata {
1953 assert(!o.builder.strip);
19571954
1958 /// This is a helper function used by `lowerDebugType`.
1959 fn lowerDebugTypeImpl(
1960 o: *Object,
1961 gop: Object.DITypeMap.Entry,
1962 resolve: DebugResolveStatus,
1963 opt_fwd_decl: ?*llvm.DIType,
1964 ) Allocator.Error!*llvm.DIType {
1965 const ty = Type.fromInterned(gop.key_ptr.*);
19661955 const gpa = o.gpa;
19671956 const target = o.target;
1968 const dib = o.di_builder.?;
19691957 const mod = o.module;
19701958 const ip = &mod.intern_pool;
1959
1960 if (o.debug_type_map.get(ty)) |debug_type| return debug_type;
1961
19711962 switch (ty.zigTypeTag(mod)) {
1972 .Void, .NoReturn => {
1973 const di_type = dib.createBasicType("void", 0, DW.ATE.signed);
1974 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
1975 return di_type;
1963 .Void,
1964 .NoReturn,
1965 => {
1966 const debug_void_type = try o.builder.debugSignedType(
1967 try o.builder.metadataString("void"),
1968 0,
1969 );
1970 try o.debug_type_map.put(gpa, ty, debug_void_type);
1971 return debug_void_type;
19761972 },
19771973 .Int => {
19781974 const info = ty.intInfo(mod);
19791975 assert(info.bits != 0);
19801976 const name = try o.allocTypeName(ty);
19811977 defer gpa.free(name);
1982 const dwarf_encoding: c_uint = switch (info.signedness) {
1983 .signed => DW.ATE.signed,
1984 .unsigned => DW.ATE.unsigned,
1978 const builder_name = try o.builder.metadataString(name);
1979 const debug_bits = ty.abiSize(mod) * 8; // lldb cannot handle non-byte sized types
1980 const debug_int_type = switch (info.signedness) {
1981 .signed => try o.builder.debugSignedType(builder_name, debug_bits),
1982 .unsigned => try o.builder.debugUnsignedType(builder_name, debug_bits),
19851983 };
1986 const di_bits = ty.abiSize(mod) * 8; // lldb cannot handle non-byte sized types
1987 const di_type = dib.createBasicType(name, di_bits, dwarf_encoding);
1988 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
1989 return di_type;
1984 try o.debug_type_map.put(gpa, ty, debug_int_type);
1985 return debug_int_type;
19901986 },
19911987 .Enum => {
19921988 const owner_decl_index = ty.getOwnerDecl(mod);
19931989 const owner_decl = o.module.declPtr(owner_decl_index);
19941990
19951991 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) {
1996 const enum_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
1997 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
1998 // means we can't use `gop` anymore.
1999 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(enum_di_ty));
2000 return enum_di_ty;
1992 const debug_enum_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
1993 try o.debug_type_map.put(gpa, ty, debug_enum_type);
1994 return debug_enum_type;
20011995 }
20021996
20031997 const enum_type = ip.indexToKey(ty.toIntern()).enum_type;
20041998
2005 const enumerators = try gpa.alloc(*llvm.DIEnumerator, enum_type.names.len);
1999 const enumerators = try gpa.alloc(Builder.Metadata, enum_type.names.len);
20062000 defer gpa.free(enumerators);
20072001
20082002 const int_ty = Type.fromInterned(enum_type.tag_ty);
......@@ -2010,66 +2004,59 @@ pub const Object = struct {
20102004 assert(int_info.bits != 0);
20112005
20122006 for (enum_type.names.get(ip), 0..) |field_name_ip, i| {
2013 const field_name_z = ip.stringToSlice(field_name_ip);
2014
20152007 var bigint_space: Value.BigIntSpace = undefined;
20162008 const bigint = if (enum_type.values.len != 0)
20172009 Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, mod)
20182010 else
20192011 std.math.big.int.Mutable.init(&bigint_space.limbs, i).toConst();
20202012
2021 if (bigint.limbs.len == 1) {
2022 enumerators[i] = dib.createEnumerator(field_name_z, bigint.limbs[0], int_info.signedness == .unsigned);
2023 continue;
2024 }
2025 if (@sizeOf(usize) == @sizeOf(u64)) {
2026 enumerators[i] = dib.createEnumerator2(
2027 field_name_z,
2028 @intCast(bigint.limbs.len),
2029 bigint.limbs.ptr,
2030 int_info.bits,
2031 int_info.signedness == .unsigned,
2032 );
2033 continue;
2034 }
2035 @panic("TODO implement bigint debug enumerators to llvm int for 32-bit compiler builds");
2013 enumerators[i] = try o.builder.debugEnumerator(
2014 try o.builder.metadataString(ip.stringToSlice(field_name_ip)),
2015 int_ty.isUnsignedInt(mod),
2016 int_info.bits,
2017 bigint,
2018 );
20362019 }
20372020
2038 const di_file = try o.getDIFile(gpa, mod.namespacePtr(owner_decl.src_namespace).file_scope);
2039 const di_scope = try o.namespaceToDebugScope(owner_decl.src_namespace);
2021 const file = try o.getDebugFile(mod.namespacePtr(owner_decl.src_namespace).file_scope);
2022 const scope = try o.namespaceToDebugScope(owner_decl.src_namespace);
20402023
20412024 const name = try o.allocTypeName(ty);
20422025 defer gpa.free(name);
20432026
2044 const enum_di_ty = dib.createEnumerationType(
2045 di_scope,
2046 name,
2047 di_file,
2048 owner_decl.src_node + 1,
2027 const debug_enum_type = try o.builder.debugEnumerationType(
2028 try o.builder.metadataString(name),
2029 file,
2030 scope,
2031 owner_decl.src_node + 1, // Line
2032 try o.lowerDebugType(int_ty),
20492033 ty.abiSize(mod) * 8,
20502034 ty.abiAlignment(mod).toByteUnits(0) * 8,
2051 enumerators.ptr,
2052 @intCast(enumerators.len),
2053 try o.lowerDebugType(int_ty, resolve),
2054 "",
2035 try o.builder.debugTuple(enumerators),
20552036 );
2056 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2057 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(enum_di_ty));
2058 return enum_di_ty;
2037
2038 try o.debug_type_map.put(gpa, ty, debug_enum_type);
2039 try o.debug_enums.append(gpa, debug_enum_type);
2040 return debug_enum_type;
20592041 },
20602042 .Float => {
20612043 const bits = ty.floatBits(target);
20622044 const name = try o.allocTypeName(ty);
20632045 defer gpa.free(name);
2064 const di_type = dib.createBasicType(name, bits, DW.ATE.float);
2065 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
2066 return di_type;
2046 const debug_float_type = try o.builder.debugFloatType(
2047 try o.builder.metadataString(name),
2048 bits,
2049 );
2050 try o.debug_type_map.put(gpa, ty, debug_float_type);
2051 return debug_float_type;
20672052 },
20682053 .Bool => {
2069 const di_bits = 8; // lldb cannot handle non-byte sized types
2070 const di_type = dib.createBasicType("bool", di_bits, DW.ATE.boolean);
2071 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
2072 return di_type;
2054 const debug_bool_type = try o.builder.debugBoolType(
2055 try o.builder.metadataString("bool"),
2056 8, // lldb cannot handle non-byte sized types
2057 );
2058 try o.debug_type_map.put(gpa, ty, debug_bool_type);
2059 return debug_bool_type;
20732060 },
20742061 .Pointer => {
20752062 // Normalize everything that the debug info does not represent.
......@@ -2099,136 +2086,145 @@ pub const Object = struct {
20992086 },
21002087 },
21012088 });
2102 const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve);
2103 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2104 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.init(ptr_di_ty, resolve));
2105 return ptr_di_ty;
2089 const debug_ptr_type = try o.lowerDebugType(bland_ptr_ty);
2090 try o.debug_type_map.put(gpa, ty, debug_ptr_type);
2091 return debug_ptr_type;
21062092 }
21072093
2094 const debug_fwd_ref = try o.builder.debugForwardReference();
2095
2096 // Set as forward reference while the type is lowered in case it references itself
2097 try o.debug_type_map.put(gpa, ty, debug_fwd_ref);
2098
21082099 if (ty.isSlice(mod)) {
21092100 const ptr_ty = ty.slicePtrFieldType(mod);
21102101 const len_ty = Type.usize;
21112102
21122103 const name = try o.allocTypeName(ty);
21132104 defer gpa.free(name);
2114 const di_file: ?*llvm.DIFile = null;
21152105 const line = 0;
2116 const compile_unit_scope = o.di_compile_unit.?.toScope();
2117
2118 const fwd_decl = opt_fwd_decl orelse blk: {
2119 const fwd_decl = dib.createReplaceableCompositeType(
2120 DW.TAG.structure_type,
2121 name.ptr,
2122 compile_unit_scope,
2123 di_file,
2124 line,
2125 );
2126 gop.value_ptr.* = AnnotatedDITypePtr.initFwd(fwd_decl);
2127 if (resolve == .fwd) return fwd_decl;
2128 break :blk fwd_decl;
2129 };
21302106
21312107 const ptr_size = ptr_ty.abiSize(mod);
21322108 const ptr_align = ptr_ty.abiAlignment(mod);
21332109 const len_size = len_ty.abiSize(mod);
21342110 const len_align = len_ty.abiAlignment(mod);
21352111
2136 var offset: u64 = 0;
2137 offset += ptr_size;
2138 offset = len_align.forward(offset);
2139 const len_offset = offset;
2140
2141 const fields: [2]*llvm.DIType = .{
2142 dib.createMemberType(
2143 fwd_decl.toScope(),
2144 "ptr",
2145 di_file,
2146 line,
2147 ptr_size * 8, // size in bits
2148 ptr_align.toByteUnits(0) * 8, // align in bits
2149 0, // offset in bits
2150 0, // flags
2151 try o.lowerDebugType(ptr_ty, resolve),
2152 ),
2153 dib.createMemberType(
2154 fwd_decl.toScope(),
2155 "len",
2156 di_file,
2157 line,
2158 len_size * 8, // size in bits
2159 len_align.toByteUnits(0) * 8, // align in bits
2160 len_offset * 8, // offset in bits
2161 0, // flags
2162 try o.lowerDebugType(len_ty, resolve),
2163 ),
2164 };
2112 const len_offset = len_align.forward(ptr_size);
2113
2114 const debug_ptr_type = try o.builder.debugMemberType(
2115 try o.builder.metadataString("ptr"),
2116 .none, // File
2117 debug_fwd_ref,
2118 0, // Line
2119 try o.lowerDebugType(ptr_ty),
2120 ptr_size * 8,
2121 ptr_align.toByteUnits(0) * 8,
2122 0, // Offset
2123 );
2124
2125 const debug_len_type = try o.builder.debugMemberType(
2126 try o.builder.metadataString("len"),
2127 .none, // File
2128 debug_fwd_ref,
2129 0, // Line
2130 try o.lowerDebugType(len_ty),
2131 len_size * 8,
2132 len_align.toByteUnits(0) * 8,
2133 len_offset * 8,
2134 );
21652135
2166 const full_di_ty = dib.createStructType(
2167 compile_unit_scope,
2168 name.ptr,
2169 di_file,
2136 const debug_slice_type = try o.builder.debugStructType(
2137 try o.builder.metadataString(name),
2138 .none, // File
2139 o.debug_compile_unit, // Scope
21702140 line,
2171 ty.abiSize(mod) * 8, // size in bits
2172 ty.abiAlignment(mod).toByteUnits(0) * 8, // align in bits
2173 0, // flags
2174 null, // derived from
2175 &fields,
2176 fields.len,
2177 0, // run time lang
2178 null, // vtable holder
2179 "", // unique id
2141 .none, // Underlying type
2142 ty.abiSize(mod) * 8,
2143 ty.abiAlignment(mod).toByteUnits(0) * 8,
2144 try o.builder.debugTuple(&.{
2145 debug_ptr_type,
2146 debug_len_type,
2147 }),
21802148 );
2181 dib.replaceTemporary(fwd_decl, full_di_ty);
2182 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2183 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(full_di_ty));
2184 return full_di_ty;
2149
2150 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_slice_type);
2151
2152 // Set to real type now that it has been lowered fully
2153 const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable;
2154 map_ptr.* = debug_slice_type;
2155
2156 return debug_slice_type;
21852157 }
21862158
2187 const elem_di_ty = try o.lowerDebugType(Type.fromInterned(ptr_info.child), .fwd);
2159 const debug_elem_ty = try o.lowerDebugType(Type.fromInterned(ptr_info.child));
2160
21882161 const name = try o.allocTypeName(ty);
21892162 defer gpa.free(name);
2190 const ptr_di_ty = dib.createPointerType(
2191 elem_di_ty,
2163
2164 const debug_ptr_type = try o.builder.debugPointerType(
2165 try o.builder.metadataString(name),
2166 .none, // File
2167 .none, // Scope
2168 0, // Line
2169 debug_elem_ty,
21922170 target.ptrBitWidth(),
21932171 ty.ptrAlignment(mod).toByteUnits(0) * 8,
2194 name,
2172 0, // Offset
21952173 );
2196 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2197 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(ptr_di_ty));
2198 return ptr_di_ty;
2174
2175 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_ptr_type);
2176
2177 // Set to real type now that it has been lowered fully
2178 const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable;
2179 map_ptr.* = debug_ptr_type;
2180
2181 return debug_ptr_type;
21992182 },
22002183 .Opaque => {
22012184 if (ty.toIntern() == .anyopaque_type) {
2202 const di_ty = dib.createBasicType("anyopaque", 0, DW.ATE.signed);
2203 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
2204 return di_ty;
2185 const debug_opaque_type = try o.builder.debugSignedType(
2186 try o.builder.metadataString("anyopaque"),
2187 0,
2188 );
2189 try o.debug_type_map.put(gpa, ty, debug_opaque_type);
2190 return debug_opaque_type;
22052191 }
2192
22062193 const name = try o.allocTypeName(ty);
22072194 defer gpa.free(name);
22082195 const owner_decl_index = ty.getOwnerDecl(mod);
22092196 const owner_decl = o.module.declPtr(owner_decl_index);
2210 const opaque_di_ty = dib.createForwardDeclType(
2211 DW.TAG.structure_type,
2212 name,
2197 const debug_opaque_type = try o.builder.debugStructType(
2198 try o.builder.metadataString(name),
2199 try o.getDebugFile(mod.namespacePtr(owner_decl.src_namespace).file_scope),
22132200 try o.namespaceToDebugScope(owner_decl.src_namespace),
2214 try o.getDIFile(gpa, mod.namespacePtr(owner_decl.src_namespace).file_scope),
2215 owner_decl.src_node + 1,
2201 owner_decl.src_node + 1, // Line
2202 .none, // Underlying type
2203 0, // Size
2204 0, // Align
2205 .none, // Fields
22162206 );
2217 // The recursive call to `lowerDebugType` va `namespaceToDebugScope`
2218 // means we can't use `gop` anymore.
2219 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(opaque_di_ty));
2220 return opaque_di_ty;
2207 try o.debug_type_map.put(gpa, ty, debug_opaque_type);
2208 return debug_opaque_type;
22212209 },
22222210 .Array => {
2223 const array_di_ty = dib.createArrayType(
2211 const debug_array_type = try o.builder.debugArrayType(
2212 .none, // Name
2213 .none, // File
2214 .none, // Scope
2215 0, // Line
2216 try o.lowerDebugType(ty.childType(mod)),
22242217 ty.abiSize(mod) * 8,
22252218 ty.abiAlignment(mod).toByteUnits(0) * 8,
2226 try o.lowerDebugType(ty.childType(mod), resolve),
2227 @intCast(ty.arrayLen(mod)),
2219 try o.builder.debugTuple(&.{
2220 try o.builder.debugSubrange(
2221 try o.builder.debugConstant(try o.builder.intConst(.i64, 0)),
2222 try o.builder.debugConstant(try o.builder.intConst(.i64, ty.arrayLen(mod))),
2223 ),
2224 }),
22282225 );
2229 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2230 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(array_di_ty));
2231 return array_di_ty;
2226 try o.debug_type_map.put(gpa, ty, debug_array_type);
2227 return debug_array_type;
22322228 },
22332229 .Vector => {
22342230 const elem_ty = ty.elemType2(mod);
......@@ -2236,146 +2232,136 @@ pub const Object = struct {
22362232 // @bitSizOf(elem) * len > @bitSizOf(vec).
22372233 // Neither gdb nor lldb seem to be able to display non-byte sized
22382234 // vectors properly.
2239 const elem_di_type = switch (elem_ty.zigTypeTag(mod)) {
2235 const debug_elem_type = switch (elem_ty.zigTypeTag(mod)) {
22402236 .Int => blk: {
22412237 const info = elem_ty.intInfo(mod);
22422238 assert(info.bits != 0);
22432239 const name = try o.allocTypeName(ty);
22442240 defer gpa.free(name);
2245 const dwarf_encoding: c_uint = switch (info.signedness) {
2246 .signed => DW.ATE.signed,
2247 .unsigned => DW.ATE.unsigned,
2241 const builder_name = try o.builder.metadataString(name);
2242 break :blk switch (info.signedness) {
2243 .signed => try o.builder.debugSignedType(builder_name, info.bits),
2244 .unsigned => try o.builder.debugUnsignedType(builder_name, info.bits),
22482245 };
2249 break :blk dib.createBasicType(name, info.bits, dwarf_encoding);
22502246 },
2251 .Bool => dib.createBasicType("bool", 1, DW.ATE.boolean),
2252 else => try o.lowerDebugType(ty.childType(mod), resolve),
2247 .Bool => try o.builder.debugBoolType(
2248 try o.builder.metadataString("bool"),
2249 1,
2250 ),
2251 else => try o.lowerDebugType(ty.childType(mod)),
22532252 };
22542253
2255 const vector_di_ty = dib.createVectorType(
2254 const debug_vector_type = try o.builder.debugVectorType(
2255 .none, // Name
2256 .none, // File
2257 .none, // Scope
2258 0, // Line
2259 debug_elem_type,
22562260 ty.abiSize(mod) * 8,
2257 @intCast(ty.abiAlignment(mod).toByteUnits(0) * 8),
2258 elem_di_type,
2259 ty.vectorLen(mod),
2261 ty.abiAlignment(mod).toByteUnits(0) * 8,
2262 try o.builder.debugTuple(&.{
2263 try o.builder.debugSubrange(
2264 try o.builder.debugConstant(try o.builder.intConst(.i64, 0)),
2265 try o.builder.debugConstant(try o.builder.intConst(.i64, ty.vectorLen(mod))),
2266 ),
2267 }),
22602268 );
2261 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2262 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(vector_di_ty));
2263 return vector_di_ty;
2269
2270 try o.debug_type_map.put(gpa, ty, debug_vector_type);
2271 return debug_vector_type;
22642272 },
22652273 .Optional => {
22662274 const name = try o.allocTypeName(ty);
22672275 defer gpa.free(name);
22682276 const child_ty = ty.optionalChild(mod);
22692277 if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2270 const di_bits = 8; // lldb cannot handle non-byte sized types
2271 const di_ty = dib.createBasicType(name, di_bits, DW.ATE.boolean);
2272 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
2273 return di_ty;
2278 const debug_bool_type = try o.builder.debugBoolType(
2279 try o.builder.metadataString(name),
2280 8,
2281 );
2282 try o.debug_type_map.put(gpa, ty, debug_bool_type);
2283 return debug_bool_type;
22742284 }
2285
2286 const debug_fwd_ref = try o.builder.debugForwardReference();
2287
2288 // Set as forward reference while the type is lowered in case it references itself
2289 try o.debug_type_map.put(gpa, ty, debug_fwd_ref);
2290
22752291 if (ty.optionalReprIsPayload(mod)) {
2276 const ptr_di_ty = try o.lowerDebugType(child_ty, resolve);
2277 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2278 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.init(ptr_di_ty, resolve));
2279 return ptr_di_ty;
2280 }
2292 const debug_optional_type = try o.lowerDebugType(child_ty);
22812293
2282 const di_file: ?*llvm.DIFile = null;
2283 const line = 0;
2284 const compile_unit_scope = o.di_compile_unit.?.toScope();
2285 const fwd_decl = opt_fwd_decl orelse blk: {
2286 const fwd_decl = dib.createReplaceableCompositeType(
2287 DW.TAG.structure_type,
2288 name.ptr,
2289 compile_unit_scope,
2290 di_file,
2291 line,
2292 );
2293 gop.value_ptr.* = AnnotatedDITypePtr.initFwd(fwd_decl);
2294 if (resolve == .fwd) return fwd_decl;
2295 break :blk fwd_decl;
2296 };
2294 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_optional_type);
2295
2296 // Set to real type now that it has been lowered fully
2297 const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable;
2298 map_ptr.* = debug_optional_type;
2299
2300 return debug_optional_type;
2301 }
22972302
22982303 const non_null_ty = Type.u8;
22992304 const payload_size = child_ty.abiSize(mod);
23002305 const payload_align = child_ty.abiAlignment(mod);
23012306 const non_null_size = non_null_ty.abiSize(mod);
23022307 const non_null_align = non_null_ty.abiAlignment(mod);
2308 const non_null_offset = non_null_align.forward(payload_size);
2309
2310 const debug_data_type = try o.builder.debugMemberType(
2311 try o.builder.metadataString("data"),
2312 .none, // File
2313 debug_fwd_ref,
2314 0, // Line
2315 try o.lowerDebugType(child_ty),
2316 payload_size * 8,
2317 payload_align.toByteUnits(0) * 8,
2318 0, // Offset
2319 );
23032320
2304 var offset: u64 = 0;
2305 offset += payload_size;
2306 offset = non_null_align.forward(offset);
2307 const non_null_offset = offset;
2308
2309 const fields: [2]*llvm.DIType = .{
2310 dib.createMemberType(
2311 fwd_decl.toScope(),
2312 "data",
2313 di_file,
2314 line,
2315 payload_size * 8, // size in bits
2316 payload_align.toByteUnits(0) * 8, // align in bits
2317 0, // offset in bits
2318 0, // flags
2319 try o.lowerDebugType(child_ty, resolve),
2320 ),
2321 dib.createMemberType(
2322 fwd_decl.toScope(),
2323 "some",
2324 di_file,
2325 line,
2326 non_null_size * 8, // size in bits
2327 non_null_align.toByteUnits(0) * 8, // align in bits
2328 non_null_offset * 8, // offset in bits
2329 0, // flags
2330 try o.lowerDebugType(non_null_ty, resolve),
2331 ),
2332 };
2321 const debug_some_type = try o.builder.debugMemberType(
2322 try o.builder.metadataString("some"),
2323 .none,
2324 debug_fwd_ref,
2325 0,
2326 try o.lowerDebugType(non_null_ty),
2327 non_null_size * 8,
2328 non_null_align.toByteUnits(0) * 8,
2329 non_null_offset * 8,
2330 );
23332331
2334 const full_di_ty = dib.createStructType(
2335 compile_unit_scope,
2336 name.ptr,
2337 di_file,
2338 line,
2339 ty.abiSize(mod) * 8, // size in bits
2340 ty.abiAlignment(mod).toByteUnits(0) * 8, // align in bits
2341 0, // flags
2342 null, // derived from
2343 &fields,
2344 fields.len,
2345 0, // run time lang
2346 null, // vtable holder
2347 "", // unique id
2332 const debug_optional_type = try o.builder.debugStructType(
2333 try o.builder.metadataString(name),
2334 .none, // File
2335 o.debug_compile_unit, // Scope
2336 0, // Line
2337 .none, // Underlying type
2338 ty.abiSize(mod) * 8,
2339 ty.abiAlignment(mod).toByteUnits(0) * 8,
2340 try o.builder.debugTuple(&.{
2341 debug_data_type,
2342 debug_some_type,
2343 }),
23482344 );
2349 dib.replaceTemporary(fwd_decl, full_di_ty);
2350 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2351 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(full_di_ty));
2352 return full_di_ty;
2345
2346 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_optional_type);
2347
2348 // Set to real type now that it has been lowered fully
2349 const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable;
2350 map_ptr.* = debug_optional_type;
2351
2352 return debug_optional_type;
23532353 },
23542354 .ErrorUnion => {
23552355 const payload_ty = ty.errorUnionPayload(mod);
23562356 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2357 const err_set_di_ty = try o.lowerDebugType(Type.anyerror, resolve);
2358 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2359 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(err_set_di_ty));
2360 return err_set_di_ty;
2357 // TODO: Maybe remove?
2358 const debug_error_union_type = try o.lowerDebugType(Type.anyerror);
2359 try o.debug_type_map.put(gpa, ty, debug_error_union_type);
2360 return debug_error_union_type;
23612361 }
2362
23622363 const name = try o.allocTypeName(ty);
23632364 defer gpa.free(name);
2364 const di_file: ?*llvm.DIFile = null;
2365 const line = 0;
2366 const compile_unit_scope = o.di_compile_unit.?.toScope();
2367 const fwd_decl = opt_fwd_decl orelse blk: {
2368 const fwd_decl = dib.createReplaceableCompositeType(
2369 DW.TAG.structure_type,
2370 name.ptr,
2371 compile_unit_scope,
2372 di_file,
2373 line,
2374 );
2375 gop.value_ptr.* = AnnotatedDITypePtr.initFwd(fwd_decl);
2376 if (resolve == .fwd) return fwd_decl;
2377 break :blk fwd_decl;
2378 };
23792365
23802366 const error_size = Type.anyerror.abiSize(mod);
23812367 const error_align = Type.anyerror.abiAlignment(mod);
......@@ -2398,59 +2384,55 @@ pub const Object = struct {
23982384 error_offset = error_align.forward(payload_size);
23992385 }
24002386
2401 var fields: [2]*llvm.DIType = undefined;
2402 fields[error_index] = dib.createMemberType(
2403 fwd_decl.toScope(),
2404 "tag",
2405 di_file,
2406 line,
2407 error_size * 8, // size in bits
2408 error_align.toByteUnits(0) * 8, // align in bits
2409 error_offset * 8, // offset in bits
2410 0, // flags
2411 try o.lowerDebugType(Type.anyerror, resolve),
2387 const debug_fwd_ref = try o.builder.debugForwardReference();
2388
2389 var fields: [2]Builder.Metadata = undefined;
2390 fields[error_index] = try o.builder.debugMemberType(
2391 try o.builder.metadataString("tag"),
2392 .none, // File
2393 debug_fwd_ref,
2394 0, // Line
2395 try o.lowerDebugType(Type.anyerror),
2396 error_size * 8,
2397 error_align.toByteUnits(0) * 8,
2398 error_offset * 8,
24122399 );
2413 fields[payload_index] = dib.createMemberType(
2414 fwd_decl.toScope(),
2415 "value",
2416 di_file,
2417 line,
2418 payload_size * 8, // size in bits
2419 payload_align.toByteUnits(0) * 8, // align in bits
2420 payload_offset * 8, // offset in bits
2421 0, // flags
2422 try o.lowerDebugType(payload_ty, resolve),
2400 fields[payload_index] = try o.builder.debugMemberType(
2401 try o.builder.metadataString("value"),
2402 .none, // File
2403 debug_fwd_ref,
2404 0, // Line
2405 try o.lowerDebugType(payload_ty),
2406 payload_size * 8,
2407 payload_align.toByteUnits(0) * 8,
2408 payload_offset * 8,
24232409 );
24242410
2425 const full_di_ty = dib.createStructType(
2426 compile_unit_scope,
2427 name.ptr,
2428 di_file,
2429 line,
2430 ty.abiSize(mod) * 8, // size in bits
2431 ty.abiAlignment(mod).toByteUnits(0) * 8, // align in bits
2432 0, // flags
2433 null, // derived from
2434 &fields,
2435 fields.len,
2436 0, // run time lang
2437 null, // vtable holder
2438 "", // unique id
2411 const debug_error_union_type = try o.builder.debugStructType(
2412 try o.builder.metadataString(name),
2413 .none, // File
2414 o.debug_compile_unit, // Sope
2415 0, // Line
2416 .none, // Underlying type
2417 ty.abiSize(mod) * 8,
2418 ty.abiAlignment(mod).toByteUnits(0) * 8,
2419 try o.builder.debugTuple(&fields),
24392420 );
2440 dib.replaceTemporary(fwd_decl, full_di_ty);
2441 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2442 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(full_di_ty));
2443 return full_di_ty;
2421
2422 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_error_union_type);
2423
2424 try o.debug_type_map.put(gpa, ty, debug_error_union_type);
2425 return debug_error_union_type;
24442426 },
24452427 .ErrorSet => {
2446 // TODO make this a proper enum with all the error codes in it.
2447 // will need to consider how to take incremental compilation into account.
2448 const di_ty = dib.createBasicType("anyerror", 16, DW.ATE.unsigned);
2449 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
2450 return di_ty;
2428 const debug_error_set = try o.builder.debugUnsignedType(
2429 try o.builder.metadataString("anyerror"),
2430 16,
2431 );
2432 try o.debug_type_map.put(gpa, ty, debug_error_set);
2433 return debug_error_set;
24512434 },
24522435 .Struct => {
2453 const compile_unit_scope = o.di_compile_unit.?.toScope();
24542436 const name = try o.allocTypeName(ty);
24552437 defer gpa.free(name);
24562438
......@@ -2458,40 +2440,28 @@ pub const Object = struct {
24582440 const backing_int_ty = struct_type.backingIntType(ip).*;
24592441 if (backing_int_ty != .none) {
24602442 const info = Type.fromInterned(backing_int_ty).intInfo(mod);
2461 const dwarf_encoding: c_uint = switch (info.signedness) {
2462 .signed => DW.ATE.signed,
2463 .unsigned => DW.ATE.unsigned,
2443 const builder_name = try o.builder.metadataString(name);
2444 const debug_int_type = switch (info.signedness) {
2445 .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(mod) * 8),
2446 .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(mod) * 8),
24642447 };
2465 const di_bits = ty.abiSize(mod) * 8; // lldb cannot handle non-byte sized types
2466 const di_ty = dib.createBasicType(name, di_bits, dwarf_encoding);
2467 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
2468 return di_ty;
2448 try o.debug_type_map.put(gpa, ty, debug_int_type);
2449 return debug_int_type;
24692450 }
24702451 }
24712452
2472 const fwd_decl = opt_fwd_decl orelse blk: {
2473 const fwd_decl = dib.createReplaceableCompositeType(
2474 DW.TAG.structure_type,
2475 name.ptr,
2476 compile_unit_scope,
2477 null, // file
2478 0, // line
2479 );
2480 gop.value_ptr.* = AnnotatedDITypePtr.initFwd(fwd_decl);
2481 if (resolve == .fwd) return fwd_decl;
2482 break :blk fwd_decl;
2483 };
2484
24852453 switch (ip.indexToKey(ty.toIntern())) {
24862454 .anon_struct_type => |tuple| {
2487 var di_fields: std.ArrayListUnmanaged(*llvm.DIType) = .{};
2488 defer di_fields.deinit(gpa);
2455 var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{};
2456 defer fields.deinit(gpa);
24892457
2490 try di_fields.ensureUnusedCapacity(gpa, tuple.types.len);
2458 try fields.ensureUnusedCapacity(gpa, tuple.types.len);
24912459
24922460 comptime assert(struct_layout_version == 2);
24932461 var offset: u64 = 0;
24942462
2463 const debug_fwd_ref = try o.builder.debugForwardReference();
2464
24952465 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
24962466 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue;
24972467
......@@ -2506,38 +2476,33 @@ pub const Object = struct {
25062476 try std.fmt.allocPrintZ(gpa, "{d}", .{i});
25072477 defer if (tuple.names.len == 0) gpa.free(field_name);
25082478
2509 try di_fields.append(gpa, dib.createMemberType(
2510 fwd_decl.toScope(),
2511 field_name,
2512 null, // file
2513 0, // line
2514 field_size * 8, // size in bits
2515 field_align.toByteUnits(0) * 8, // align in bits
2516 field_offset * 8, // offset in bits
2517 0, // flags
2518 try o.lowerDebugType(Type.fromInterned(field_ty), resolve),
2479 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2480 try o.builder.metadataString(field_name),
2481 .none, // File
2482 debug_fwd_ref,
2483 0,
2484 try o.lowerDebugType(Type.fromInterned(field_ty)),
2485 field_size * 8,
2486 field_align.toByteUnits(0) * 8,
2487 field_offset * 8,
25192488 ));
25202489 }
25212490
2522 const full_di_ty = dib.createStructType(
2523 compile_unit_scope,
2524 name.ptr,
2525 null, // file
2526 0, // line
2527 ty.abiSize(mod) * 8, // size in bits
2528 ty.abiAlignment(mod).toByteUnits(0) * 8, // align in bits
2529 0, // flags
2530 null, // derived from
2531 di_fields.items.ptr,
2532 @intCast(di_fields.items.len),
2533 0, // run time lang
2534 null, // vtable holder
2535 "", // unique id
2491 const debug_struct_type = try o.builder.debugStructType(
2492 try o.builder.metadataString(name),
2493 .none, // File
2494 o.debug_compile_unit, // Scope
2495 0, // Line
2496 .none, // Underlying type
2497 ty.abiSize(mod) * 8,
2498 ty.abiAlignment(mod).toByteUnits(0) * 8,
2499 try o.builder.debugTuple(fields.items),
25362500 );
2537 dib.replaceTemporary(fwd_decl, full_di_ty);
2538 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2539 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(full_di_ty));
2540 return full_di_ty;
2501
2502 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_struct_type);
2503
2504 try o.debug_type_map.put(gpa, ty, debug_struct_type);
2505 return debug_struct_type;
25412506 },
25422507 .struct_type => |struct_type| {
25432508 if (!struct_type.haveFieldTypes(ip)) {
......@@ -2549,12 +2514,9 @@ pub const Object = struct {
25492514 // rather than changing the frontend to unnecessarily resolve the
25502515 // struct field types.
25512516 const owner_decl_index = ty.getOwnerDecl(mod);
2552 const struct_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
2553 dib.replaceTemporary(fwd_decl, struct_di_ty);
2554 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
2555 // means we can't use `gop` anymore.
2556 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(struct_di_ty));
2557 return struct_di_ty;
2517 const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
2518 try o.debug_type_map.put(gpa, ty, debug_struct_type);
2519 return debug_struct_type;
25582520 }
25592521 },
25602522 else => {},
......@@ -2562,20 +2524,22 @@ pub const Object = struct {
25622524
25632525 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) {
25642526 const owner_decl_index = ty.getOwnerDecl(mod);
2565 const struct_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
2566 dib.replaceTemporary(fwd_decl, struct_di_ty);
2567 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
2568 // means we can't use `gop` anymore.
2569 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(struct_di_ty));
2570 return struct_di_ty;
2527 const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
2528 try o.debug_type_map.put(gpa, ty, debug_struct_type);
2529 return debug_struct_type;
25712530 }
25722531
25732532 const struct_type = mod.typeToStruct(ty).?;
25742533
2575 var di_fields: std.ArrayListUnmanaged(*llvm.DIType) = .{};
2576 defer di_fields.deinit(gpa);
2534 var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{};
2535 defer fields.deinit(gpa);
2536
2537 try fields.ensureUnusedCapacity(gpa, struct_type.field_types.len);
2538
2539 const debug_fwd_ref = try o.builder.debugForwardReference();
25772540
2578 try di_fields.ensureUnusedCapacity(gpa, struct_type.field_types.len);
2541 // Set as forward reference while the type is lowered in case it references itself
2542 try o.debug_type_map.put(gpa, ty, debug_fwd_ref);
25792543
25802544 comptime assert(struct_layout_version == 2);
25812545 var it = struct_type.iterateRuntimeOrder(ip);
......@@ -2593,103 +2557,88 @@ pub const Object = struct {
25932557 const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse
25942558 try ip.getOrPutStringFmt(gpa, "{d}", .{field_index});
25952559
2596 const field_di_ty = try o.lowerDebugType(field_ty, resolve);
2597
2598 try di_fields.append(gpa, dib.createMemberType(
2599 fwd_decl.toScope(),
2600 ip.stringToSlice(field_name),
2601 null, // file
2602 0, // line
2603 field_size * 8, // size in bits
2604 field_align.toByteUnits(0) * 8, // align in bits
2605 field_offset * 8, // offset in bits
2606 0, // flags
2607 field_di_ty,
2560 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2561 try o.builder.metadataString(ip.stringToSlice(field_name)),
2562 .none, // File
2563 debug_fwd_ref,
2564 0, // Line
2565 try o.lowerDebugType(field_ty),
2566 field_size * 8,
2567 field_align.toByteUnits(0) * 8,
2568 field_offset * 8,
26082569 ));
26092570 }
26102571
2611 const full_di_ty = dib.createStructType(
2612 compile_unit_scope,
2613 name.ptr,
2614 null, // file
2615 0, // line
2616 ty.abiSize(mod) * 8, // size in bits
2617 ty.abiAlignment(mod).toByteUnits(0) * 8, // align in bits
2618 0, // flags
2619 null, // derived from
2620 di_fields.items.ptr,
2621 @intCast(di_fields.items.len),
2622 0, // run time lang
2623 null, // vtable holder
2624 "", // unique id
2572 const debug_struct_type = try o.builder.debugStructType(
2573 try o.builder.metadataString(name),
2574 .none, // File
2575 o.debug_compile_unit, // Scope
2576 0, // Line
2577 .none, // Underlying type
2578 ty.abiSize(mod) * 8,
2579 ty.abiAlignment(mod).toByteUnits(0) * 8,
2580 try o.builder.debugTuple(fields.items),
26252581 );
2626 dib.replaceTemporary(fwd_decl, full_di_ty);
2627 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2628 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(full_di_ty));
2629 return full_di_ty;
2582
2583 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_struct_type);
2584
2585 // Set to real type now that it has been lowered fully
2586 const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable;
2587 map_ptr.* = debug_struct_type;
2588
2589 return debug_struct_type;
26302590 },
26312591 .Union => {
2632 const compile_unit_scope = o.di_compile_unit.?.toScope();
26332592 const owner_decl_index = ty.getOwnerDecl(mod);
26342593
26352594 const name = try o.allocTypeName(ty);
26362595 defer gpa.free(name);
26372596
2638 const fwd_decl = opt_fwd_decl orelse blk: {
2639 const fwd_decl = dib.createReplaceableCompositeType(
2640 DW.TAG.structure_type,
2641 name.ptr,
2642 o.di_compile_unit.?.toScope(),
2643 null, // file
2644 0, // line
2645 );
2646 gop.value_ptr.* = AnnotatedDITypePtr.initFwd(fwd_decl);
2647 if (resolve == .fwd) return fwd_decl;
2648 break :blk fwd_decl;
2649 };
2650
26512597 const union_type = ip.indexToKey(ty.toIntern()).union_type;
26522598 if (!union_type.haveFieldTypes(ip) or !ty.hasRuntimeBitsIgnoreComptime(mod)) {
2653 const union_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
2654 dib.replaceTemporary(fwd_decl, union_di_ty);
2655 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
2656 // means we can't use `gop` anymore.
2657 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(union_di_ty));
2658 return union_di_ty;
2599 const debug_union_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
2600 try o.debug_type_map.put(gpa, ty, debug_union_type);
2601 return debug_union_type;
26592602 }
26602603
26612604 const union_obj = ip.loadUnionType(union_type);
26622605 const layout = mod.getUnionLayout(union_obj);
26632606
2607 const debug_fwd_ref = try o.builder.debugForwardReference();
2608
2609 // Set as forward reference while the type is lowered in case it references itself
2610 try o.debug_type_map.put(gpa, ty, debug_fwd_ref);
2611
26642612 if (layout.payload_size == 0) {
2665 const tag_di_ty = try o.lowerDebugType(Type.fromInterned(union_obj.enum_tag_ty), resolve);
2666 const di_fields = [_]*llvm.DIType{tag_di_ty};
2667 const full_di_ty = dib.createStructType(
2668 compile_unit_scope,
2669 name.ptr,
2670 null, // file
2671 0, // line
2672 ty.abiSize(mod) * 8, // size in bits
2673 ty.abiAlignment(mod).toByteUnits(0) * 8, // align in bits
2674 0, // flags
2675 null, // derived from
2676 &di_fields,
2677 di_fields.len,
2678 0, // run time lang
2679 null, // vtable holder
2680 "", // unique id
2613 const debug_union_type = try o.builder.debugStructType(
2614 try o.builder.metadataString(name),
2615 .none, // File
2616 o.debug_compile_unit, // Scope
2617 0, // Line
2618 .none, // Underlying type
2619 ty.abiSize(mod) * 8,
2620 ty.abiAlignment(mod).toByteUnits(0) * 8,
2621 try o.builder.debugTuple(
2622 &.{try o.lowerDebugType(Type.fromInterned(union_obj.enum_tag_ty))},
2623 ),
26812624 );
2682 dib.replaceTemporary(fwd_decl, full_di_ty);
2683 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
2684 // means we can't use `gop` anymore.
2685 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(full_di_ty));
2686 return full_di_ty;
2625
2626 // Set to real type now that it has been lowered fully
2627 const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable;
2628 map_ptr.* = debug_union_type;
2629
2630 return debug_union_type;
26872631 }
26882632
2689 var di_fields: std.ArrayListUnmanaged(*llvm.DIType) = .{};
2690 defer di_fields.deinit(gpa);
2633 var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{};
2634 defer fields.deinit(gpa);
2635
2636 try fields.ensureUnusedCapacity(gpa, union_obj.field_names.len);
26912637
2692 try di_fields.ensureUnusedCapacity(gpa, union_obj.field_names.len);
2638 const debug_union_fwd_ref = if (layout.tag_size == 0)
2639 debug_fwd_ref
2640 else
2641 try o.builder.debugForwardReference();
26932642
26942643 for (0..union_obj.field_names.len) |field_index| {
26952644 const field_ty = union_obj.field_types.get(ip)[field_index];
......@@ -2698,18 +2647,16 @@ pub const Object = struct {
26982647 const field_size = Type.fromInterned(field_ty).abiSize(mod);
26992648 const field_align = mod.unionFieldNormalAlignment(union_obj, @intCast(field_index));
27002649
2701 const field_di_ty = try o.lowerDebugType(Type.fromInterned(field_ty), resolve);
27022650 const field_name = union_obj.field_names.get(ip)[field_index];
2703 di_fields.appendAssumeCapacity(dib.createMemberType(
2704 fwd_decl.toScope(),
2705 ip.stringToSlice(field_name),
2706 null, // file
2707 0, // line
2708 field_size * 8, // size in bits
2709 field_align.toByteUnits(0) * 8, // align in bits
2710 0, // offset in bits
2711 0, // flags
2712 field_di_ty,
2651 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2652 try o.builder.metadataString(ip.stringToSlice(field_name)),
2653 .none, // File
2654 debug_union_fwd_ref,
2655 0, // Line
2656 try o.lowerDebugType(Type.fromInterned(field_ty)),
2657 field_size * 8,
2658 field_align.toByteUnits(0) * 8,
2659 0, // Offset
27132660 ));
27142661 }
27152662
......@@ -2720,25 +2667,25 @@ pub const Object = struct {
27202667 break :name union_name_buf.?;
27212668 };
27222669
2723 const union_di_ty = dib.createUnionType(
2724 compile_unit_scope,
2725 union_name.ptr,
2726 null, // file
2727 0, // line
2728 ty.abiSize(mod) * 8, // size in bits
2729 ty.abiAlignment(mod).toByteUnits(0) * 8, // align in bits
2730 0, // flags
2731 di_fields.items.ptr,
2732 @intCast(di_fields.items.len),
2733 0, // run time lang
2734 "", // unique id
2670 const debug_union_type = try o.builder.debugUnionType(
2671 try o.builder.metadataString(union_name),
2672 .none, // File
2673 o.debug_compile_unit, // Scope
2674 0, // Line
2675 .none, // Underlying type
2676 ty.abiSize(mod) * 8,
2677 ty.abiAlignment(mod).toByteUnits(0) * 8,
2678 try o.builder.debugTuple(fields.items),
27352679 );
27362680
2681 o.builder.debugForwardReferenceSetType(debug_union_fwd_ref, debug_union_type);
2682
27372683 if (layout.tag_size == 0) {
2738 dib.replaceTemporary(fwd_decl, union_di_ty);
2739 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2740 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(union_di_ty));
2741 return union_di_ty;
2684 // Set to real type now that it has been lowered fully
2685 const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable;
2686 map_ptr.* = debug_union_type;
2687
2688 return debug_union_type;
27422689 }
27432690
27442691 var tag_offset: u64 = undefined;
......@@ -2751,81 +2698,80 @@ pub const Object = struct {
27512698 tag_offset = layout.tag_align.forward(layout.payload_size);
27522699 }
27532700
2754 const tag_di = dib.createMemberType(
2755 fwd_decl.toScope(),
2756 "tag",
2757 null, // file
2758 0, // line
2701 const debug_tag_type = try o.builder.debugMemberType(
2702 try o.builder.metadataString("tag"),
2703 .none, // File
2704 debug_fwd_ref,
2705 0, // Line
2706 try o.lowerDebugType(Type.fromInterned(union_obj.enum_tag_ty)),
27592707 layout.tag_size * 8,
27602708 layout.tag_align.toByteUnits(0) * 8,
2761 tag_offset * 8, // offset in bits
2762 0, // flags
2763 try o.lowerDebugType(Type.fromInterned(union_obj.enum_tag_ty), resolve),
2709 tag_offset * 8,
27642710 );
27652711
2766 const payload_di = dib.createMemberType(
2767 fwd_decl.toScope(),
2768 "payload",
2769 null, // file
2770 0, // line
2771 layout.payload_size * 8, // size in bits
2712 const debug_payload_type = try o.builder.debugMemberType(
2713 try o.builder.metadataString("payload"),
2714 .none, // File
2715 debug_fwd_ref,
2716 0, // Line
2717 debug_union_type,
2718 layout.payload_size * 8,
27722719 layout.payload_align.toByteUnits(0) * 8,
2773 payload_offset * 8, // offset in bits
2774 0, // flags
2775 union_di_ty,
2720 payload_offset * 8,
27762721 );
27772722
2778 const full_di_fields: [2]*llvm.DIType =
2723 const full_fields: [2]Builder.Metadata =
27792724 if (layout.tag_align.compare(.gte, layout.payload_align))
2780 .{ tag_di, payload_di }
2725 .{ debug_tag_type, debug_payload_type }
27812726 else
2782 .{ payload_di, tag_di };
2783
2784 const full_di_ty = dib.createStructType(
2785 compile_unit_scope,
2786 name.ptr,
2787 null, // file
2788 0, // line
2789 ty.abiSize(mod) * 8, // size in bits
2790 ty.abiAlignment(mod).toByteUnits(0) * 8, // align in bits
2791 0, // flags
2792 null, // derived from
2793 &full_di_fields,
2794 full_di_fields.len,
2795 0, // run time lang
2796 null, // vtable holder
2797 "", // unique id
2727 .{ debug_payload_type, debug_tag_type };
2728
2729 const debug_tagged_union_type = try o.builder.debugStructType(
2730 try o.builder.metadataString(name),
2731 .none, // File
2732 o.debug_compile_unit, // Scope
2733 0, // Line
2734 .none, // Underlying type
2735 ty.abiSize(mod) * 8,
2736 ty.abiAlignment(mod).toByteUnits(0) * 8,
2737 try o.builder.debugTuple(&full_fields),
27982738 );
2799 dib.replaceTemporary(fwd_decl, full_di_ty);
2800 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2801 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(full_di_ty));
2802 return full_di_ty;
2739
2740 o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_tagged_union_type);
2741
2742 // Set to real type now that it has been lowered fully
2743 const map_ptr = o.debug_type_map.getPtr(ty) orelse unreachable;
2744 map_ptr.* = debug_tagged_union_type;
2745
2746 return debug_tagged_union_type;
28032747 },
28042748 .Fn => {
28052749 const fn_info = mod.typeToFunc(ty).?;
28062750
2807 var param_di_types = std.ArrayList(*llvm.DIType).init(gpa);
2808 defer param_di_types.deinit();
2751 var debug_param_types = std.ArrayList(Builder.Metadata).init(gpa);
2752 defer debug_param_types.deinit();
2753
2754 try debug_param_types.ensureUnusedCapacity(3 + fn_info.param_types.len);
28092755
28102756 // Return type goes first.
28112757 if (Type.fromInterned(fn_info.return_type).hasRuntimeBitsIgnoreComptime(mod)) {
28122758 const sret = firstParamSRet(fn_info, mod);
2813 const di_ret_ty = if (sret) Type.void else Type.fromInterned(fn_info.return_type);
2814 try param_di_types.append(try o.lowerDebugType(di_ret_ty, resolve));
2759 const ret_ty = if (sret) Type.void else Type.fromInterned(fn_info.return_type);
2760 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ret_ty));
28152761
28162762 if (sret) {
28172763 const ptr_ty = try mod.singleMutPtrType(Type.fromInterned(fn_info.return_type));
2818 try param_di_types.append(try o.lowerDebugType(ptr_ty, resolve));
2764 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty));
28192765 }
28202766 } else {
2821 try param_di_types.append(try o.lowerDebugType(Type.void, resolve));
2767 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(Type.void));
28222768 }
28232769
28242770 if (Type.fromInterned(fn_info.return_type).isError(mod) and
28252771 o.module.comp.config.any_error_tracing)
28262772 {
28272773 const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType());
2828 try param_di_types.append(try o.lowerDebugType(ptr_ty, resolve));
2774 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty));
28292775 }
28302776
28312777 for (0..fn_info.param_types.len) |i| {
......@@ -2834,20 +2780,18 @@ pub const Object = struct {
28342780
28352781 if (isByRef(param_ty, mod)) {
28362782 const ptr_ty = try mod.singleMutPtrType(param_ty);
2837 try param_di_types.append(try o.lowerDebugType(ptr_ty, resolve));
2783 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty));
28382784 } else {
2839 try param_di_types.append(try o.lowerDebugType(param_ty, resolve));
2785 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(param_ty));
28402786 }
28412787 }
28422788
2843 const fn_di_ty = dib.createSubroutineType(
2844 param_di_types.items.ptr,
2845 @intCast(param_di_types.items.len),
2846 0,
2789 const debug_function_type = try o.builder.debugSubroutineType(
2790 try o.builder.debugTuple(debug_param_types.items),
28472791 );
2848 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2849 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(fn_di_ty));
2850 return fn_di_ty;
2792
2793 try o.debug_type_map.put(gpa, ty, debug_function_type);
2794 return debug_function_type;
28512795 },
28522796 .ComptimeInt => unreachable,
28532797 .ComptimeFloat => unreachable,
......@@ -2861,39 +2805,30 @@ pub const Object = struct {
28612805 }
28622806 }
28632807
2864 fn namespaceToDebugScope(o: *Object, namespace_index: InternPool.NamespaceIndex) !*llvm.DIScope {
2808 fn namespaceToDebugScope(o: *Object, namespace_index: InternPool.NamespaceIndex) !Builder.Metadata {
28652809 const mod = o.module;
28662810 const namespace = mod.namespacePtr(namespace_index);
2867 if (namespace.parent == .none) {
2868 const di_file = try o.getDIFile(o.gpa, namespace.file_scope);
2869 return di_file.toScope();
2870 }
2871 const di_type = try o.lowerDebugType(namespace.ty, .fwd);
2872 return di_type.toScope();
2811 if (namespace.parent == .none) return try o.getDebugFile(namespace.file_scope);
2812
2813 const gop = try o.debug_unresolved_namespace_scopes.getOrPut(o.gpa, namespace_index);
2814
2815 if (!gop.found_existing) gop.value_ptr.* = try o.builder.debugForwardReference();
2816
2817 return gop.value_ptr.*;
28732818 }
28742819
2875 /// This is to be used instead of void for debug info types, to avoid tripping
2876 /// Assertion `!isa<DIType>(Scope) && "shouldn't make a namespace scope for a type"'
2877 /// when targeting CodeView (Windows).
2878 fn makeEmptyNamespaceDIType(o: *Object, decl_index: InternPool.DeclIndex) !*llvm.DIType {
2820 fn makeEmptyNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex) !Builder.Metadata {
28792821 const mod = o.module;
28802822 const decl = mod.declPtr(decl_index);
2881 const fields: [0]*llvm.DIType = .{};
2882 const di_scope = try o.namespaceToDebugScope(decl.src_namespace);
2883 return o.di_builder.?.createStructType(
2884 di_scope,
2885 mod.intern_pool.stringToSlice(decl.name), // TODO use fully qualified name
2886 try o.getDIFile(o.gpa, mod.namespacePtr(decl.src_namespace).file_scope),
2823 return o.builder.debugStructType(
2824 try o.builder.metadataString(mod.intern_pool.stringToSlice(decl.name)), // TODO use fully qualified name
2825 try o.getDebugFile(mod.namespacePtr(decl.src_namespace).file_scope),
2826 try o.namespaceToDebugScope(decl.src_namespace),
28872827 decl.src_line + 1,
2888 0, // size in bits
2889 0, // align in bits
2890 0, // flags
2891 null, // derived from
2892 undefined, // TODO should be able to pass &fields,
2893 fields.len,
2894 0, // run time lang
2895 null, // vtable holder
2896 "", // unique id
2828 .none,
2829 0,
2830 0,
2831 .none,
28972832 );
28982833 }
28992834
......@@ -3202,26 +3137,6 @@ pub const Object = struct {
32023137 }
32033138
32043139 fn lowerType(o: *Object, t: Type) Allocator.Error!Builder.Type {
3205 const ty = try o.lowerTypeInner(t);
3206 const mod = o.module;
3207 if (std.debug.runtime_safety and o.builder.useLibLlvm() and false) check: {
3208 const llvm_ty = ty.toLlvm(&o.builder);
3209 if (t.zigTypeTag(mod) == .Opaque) break :check;
3210 if (!t.hasRuntimeBits(mod)) break :check;
3211 if (!try ty.isSized(&o.builder)) break :check;
3212
3213 const zig_size = t.abiSize(mod);
3214 const llvm_size = o.target_data.abiSizeOfType(llvm_ty);
3215 if (llvm_size != zig_size) {
3216 log.err("when lowering {}, Zig ABI size = {d} but LLVM ABI size = {d}", .{
3217 t.fmt(o.module), zig_size, llvm_size,
3218 });
3219 }
3220 }
3221 return ty;
3222 }
3223
3224 fn lowerTypeInner(o: *Object, t: Type) Allocator.Error!Builder.Type {
32253140 const mod = o.module;
32263141 const target = mod.getTarget();
32273142 const ip = &mod.intern_pool;
......@@ -3406,20 +3321,17 @@ pub const Object = struct {
34063321 },
34073322 .simple_type => unreachable,
34083323 .struct_type => |struct_type| {
3409 const gop = try o.type_map.getOrPut(o.gpa, t.toIntern());
3410 if (gop.found_existing) return gop.value_ptr.*;
3324 if (o.type_map.get(t.toIntern())) |value| return value;
34113325
34123326 if (struct_type.layout == .Packed) {
34133327 const int_ty = try o.lowerType(Type.fromInterned(struct_type.backingIntType(ip).*));
3414 gop.value_ptr.* = int_ty;
3328 try o.type_map.put(o.gpa, t.toIntern(), int_ty);
34153329 return int_ty;
34163330 }
34173331
34183332 const name = try o.builder.string(ip.stringToSlice(
34193333 try mod.declPtr(struct_type.decl.unwrap().?).getFullyQualifiedName(mod),
34203334 ));
3421 const ty = try o.builder.opaqueType(name);
3422 gop.value_ptr.* = ty; // must be done before any recursive calls
34233335
34243336 var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){};
34253337 defer llvm_field_types.deinit(o.gpa);
......@@ -3484,7 +3396,10 @@ pub const Object = struct {
34843396 );
34853397 }
34863398
3487 try o.builder.namedTypeSetBody(
3399 const ty = try o.builder.opaqueType(name);
3400 try o.type_map.put(o.gpa, t.toIntern(), ty);
3401
3402 o.builder.namedTypeSetBody(
34883403 ty,
34893404 try o.builder.structType(struct_kind, llvm_field_types.items),
34903405 );
......@@ -3553,29 +3468,26 @@ pub const Object = struct {
35533468 return o.builder.structType(.normal, llvm_field_types.items);
35543469 },
35553470 .union_type => |union_type| {
3556 const gop = try o.type_map.getOrPut(o.gpa, t.toIntern());
3557 if (gop.found_existing) return gop.value_ptr.*;
3471 if (o.type_map.get(t.toIntern())) |value| return value;
35583472
35593473 const union_obj = ip.loadUnionType(union_type);
35603474 const layout = mod.getUnionLayout(union_obj);
35613475
35623476 if (union_obj.flagsPtr(ip).layout == .Packed) {
35633477 const int_ty = try o.builder.intType(@intCast(t.bitSize(mod)));
3564 gop.value_ptr.* = int_ty;
3478 try o.type_map.put(o.gpa, t.toIntern(), int_ty);
35653479 return int_ty;
35663480 }
35673481
35683482 if (layout.payload_size == 0) {
35693483 const enum_tag_ty = try o.lowerType(Type.fromInterned(union_obj.enum_tag_ty));
3570 gop.value_ptr.* = enum_tag_ty;
3484 try o.type_map.put(o.gpa, t.toIntern(), enum_tag_ty);
35713485 return enum_tag_ty;
35723486 }
35733487
35743488 const name = try o.builder.string(ip.stringToSlice(
35753489 try mod.declPtr(union_obj.decl).getFullyQualifiedName(mod),
35763490 ));
3577 const ty = try o.builder.opaqueType(name);
3578 gop.value_ptr.* = ty; // must be done before any recursive calls
35793491
35803492 const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]);
35813493 const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty);
......@@ -3595,7 +3507,10 @@ pub const Object = struct {
35953507 };
35963508
35973509 if (layout.tag_size == 0) {
3598 try o.builder.namedTypeSetBody(
3510 const ty = try o.builder.opaqueType(name);
3511 try o.type_map.put(o.gpa, t.toIntern(), ty);
3512
3513 o.builder.namedTypeSetBody(
35993514 ty,
36003515 try o.builder.structType(.normal, &.{payload_ty}),
36013516 );
......@@ -3620,7 +3535,10 @@ pub const Object = struct {
36203535 llvm_fields_len += 1;
36213536 }
36223537
3623 try o.builder.namedTypeSetBody(
3538 const ty = try o.builder.opaqueType(name);
3539 try o.type_map.put(o.gpa, t.toIntern(), ty);
3540
3541 o.builder.namedTypeSetBody(
36243542 ty,
36253543 try o.builder.structType(.normal, llvm_fields[0..llvm_fields_len]),
36263544 );
......@@ -4368,7 +4286,7 @@ pub const Object = struct {
43684286 const err_align = err_int_ty.abiAlignment(mod);
43694287 const index: u32 = if (payload_align.compare(.gt, err_align)) 2 else 1;
43704288 return o.builder.gepConst(.inbounds, try o.lowerType(eu_ty), parent_ptr, null, &.{
4371 try o.builder.intConst(.i32, 0), try o.builder.intConst(.i32, index),
4289 .@"0", try o.builder.intConst(.i32, index),
43724290 });
43734291 },
43744292 .opt_payload => |opt_ptr| {
......@@ -4384,9 +4302,7 @@ pub const Object = struct {
43844302 return parent_ptr;
43854303 }
43864304
4387 return o.builder.gepConst(.inbounds, try o.lowerType(opt_ty), parent_ptr, null, &.{
4388 try o.builder.intConst(.i32, 0), try o.builder.intConst(.i32, 0),
4389 });
4305 return o.builder.gepConst(.inbounds, try o.lowerType(opt_ty), parent_ptr, null, &.{ .@"0", .@"0" });
43904306 },
43914307 .comptime_field => unreachable,
43924308 .elem => |elem_ptr| {
......@@ -4417,7 +4333,7 @@ pub const Object = struct {
44174333
44184334 const parent_llvm_ty = try o.lowerType(parent_ty);
44194335 return o.builder.gepConst(.inbounds, parent_llvm_ty, parent_ptr, null, &.{
4420 try o.builder.intConst(.i32, 0),
4336 .@"0",
44214337 try o.builder.intConst(.i32, @intFromBool(
44224338 layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align),
44234339 )),
......@@ -4443,7 +4359,7 @@ pub const Object = struct {
44434359 parent_ptr,
44444360 null,
44454361 if (o.llvmFieldIndex(parent_ty, field_index)) |llvm_field_index| &.{
4446 try o.builder.intConst(.i32, 0),
4362 .@"0",
44474363 try o.builder.intConst(.i32, llvm_field_index),
44484364 } else &.{
44494365 try o.builder.intConst(.i32, @intFromBool(
......@@ -4456,7 +4372,7 @@ pub const Object = struct {
44564372 assert(parent_ty.isSlice(mod));
44574373 const parent_llvm_ty = try o.lowerType(parent_ty);
44584374 return o.builder.gepConst(.inbounds, parent_llvm_ty, parent_ptr, null, &.{
4459 try o.builder.intConst(.i32, 0), try o.builder.intConst(.i32, field_index),
4375 .@"0", try o.builder.intConst(.i32, field_index),
44604376 });
44614377 },
44624378 else => unreachable,
......@@ -4716,8 +4632,8 @@ pub const Object = struct {
47164632 defer wip_switch.finish(&wip);
47174633
47184634 for (0..enum_type.names.len) |field_index| {
4719 const name = try o.builder.string(ip.stringToSlice(enum_type.names.get(ip)[field_index]));
4720 const name_init = try o.builder.stringNullConst(name);
4635 const name = try o.builder.stringNull(ip.stringToSlice(enum_type.names.get(ip)[field_index]));
4636 const name_init = try o.builder.stringConst(name);
47214637 const name_variable_index =
47224638 try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default);
47234639 try name_variable_index.setInitializer(name_init, &o.builder);
......@@ -4728,7 +4644,7 @@ pub const Object = struct {
47284644
47294645 const name_val = try o.builder.structValue(ret_ty, &.{
47304646 name_variable_index.toConst(&o.builder),
4731 try o.builder.intConst(usize_ty, name.slice(&o.builder).?.len),
4647 try o.builder.intConst(usize_ty, name.slice(&o.builder).?.len - 1),
47324648 });
47334649
47344650 const return_block = try wip.block(1, "Name");
......@@ -4800,26 +4716,33 @@ pub const DeclGen = struct {
48004716 else => try o.lowerValue(init_val),
48014717 }, &o.builder);
48024718
4803 if (o.di_builder) |dib| {
4804 const di_file =
4805 try o.getDIFile(o.gpa, mod.namespacePtr(decl.src_namespace).file_scope);
4806
4807 const line_number = decl.src_line + 1;
4808 const is_internal_linkage = !o.module.decl_exports.contains(decl_index);
4809 const di_global = dib.createGlobalVariableExpression(
4810 di_file.toScope(),
4811 mod.intern_pool.stringToSlice(decl.name),
4812 variable_index.name(&o.builder).slice(&o.builder).?,
4813 di_file,
4814 line_number,
4815 try o.lowerDebugType(decl.ty, .full),
4816 is_internal_linkage,
4817 );
4719 const line_number = decl.src_line + 1;
4720 const is_internal_linkage = !o.module.decl_exports.contains(decl_index);
48184721
4819 try o.di_map.put(o.gpa, dg.decl, di_global.getVariable().toNode());
4820 if (!is_internal_linkage or decl.isExtern(mod))
4821 variable_index.toLlvm(&o.builder).attachMetaData(di_global);
4822 }
4722 if (dg.object.builder.strip) return;
4723
4724 const debug_file = try o.getDebugFile(mod.namespacePtr(decl.src_namespace).file_scope);
4725
4726 const debug_global_var = try o.builder.debugGlobalVar(
4727 try o.builder.metadataString(mod.intern_pool.stringToSlice(decl.name)), // Name
4728 try o.builder.metadataStringFromString(variable_index.name(&o.builder)), // Linkage name
4729 debug_file, // File
4730 debug_file, // Scope
4731 line_number,
4732 try o.lowerDebugType(decl.ty),
4733 variable_index,
4734 .{ .local = is_internal_linkage },
4735 );
4736
4737 const debug_expression = try o.builder.debugExpression(&.{});
4738
4739 const debug_global_var_expression = try o.builder.debugGlobalVarExpression(
4740 debug_global_var,
4741 debug_expression,
4742 );
4743 if (!is_internal_linkage or decl.isExtern(mod))
4744 variable_index.setGlobalVariableExpression(debug_global_var_expression, &o.builder);
4745 try o.debug_globals.append(o.gpa, debug_global_var_expression);
48234746 }
48244747 }
48254748};
......@@ -4830,19 +4753,22 @@ pub const FuncGen = struct {
48304753 air: Air,
48314754 liveness: Liveness,
48324755 wip: Builder.WipFunction,
4833 di_scope: ?if (build_options.have_llvm) *llvm.DIScope else noreturn,
4834 di_file: ?if (build_options.have_llvm) *llvm.DIFile else noreturn,
4756
4757 file: Builder.Metadata,
4758 scope: Builder.Metadata,
4759
4760 inlined: std.ArrayListUnmanaged(struct {
4761 base_line: u32,
4762 location: Builder.Metadata,
4763 scope: Builder.Metadata,
4764 }) = .{},
4765
4766 scope_stack: std.ArrayListUnmanaged(Builder.Metadata) = .{},
4767
48354768 base_line: u32,
48364769 prev_dbg_line: c_uint,
48374770 prev_dbg_column: c_uint,
48384771
4839 /// Stack of locations where a call was inlined.
4840 dbg_inlined: std.ArrayListUnmanaged(if (build_options.have_llvm) DbgState else void) = .{},
4841
4842 /// Stack of `DILexicalBlock`s. dbg_block instructions cannot happend accross
4843 /// dbg_inline instructions so no special handling there is required.
4844 dbg_block_stack: std.ArrayListUnmanaged(if (build_options.have_llvm) *llvm.DIScope else void) = .{},
4845
48464772 /// This stores the LLVM values used in a function, such that they can be referred to
48474773 /// in other instructions. This table is cleared before every function is generated.
48484774 func_inst_table: std.AutoHashMapUnmanaged(Air.Inst.Ref, Builder.Value),
......@@ -4872,7 +4798,6 @@ pub const FuncGen = struct {
48724798
48734799 sync_scope: Builder.SyncScope,
48744800
4875 const DbgState = if (build_options.have_llvm) struct { loc: *llvm.DILocation, scope: *llvm.DIScope, base_line: u32 } else struct {};
48764801 const BreakList = union {
48774802 list: std.MultiArrayList(struct {
48784803 bb: Builder.Function.Block.Index,
......@@ -4883,8 +4808,8 @@ pub const FuncGen = struct {
48834808
48844809 fn deinit(self: *FuncGen) void {
48854810 self.wip.deinit();
4886 self.dbg_inlined.deinit(self.gpa);
4887 self.dbg_block_stack.deinit(self.gpa);
4811 self.scope_stack.deinit(self.gpa);
4812 self.inlined.deinit(self.gpa);
48884813 self.func_inst_table.deinit(self.gpa);
48894814 self.blocks.deinit(self.gpa);
48904815 }
......@@ -5493,9 +5418,6 @@ pub const FuncGen = struct {
54935418 // a different LLVM type than the usual one. We solve this here at the callsite
54945419 // by using our canonical type, then loading it if necessary.
54955420 const alignment = return_type.abiAlignment(mod).toLlvm();
5496 if (o.builder.useLibLlvm())
5497 assert(o.target_data.abiSizeOfType(abi_ret_ty.toLlvm(&o.builder)) >=
5498 o.target_data.abiSizeOfType(llvm_ret_ty.toLlvm(&o.builder)));
54995421 const rp = try self.buildAlloca(abi_ret_ty, alignment);
55005422 _ = try self.wip.store(.normal, call, rp, alignment);
55015423 return if (isByRef(return_type, mod))
......@@ -5862,7 +5784,7 @@ pub const FuncGen = struct {
58625784 };
58635785
58645786 const phi = try self.wip.phi(.i1, "");
5865 try phi.finish(
5787 phi.finish(
58665788 &incoming_values,
58675789 &.{ both_null_block, mixed_block, both_pl_block_end },
58685790 &self.wip,
......@@ -5929,7 +5851,7 @@ pub const FuncGen = struct {
59295851
59305852 parent_bb.ptr(&self.wip).incoming = @intCast(breaks.list.len);
59315853 const phi = try self.wip.phi(llvm_ty, "");
5932 try phi.finish(breaks.list.items(.val), breaks.list.items(.bb), &self.wip);
5854 phi.finish(breaks.list.items(.val), breaks.list.items(.bb), &self.wip);
59335855 return phi.toValue();
59345856 } else {
59355857 parent_bb.ptr(&self.wip).incoming = @intCast(breaks.len);
......@@ -6653,42 +6575,43 @@ pub const FuncGen = struct {
66536575 }
66546576
66556577 fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6656 const di_scope = self.di_scope orelse return .none;
6578 if (self.wip.builder.strip) return .none;
66576579 const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
66586580 self.prev_dbg_line = @intCast(self.base_line + dbg_stmt.line + 1);
66596581 self.prev_dbg_column = @intCast(dbg_stmt.column + 1);
6660 const inlined_at = if (self.dbg_inlined.items.len > 0)
6661 self.dbg_inlined.items[self.dbg_inlined.items.len - 1].loc
6582 const inlined_at = if (self.inlined.items.len > 0)
6583 self.inlined.items[self.inlined.items.len - 1].location
66626584 else
6663 null;
6664 self.wip.llvm.builder.setCurrentDebugLocation(
6585 .none;
6586
6587 self.wip.current_debug_location = try self.wip.builder.debugLocation(
66656588 self.prev_dbg_line,
66666589 self.prev_dbg_column,
6667 di_scope,
6590 self.scope,
66686591 inlined_at,
66696592 );
6593
66706594 return .none;
66716595 }
66726596
66736597 fn airDbgInlineBegin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6598 if (self.wip.builder.strip) return .none;
66746599 const o = self.dg.object;
6675 const dib = o.di_builder orelse return .none;
6676 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
6677
66786600 const zcu = o.module;
6601
6602 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
66796603 const func = zcu.funcInfo(ty_fn.func);
66806604 const decl_index = func.owner_decl;
66816605 const decl = zcu.declPtr(decl_index);
66826606 const namespace = zcu.namespacePtr(decl.src_namespace);
66836607 const owner_mod = namespace.file_scope.mod;
6684 const di_file = try o.getDIFile(self.gpa, zcu.namespacePtr(decl.src_namespace).file_scope);
6685 self.di_file = di_file;
6686 const line_number = decl.src_line + 1;
6687 const cur_debug_location = self.wip.llvm.builder.getCurrentDebugLocation2();
66886608
6689 try self.dbg_inlined.append(self.gpa, .{
6690 .loc = @ptrCast(cur_debug_location),
6691 .scope = self.di_scope.?,
6609 self.file = try o.getDebugFile(namespace.file_scope);
6610
6611 const line_number = decl.src_line + 1;
6612 try self.inlined.append(self.gpa, .{
6613 .location = self.wip.current_debug_location,
6614 .scope = self.scope,
66926615 .base_line = self.base_line,
66936616 });
66946617
......@@ -6699,91 +6622,118 @@ pub const FuncGen = struct {
66996622 .param_types = &.{},
67006623 .return_type = .void_type,
67016624 });
6702 const fn_di_ty = try o.lowerDebugType(fn_ty, .full);
6703 const subprogram = dib.createFunction(
6704 di_file.toScope(),
6705 zcu.intern_pool.stringToSlice(decl.name),
6706 zcu.intern_pool.stringToSlice(fqn),
6707 di_file,
6625
6626 const subprogram = try o.builder.debugSubprogram(
6627 self.file,
6628 try o.builder.metadataString(zcu.intern_pool.stringToSlice(decl.name)),
6629 try o.builder.metadataString(zcu.intern_pool.stringToSlice(fqn)),
67086630 line_number,
6709 fn_di_ty,
6710 is_internal_linkage,
6711 true, // is definition
6712 line_number + func.lbrace_line, // scope line
6713 llvm.DIFlags.StaticMember,
6714 owner_mod.optimize_mode != .Debug,
6715 null, // decl_subprogram
6631 line_number + func.lbrace_line,
6632 try o.lowerDebugType(fn_ty),
6633 .{
6634 .di_flags = .{ .StaticMember = true },
6635 .sp_flags = .{
6636 .Optimized = owner_mod.optimize_mode != .Debug,
6637 .Definition = true,
6638 .LocalToUnit = is_internal_linkage,
6639 },
6640 },
6641 o.debug_compile_unit,
67166642 );
67176643
6718 const lexical_block = dib.createLexicalBlock(subprogram.toScope(), di_file, line_number, 1);
6719 self.di_scope = lexical_block.toScope();
6644 const lexical_block = try o.builder.debugLexicalBlock(
6645 subprogram,
6646 self.file,
6647 line_number,
6648 1,
6649 );
6650 self.scope = lexical_block;
67206651 self.base_line = decl.src_line;
6652 const inlined_at = self.wip.current_debug_location;
6653 self.wip.current_debug_location = try o.builder.debugLocation(
6654 line_number,
6655 0,
6656 self.scope,
6657 inlined_at,
6658 );
67216659 return .none;
67226660 }
67236661
6724 fn airDbgInlineEnd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6662 fn airDbgInlineEnd(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
6663 if (self.wip.builder.strip) return .none;
67256664 const o = self.dg.object;
6726 if (o.di_builder == null) return .none;
6665
67276666 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
67286667
67296668 const mod = o.module;
67306669 const decl = mod.funcOwnerDeclPtr(ty_fn.func);
6731 const di_file = try o.getDIFile(self.gpa, mod.namespacePtr(decl.src_namespace).file_scope);
6732 self.di_file = di_file;
6733 const old = self.dbg_inlined.pop();
6734 self.di_scope = old.scope;
6670 self.file = try o.getDebugFile(mod.namespacePtr(decl.src_namespace).file_scope);
6671
6672 const old = self.inlined.pop();
6673 self.scope = old.scope;
67356674 self.base_line = old.base_line;
6675 self.wip.current_debug_location = old.location;
67366676 return .none;
67376677 }
67386678
6739 fn airDbgBlockBegin(self: *FuncGen) !Builder.Value {
6679 fn airDbgBlockBegin(self: *FuncGen) Allocator.Error!Builder.Value {
6680 if (self.wip.builder.strip) return .none;
67406681 const o = self.dg.object;
6741 const dib = o.di_builder orelse return .none;
6742 const old_scope = self.di_scope.?;
6743 try self.dbg_block_stack.append(self.gpa, old_scope);
6744 const lexical_block = dib.createLexicalBlock(old_scope, self.di_file.?, self.prev_dbg_line, self.prev_dbg_column);
6745 self.di_scope = lexical_block.toScope();
6682
6683 try self.scope_stack.append(self.gpa, self.scope);
6684
6685 const old = self.scope;
6686 self.scope = try o.builder.debugLexicalBlock(
6687 old,
6688 self.file,
6689 self.prev_dbg_line,
6690 self.prev_dbg_column,
6691 );
67466692 return .none;
67476693 }
67486694
67496695 fn airDbgBlockEnd(self: *FuncGen) !Builder.Value {
6750 const o = self.dg.object;
6751 if (o.di_builder == null) return .none;
6752 self.di_scope = self.dbg_block_stack.pop();
6696 if (self.wip.builder.strip) return .none;
6697 self.scope = self.scope_stack.pop();
67536698 return .none;
67546699 }
67556700
67566701 fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6702 if (self.wip.builder.strip) return .none;
67576703 const o = self.dg.object;
67586704 const mod = o.module;
6759 const dib = o.di_builder orelse return .none;
67606705 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
67616706 const operand = try self.resolveInst(pl_op.operand);
67626707 const name = self.air.nullTerminatedString(pl_op.payload);
67636708 const ptr_ty = self.typeOf(pl_op.operand);
67646709
6765 const di_local_var = dib.createAutoVariable(
6766 self.di_scope.?,
6767 name.ptr,
6768 self.di_file.?,
6710 const debug_local_var = try o.builder.debugLocalVar(
6711 try o.builder.metadataString(name),
6712 self.file,
6713 self.scope,
67696714 self.prev_dbg_line,
6770 try o.lowerDebugType(ptr_ty.childType(mod), .full),
6771 true, // always preserve
6772 0, // flags
6715 try o.lowerDebugType(ptr_ty.childType(mod)),
67736716 );
6774 const inlined_at = if (self.dbg_inlined.items.len > 0)
6775 self.dbg_inlined.items[self.dbg_inlined.items.len - 1].loc
6776 else
6777 null;
6778 const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at);
6779 const insert_block = self.wip.cursor.block.toLlvm(&self.wip);
6780 _ = dib.insertDeclareAtEnd(operand.toLlvm(&self.wip), di_local_var, debug_loc, insert_block);
6717
6718 _ = try self.wip.callIntrinsic(
6719 .normal,
6720 .none,
6721 .@"dbg.declare",
6722 &.{},
6723 &.{
6724 (try self.wip.debugValue(operand)).toValue(),
6725 debug_local_var.toValue(),
6726 (try o.builder.debugExpression(&.{})).toValue(),
6727 },
6728 "",
6729 );
6730
67816731 return .none;
67826732 }
67836733
67846734 fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6735 if (self.wip.builder.strip) return .none;
67856736 const o = self.dg.object;
6786 const dib = o.di_builder orelse return .none;
67876737 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
67886738 const operand = try self.resolveInst(pl_op.operand);
67896739 const operand_ty = self.typeOf(pl_op.operand);
......@@ -6791,32 +6741,58 @@ pub const FuncGen = struct {
67916741
67926742 if (needDbgVarWorkaround(o)) return .none;
67936743
6794 const di_local_var = dib.createAutoVariable(
6795 self.di_scope.?,
6796 name.ptr,
6797 self.di_file.?,
6744 const debug_local_var = try o.builder.debugLocalVar(
6745 try o.builder.metadataString(name),
6746 self.file,
6747 self.scope,
67986748 self.prev_dbg_line,
6799 try o.lowerDebugType(operand_ty, .full),
6800 true, // always preserve
6801 0, // flags
6749 try o.lowerDebugType(operand_ty),
68026750 );
6803 const inlined_at = if (self.dbg_inlined.items.len > 0)
6804 self.dbg_inlined.items[self.dbg_inlined.items.len - 1].loc
6805 else
6806 null;
6807 const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at);
6808 const insert_block = self.wip.cursor.block.toLlvm(&self.wip);
6751
68096752 const zcu = o.module;
68106753 const owner_mod = self.dg.ownerModule();
68116754 if (isByRef(operand_ty, zcu)) {
6812 _ = dib.insertDeclareAtEnd(operand.toLlvm(&self.wip), di_local_var, debug_loc, insert_block);
6755 _ = try self.wip.callIntrinsic(
6756 .normal,
6757 .none,
6758 .@"dbg.declare",
6759 &.{},
6760 &.{
6761 (try self.wip.debugValue(operand)).toValue(),
6762 debug_local_var.toValue(),
6763 (try o.builder.debugExpression(&.{})).toValue(),
6764 },
6765 "",
6766 );
68136767 } else if (owner_mod.optimize_mode == .Debug) {
68146768 const alignment = operand_ty.abiAlignment(zcu).toLlvm();
68156769 const alloca = try self.buildAlloca(operand.typeOfWip(&self.wip), alignment);
68166770 _ = try self.wip.store(.normal, operand, alloca, alignment);
6817 _ = dib.insertDeclareAtEnd(alloca.toLlvm(&self.wip), di_local_var, debug_loc, insert_block);
6771 _ = try self.wip.callIntrinsic(
6772 .normal,
6773 .none,
6774 .@"dbg.declare",
6775 &.{},
6776 &.{
6777 (try self.wip.debugValue(alloca)).toValue(),
6778 debug_local_var.toValue(),
6779 (try o.builder.debugExpression(&.{})).toValue(),
6780 },
6781 "",
6782 );
68186783 } else {
6819 _ = dib.insertDbgValueIntrinsicAtEnd(operand.toLlvm(&self.wip), di_local_var, debug_loc, insert_block);
6784 _ = try self.wip.callIntrinsic(
6785 .normal,
6786 .none,
6787 .@"dbg.value",
6788 &.{},
6789 &.{
6790 (try self.wip.debugValue(operand)).toValue(),
6791 debug_local_var.toValue(),
6792 (try o.builder.debugExpression(&.{})).toValue(),
6793 },
6794 "",
6795 );
68206796 }
68216797 return .none;
68226798 }
......@@ -7885,7 +7861,7 @@ pub const FuncGen = struct {
78857861 .none,
78867862 if (scalar_ty.isSignedInt(mod)) .@"smul.fix.sat" else .@"umul.fix.sat",
78877863 &.{try o.lowerType(inst_ty)},
7888 &.{ lhs, rhs, try o.builder.intValue(.i32, 0) },
7864 &.{ lhs, rhs, .@"0" },
78897865 "",
78907866 );
78917867 }
......@@ -8208,7 +8184,6 @@ pub const FuncGen = struct {
82088184
82098185 const libc_fn = try self.getLibcFunction(fn_name, &.{ scalar_llvm_ty, scalar_llvm_ty }, .i32);
82108186
8211 const zero = try o.builder.intConst(.i32, 0);
82128187 const int_cond: Builder.IntegerCondition = switch (pred) {
82138188 .eq => .eq,
82148189 .neq => .ne,
......@@ -8225,7 +8200,7 @@ pub const FuncGen = struct {
82258200 const init = try o.builder.poisonValue(vector_result_ty);
82268201 const result = try self.buildElementwiseCall(libc_fn, &params, init, vec_len);
82278202
8228 const zero_vector = try o.builder.splatValue(vector_result_ty, zero);
8203 const zero_vector = try o.builder.splatValue(vector_result_ty, .@"0");
82298204 return self.wip.icmp(int_cond, result, zero_vector, "");
82308205 }
82318206
......@@ -8238,7 +8213,7 @@ pub const FuncGen = struct {
82388213 &params,
82398214 "",
82408215 );
8241 return self.wip.icmp(int_cond, result, zero.toValue(), "");
8216 return self.wip.icmp(int_cond, result, .@"0", "");
82428217 }
82438218
82448219 const FloatOp = enum {
......@@ -8838,41 +8813,80 @@ pub const FuncGen = struct {
88388813 const arg_val = self.args[self.arg_index];
88398814 self.arg_index += 1;
88408815
8816 if (self.wip.builder.strip) return arg_val;
8817
88418818 const inst_ty = self.typeOfIndex(inst);
8842 if (o.di_builder) |dib| {
8843 if (needDbgVarWorkaround(o)) return arg_val;
8844
8845 const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
8846 const func_index = self.dg.decl.getOwnedFunctionIndex();
8847 const func = mod.funcInfo(func_index);
8848 const lbrace_line = mod.declPtr(func.owner_decl).src_line + func.lbrace_line + 1;
8849 const lbrace_col = func.lbrace_column + 1;
8850 const di_local_var = dib.createParameterVariable(
8851 self.di_scope.?,
8852 mod.getParamName(func_index, src_index).ptr, // TODO test 0 bit args
8853 self.di_file.?,
8854 lbrace_line,
8855 try o.lowerDebugType(inst_ty, .full),
8856 true, // always preserve
8857 0, // flags
8858 @intCast(self.arg_index), // includes +1 because 0 is return type
8859 );
8819 if (needDbgVarWorkaround(o)) return arg_val;
8820
8821 const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
8822 const func_index = self.dg.decl.getOwnedFunctionIndex();
8823 const func = mod.funcInfo(func_index);
8824 const lbrace_line = mod.declPtr(func.owner_decl).src_line + func.lbrace_line + 1;
8825 const lbrace_col = func.lbrace_column + 1;
8826
8827 const debug_parameter = try o.builder.debugParameter(
8828 try o.builder.metadataString(mod.getParamName(func_index, src_index)),
8829 self.file,
8830 self.scope,
8831 lbrace_line,
8832 try o.lowerDebugType(inst_ty),
8833 @intCast(self.arg_index),
8834 );
88608835
8861 const debug_loc = llvm.getDebugLoc(lbrace_line, lbrace_col, self.di_scope.?, null);
8862 const insert_block = self.wip.cursor.block.toLlvm(&self.wip);
8863 const owner_mod = self.dg.ownerModule();
8864 if (isByRef(inst_ty, mod)) {
8865 _ = dib.insertDeclareAtEnd(arg_val.toLlvm(&self.wip), di_local_var, debug_loc, insert_block);
8866 } else if (owner_mod.optimize_mode == .Debug) {
8867 const alignment = inst_ty.abiAlignment(mod).toLlvm();
8868 const alloca = try self.buildAlloca(arg_val.typeOfWip(&self.wip), alignment);
8869 _ = try self.wip.store(.normal, arg_val, alloca, alignment);
8870 _ = dib.insertDeclareAtEnd(alloca.toLlvm(&self.wip), di_local_var, debug_loc, insert_block);
8871 } else {
8872 _ = dib.insertDbgValueIntrinsicAtEnd(arg_val.toLlvm(&self.wip), di_local_var, debug_loc, insert_block);
8873 }
8836 const old_location = self.wip.current_debug_location;
8837 self.wip.current_debug_location = try o.builder.debugLocation(
8838 lbrace_line,
8839 lbrace_col,
8840 self.scope,
8841 .none,
8842 );
8843
8844 const owner_mod = self.dg.ownerModule();
8845 if (isByRef(inst_ty, mod)) {
8846 _ = try self.wip.callIntrinsic(
8847 .normal,
8848 .none,
8849 .@"dbg.declare",
8850 &.{},
8851 &.{
8852 (try self.wip.debugValue(arg_val)).toValue(),
8853 debug_parameter.toValue(),
8854 (try o.builder.debugExpression(&.{})).toValue(),
8855 },
8856 "",
8857 );
8858 } else if (owner_mod.optimize_mode == .Debug) {
8859 const alignment = inst_ty.abiAlignment(mod).toLlvm();
8860 const alloca = try self.buildAlloca(arg_val.typeOfWip(&self.wip), alignment);
8861 _ = try self.wip.store(.normal, arg_val, alloca, alignment);
8862 _ = try self.wip.callIntrinsic(
8863 .normal,
8864 .none,
8865 .@"dbg.declare",
8866 &.{},
8867 &.{
8868 (try self.wip.debugValue(alloca)).toValue(),
8869 debug_parameter.toValue(),
8870 (try o.builder.debugExpression(&.{})).toValue(),
8871 },
8872 "",
8873 );
8874 } else {
8875 _ = try self.wip.callIntrinsic(
8876 .normal,
8877 .none,
8878 .@"dbg.value",
8879 &.{},
8880 &.{
8881 (try self.wip.debugValue(arg_val)).toValue(),
8882 debug_parameter.toValue(),
8883 (try o.builder.debugExpression(&.{})).toValue(),
8884 },
8885 "",
8886 );
88748887 }
88758888
8889 self.wip.current_debug_location = old_location;
88768890 return arg_val;
88778891 }
88788892
......@@ -8910,7 +8924,7 @@ pub const FuncGen = struct {
89108924 alignment: Builder.Alignment,
89118925 ) Allocator.Error!Builder.Value {
89128926 const target = self.dg.object.module.getTarget();
8913 return buildAllocaInner(&self.wip, self.di_scope != null, llvm_ty, alignment, target);
8927 return buildAllocaInner(&self.wip, llvm_ty, alignment, target);
89148928 }
89158929
89168930 // Workaround for https://github.com/ziglang/zig/issues/16392
......@@ -9025,18 +9039,14 @@ pub const FuncGen = struct {
90259039 // https://github.com/ziglang/zig/issues/11946
90269040 return o.builder.intValue(llvm_usize, 0);
90279041 }
9028 const result = try self.wip.callIntrinsic(.normal, .none, .returnaddress, &.{}, &.{
9029 try o.builder.intValue(.i32, 0),
9030 }, "");
9042 const result = try self.wip.callIntrinsic(.normal, .none, .returnaddress, &.{}, &.{.@"0"}, "");
90319043 return self.wip.cast(.ptrtoint, result, llvm_usize, "");
90329044 }
90339045
90349046 fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
90359047 _ = inst;
90369048 const o = self.dg.object;
9037 const result = try self.wip.callIntrinsic(.normal, .none, .frameaddress, &.{.ptr}, &.{
9038 try o.builder.intValue(.i32, 0),
9039 }, "");
9049 const result = try self.wip.callIntrinsic(.normal, .none, .frameaddress, &.{.ptr}, &.{.@"0"}, "");
90409050 return self.wip.cast(.ptrtoint, result, try o.lowerType(Type.usize), "");
90419051 }
90429052
......@@ -9364,7 +9374,7 @@ pub const FuncGen = struct {
93649374 _ = try self.wip.br(loop_block);
93659375
93669376 self.wip.cursor = .{ .block = end_block };
9367 try it_ptr.finish(&.{ next_ptr, dest_ptr }, &.{ body_block, entry_block }, &self.wip);
9377 it_ptr.finish(&.{ next_ptr, dest_ptr }, &.{ body_block, entry_block }, &self.wip);
93689378 return .none;
93699379 }
93709380
......@@ -9599,7 +9609,7 @@ pub const FuncGen = struct {
95999609
96009610 self.wip.cursor = .{ .block = end_block };
96019611 const phi = try self.wip.phi(.i1, "");
9602 try phi.finish(&.{ .true, .false }, &.{ valid_block, invalid_block }, &self.wip);
9612 phi.finish(&.{ .true, .false }, &.{ valid_block, invalid_block }, &self.wip);
96039613 return phi.toValue();
96049614 }
96059615
......@@ -10120,7 +10130,6 @@ pub const FuncGen = struct {
1012010130 const field_align = mod.unionFieldNormalAlignment(union_obj, extra.field_index);
1012110131 const llvm_usize = try o.lowerType(Type.usize);
1012210132 const usize_zero = try o.builder.intValue(llvm_usize, 0);
10123 const i32_zero = try o.builder.intValue(.i32, 0);
1012410133
1012510134 const llvm_union_ty = t: {
1012610135 const payload_ty = p: {
......@@ -10159,7 +10168,7 @@ pub const FuncGen = struct {
1015910168 .flags = .{ .alignment = field_align },
1016010169 });
1016110170 if (layout.tag_size == 0) {
10162 const indices = [3]Builder.Value{ usize_zero, i32_zero, i32_zero };
10171 const indices = [3]Builder.Value{ usize_zero, .@"0", .@"0" };
1016310172 const len: usize = if (field_size == layout.payload_size) 2 else 3;
1016410173 const field_ptr =
1016510174 try self.wip.gep(.inbounds, llvm_union_ty, result_ptr, indices[0..len], "");
......@@ -10169,11 +10178,9 @@ pub const FuncGen = struct {
1016910178
1017010179 {
1017110180 const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align));
10172 const indices: [3]Builder.Value =
10173 .{ usize_zero, try o.builder.intValue(.i32, payload_index), i32_zero };
10181 const indices: [3]Builder.Value = .{ usize_zero, try o.builder.intValue(.i32, payload_index), .@"0" };
1017410182 const len: usize = if (field_size == layout.payload_size) 2 else 3;
10175 const field_ptr =
10176 try self.wip.gep(.inbounds, llvm_union_ty, result_ptr, indices[0..len], "");
10183 const field_ptr = try self.wip.gep(.inbounds, llvm_union_ty, result_ptr, indices[0..len], "");
1017710184 try self.store(field_ptr, field_ptr_ty, llvm_payload, .none);
1017810185 }
1017910186 {
......@@ -10279,7 +10286,7 @@ pub const FuncGen = struct {
1027910286
1028010287 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
1028110288 const dimension = pl_op.payload;
10282 if (dimension >= 3) return o.builder.intValue(.i32, 1);
10289 if (dimension >= 3) return .@"1";
1028310290
1028410291 // Fetch the dispatch pointer, which points to this structure:
1028510292 // https://github.com/RadeonOpenCompute/ROCR-Runtime/blob/adae6c61e10d371f7cbc3d0e94ae2c070cab18a4/src/inc/hsa.h#L2913
......@@ -11694,45 +11701,6 @@ const struct_layout_version = 2;
1169411701// https://github.com/llvm/llvm-project/issues/56585/ is fixed
1169511702const optional_layout_version = 3;
1169611703
11697/// We use the least significant bit of the pointer address to tell us
11698/// whether the type is fully resolved. Types that are only fwd declared
11699/// have the LSB flipped to a 1.
11700const AnnotatedDITypePtr = enum(usize) {
11701 null,
11702 _,
11703
11704 fn initFwd(di_type: *llvm.DIType) AnnotatedDITypePtr {
11705 const addr = @intFromPtr(di_type);
11706 assert(@as(u1, @truncate(addr)) == 0);
11707 return @enumFromInt(addr | 1);
11708 }
11709
11710 fn initFull(di_type: *llvm.DIType) AnnotatedDITypePtr {
11711 const addr = @intFromPtr(di_type);
11712 return @enumFromInt(addr);
11713 }
11714
11715 fn init(di_type: *llvm.DIType, resolve: Object.DebugResolveStatus) AnnotatedDITypePtr {
11716 const addr = @intFromPtr(di_type);
11717 const bit = @intFromBool(resolve == .fwd);
11718 return @enumFromInt(addr | bit);
11719 }
11720
11721 fn toDIType(self: AnnotatedDITypePtr) *llvm.DIType {
11722 switch (self) {
11723 .null => unreachable,
11724 _ => return @ptrFromInt(@intFromEnum(self) & ~@as(usize, 1)),
11725 }
11726 }
11727
11728 fn isFwdOnly(self: AnnotatedDITypePtr) bool {
11729 switch (self) {
11730 .null => unreachable,
11731 _ => return @as(u1, @truncate(@intFromEnum(self))) != 0,
11732 }
11733 }
11734};
11735
1173611704const lt_errors_fn_name = "__zig_lt_errors_len";
1173711705
1173811706/// Without this workaround, LLVM crashes with "unknown codeview register H1"
......@@ -11756,7 +11724,6 @@ fn compilerRtIntBits(bits: u16) u16 {
1175611724
1175711725fn buildAllocaInner(
1175811726 wip: *Builder.WipFunction,
11759 di_scope_non_null: bool,
1176011727 llvm_ty: Builder.Type,
1176111728 alignment: Builder.Alignment,
1176211729 target: std.Target,
......@@ -11765,19 +11732,15 @@ fn buildAllocaInner(
1176511732
1176611733 const alloca = blk: {
1176711734 const prev_cursor = wip.cursor;
11768 const prev_debug_location = if (wip.builder.useLibLlvm())
11769 wip.llvm.builder.getCurrentDebugLocation2()
11770 else
11771 undefined;
11735 const prev_debug_location = wip.current_debug_location;
1177211736 defer {
1177311737 wip.cursor = prev_cursor;
1177411738 if (wip.cursor.block == .entry) wip.cursor.instruction += 1;
11775 if (wip.builder.useLibLlvm() and di_scope_non_null)
11776 wip.llvm.builder.setCurrentDebugLocation2(prev_debug_location);
11739 wip.current_debug_location = prev_debug_location;
1177711740 }
1177811741
1177911742 wip.cursor = .{ .block = .entry };
11780 if (wip.builder.useLibLlvm()) wip.llvm.builder.clearCurrentDebugLocation();
11743 wip.current_debug_location = .none;
1178111744 break :blk try wip.alloca(.normal, llvm_ty, .none, alignment, address_space, "");
1178211745 };
1178311746
......@@ -11823,3 +11786,195 @@ fn constraintAllowsRegister(constraint: []const u8) bool {
1182311786 }
1182411787 } else return false;
1182511788}
11789
11790pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
11791 switch (arch) {
11792 .aarch64, .aarch64_be, .aarch64_32 => {
11793 llvm.LLVMInitializeAArch64Target();
11794 llvm.LLVMInitializeAArch64TargetInfo();
11795 llvm.LLVMInitializeAArch64TargetMC();
11796 llvm.LLVMInitializeAArch64AsmPrinter();
11797 llvm.LLVMInitializeAArch64AsmParser();
11798 },
11799 .amdgcn => {
11800 llvm.LLVMInitializeAMDGPUTarget();
11801 llvm.LLVMInitializeAMDGPUTargetInfo();
11802 llvm.LLVMInitializeAMDGPUTargetMC();
11803 llvm.LLVMInitializeAMDGPUAsmPrinter();
11804 llvm.LLVMInitializeAMDGPUAsmParser();
11805 },
11806 .thumb, .thumbeb, .arm, .armeb => {
11807 llvm.LLVMInitializeARMTarget();
11808 llvm.LLVMInitializeARMTargetInfo();
11809 llvm.LLVMInitializeARMTargetMC();
11810 llvm.LLVMInitializeARMAsmPrinter();
11811 llvm.LLVMInitializeARMAsmParser();
11812 },
11813 .avr => {
11814 llvm.LLVMInitializeAVRTarget();
11815 llvm.LLVMInitializeAVRTargetInfo();
11816 llvm.LLVMInitializeAVRTargetMC();
11817 llvm.LLVMInitializeAVRAsmPrinter();
11818 llvm.LLVMInitializeAVRAsmParser();
11819 },
11820 .bpfel, .bpfeb => {
11821 llvm.LLVMInitializeBPFTarget();
11822 llvm.LLVMInitializeBPFTargetInfo();
11823 llvm.LLVMInitializeBPFTargetMC();
11824 llvm.LLVMInitializeBPFAsmPrinter();
11825 llvm.LLVMInitializeBPFAsmParser();
11826 },
11827 .hexagon => {
11828 llvm.LLVMInitializeHexagonTarget();
11829 llvm.LLVMInitializeHexagonTargetInfo();
11830 llvm.LLVMInitializeHexagonTargetMC();
11831 llvm.LLVMInitializeHexagonAsmPrinter();
11832 llvm.LLVMInitializeHexagonAsmParser();
11833 },
11834 .lanai => {
11835 llvm.LLVMInitializeLanaiTarget();
11836 llvm.LLVMInitializeLanaiTargetInfo();
11837 llvm.LLVMInitializeLanaiTargetMC();
11838 llvm.LLVMInitializeLanaiAsmPrinter();
11839 llvm.LLVMInitializeLanaiAsmParser();
11840 },
11841 .mips, .mipsel, .mips64, .mips64el => {
11842 llvm.LLVMInitializeMipsTarget();
11843 llvm.LLVMInitializeMipsTargetInfo();
11844 llvm.LLVMInitializeMipsTargetMC();
11845 llvm.LLVMInitializeMipsAsmPrinter();
11846 llvm.LLVMInitializeMipsAsmParser();
11847 },
11848 .msp430 => {
11849 llvm.LLVMInitializeMSP430Target();
11850 llvm.LLVMInitializeMSP430TargetInfo();
11851 llvm.LLVMInitializeMSP430TargetMC();
11852 llvm.LLVMInitializeMSP430AsmPrinter();
11853 llvm.LLVMInitializeMSP430AsmParser();
11854 },
11855 .nvptx, .nvptx64 => {
11856 llvm.LLVMInitializeNVPTXTarget();
11857 llvm.LLVMInitializeNVPTXTargetInfo();
11858 llvm.LLVMInitializeNVPTXTargetMC();
11859 llvm.LLVMInitializeNVPTXAsmPrinter();
11860 // There is no LLVMInitializeNVPTXAsmParser function available.
11861 },
11862 .powerpc, .powerpcle, .powerpc64, .powerpc64le => {
11863 llvm.LLVMInitializePowerPCTarget();
11864 llvm.LLVMInitializePowerPCTargetInfo();
11865 llvm.LLVMInitializePowerPCTargetMC();
11866 llvm.LLVMInitializePowerPCAsmPrinter();
11867 llvm.LLVMInitializePowerPCAsmParser();
11868 },
11869 .riscv32, .riscv64 => {
11870 llvm.LLVMInitializeRISCVTarget();
11871 llvm.LLVMInitializeRISCVTargetInfo();
11872 llvm.LLVMInitializeRISCVTargetMC();
11873 llvm.LLVMInitializeRISCVAsmPrinter();
11874 llvm.LLVMInitializeRISCVAsmParser();
11875 },
11876 .sparc, .sparc64, .sparcel => {
11877 llvm.LLVMInitializeSparcTarget();
11878 llvm.LLVMInitializeSparcTargetInfo();
11879 llvm.LLVMInitializeSparcTargetMC();
11880 llvm.LLVMInitializeSparcAsmPrinter();
11881 llvm.LLVMInitializeSparcAsmParser();
11882 },
11883 .s390x => {
11884 llvm.LLVMInitializeSystemZTarget();
11885 llvm.LLVMInitializeSystemZTargetInfo();
11886 llvm.LLVMInitializeSystemZTargetMC();
11887 llvm.LLVMInitializeSystemZAsmPrinter();
11888 llvm.LLVMInitializeSystemZAsmParser();
11889 },
11890 .wasm32, .wasm64 => {
11891 llvm.LLVMInitializeWebAssemblyTarget();
11892 llvm.LLVMInitializeWebAssemblyTargetInfo();
11893 llvm.LLVMInitializeWebAssemblyTargetMC();
11894 llvm.LLVMInitializeWebAssemblyAsmPrinter();
11895 llvm.LLVMInitializeWebAssemblyAsmParser();
11896 },
11897 .x86, .x86_64 => {
11898 llvm.LLVMInitializeX86Target();
11899 llvm.LLVMInitializeX86TargetInfo();
11900 llvm.LLVMInitializeX86TargetMC();
11901 llvm.LLVMInitializeX86AsmPrinter();
11902 llvm.LLVMInitializeX86AsmParser();
11903 },
11904 .xtensa => {
11905 if (build_options.llvm_has_xtensa) {
11906 llvm.LLVMInitializeXtensaTarget();
11907 llvm.LLVMInitializeXtensaTargetInfo();
11908 llvm.LLVMInitializeXtensaTargetMC();
11909 // There is no LLVMInitializeXtensaAsmPrinter function.
11910 llvm.LLVMInitializeXtensaAsmParser();
11911 }
11912 },
11913 .xcore => {
11914 llvm.LLVMInitializeXCoreTarget();
11915 llvm.LLVMInitializeXCoreTargetInfo();
11916 llvm.LLVMInitializeXCoreTargetMC();
11917 llvm.LLVMInitializeXCoreAsmPrinter();
11918 // There is no LLVMInitializeXCoreAsmParser function.
11919 },
11920 .m68k => {
11921 if (build_options.llvm_has_m68k) {
11922 llvm.LLVMInitializeM68kTarget();
11923 llvm.LLVMInitializeM68kTargetInfo();
11924 llvm.LLVMInitializeM68kTargetMC();
11925 llvm.LLVMInitializeM68kAsmPrinter();
11926 llvm.LLVMInitializeM68kAsmParser();
11927 }
11928 },
11929 .csky => {
11930 if (build_options.llvm_has_csky) {
11931 llvm.LLVMInitializeCSKYTarget();
11932 llvm.LLVMInitializeCSKYTargetInfo();
11933 llvm.LLVMInitializeCSKYTargetMC();
11934 // There is no LLVMInitializeCSKYAsmPrinter function.
11935 llvm.LLVMInitializeCSKYAsmParser();
11936 }
11937 },
11938 .ve => {
11939 llvm.LLVMInitializeVETarget();
11940 llvm.LLVMInitializeVETargetInfo();
11941 llvm.LLVMInitializeVETargetMC();
11942 llvm.LLVMInitializeVEAsmPrinter();
11943 llvm.LLVMInitializeVEAsmParser();
11944 },
11945 .arc => {
11946 if (build_options.llvm_has_arc) {
11947 llvm.LLVMInitializeARCTarget();
11948 llvm.LLVMInitializeARCTargetInfo();
11949 llvm.LLVMInitializeARCTargetMC();
11950 llvm.LLVMInitializeARCAsmPrinter();
11951 // There is no LLVMInitializeARCAsmParser function.
11952 }
11953 },
11954
11955 // LLVM backends that have no initialization functions.
11956 .tce,
11957 .tcele,
11958 .r600,
11959 .le32,
11960 .le64,
11961 .amdil,
11962 .amdil64,
11963 .hsail,
11964 .hsail64,
11965 .shave,
11966 .spir,
11967 .spir64,
11968 .kalimba,
11969 .renderscript32,
11970 .renderscript64,
11971 .dxil,
11972 .loongarch32,
11973 .loongarch64,
11974 => {},
11975
11976 .spu_2 => unreachable, // LLVM does not support this backend
11977 .spirv32 => unreachable, // LLVM does not support this backend
11978 .spirv64 => unreachable, // LLVM does not support this backend
11979 }
11980}
src/codegen/llvm/Builder.zig+5222-1998
......@@ -1,21 +1,6 @@
11gpa: Allocator,
2use_lib_llvm: bool,
32strip: bool,
43
5llvm: if (build_options.have_llvm) struct {
6 context: *llvm.Context,
7 module: ?*llvm.Module,
8 target: ?*llvm.Target,
9 di_builder: ?*llvm.DIBuilder,
10 di_compile_unit: ?*llvm.DICompileUnit,
11 attribute_kind_ids: ?*[Attribute.Kind.len]c_uint,
12 attributes: std.ArrayListUnmanaged(*llvm.Attribute),
13 types: std.ArrayListUnmanaged(*llvm.Type),
14 globals: std.ArrayListUnmanaged(*llvm.Value),
15 constants: std.ArrayListUnmanaged(*llvm.Value),
16 replacements: std.AutoHashMapUnmanaged(*llvm.Value, Global.Index),
17} else void,
18
194source_filename: String,
205data_layout: String,
216target_triple: String,
......@@ -37,6 +22,8 @@ attributes_map: std.AutoArrayHashMapUnmanaged(void, void),
3722attributes_indices: std.ArrayListUnmanaged(u32),
3823attributes_extra: std.ArrayListUnmanaged(u32),
3924
25function_attributes_set: std.AutoArrayHashMapUnmanaged(FunctionAttributes, void),
26
4027globals: std.AutoArrayHashMapUnmanaged(String, Global),
4128next_unnamed_global: String,
4229next_replaced_global: String,
......@@ -50,17 +37,29 @@ constant_items: std.MultiArrayList(Constant.Item),
5037constant_extra: std.ArrayListUnmanaged(u32),
5138constant_limbs: std.ArrayListUnmanaged(std.math.big.Limb),
5239
40metadata_map: std.AutoArrayHashMapUnmanaged(void, void),
41metadata_items: std.MultiArrayList(Metadata.Item),
42metadata_extra: std.ArrayListUnmanaged(u32),
43metadata_limbs: std.ArrayListUnmanaged(std.math.big.Limb),
44metadata_forward_references: std.ArrayListUnmanaged(Metadata),
45metadata_named: std.AutoArrayHashMapUnmanaged(MetadataString, struct {
46 len: u32,
47 index: Metadata.Item.ExtraIndex,
48}),
49
50metadata_string_map: std.AutoArrayHashMapUnmanaged(void, void),
51metadata_string_indices: std.ArrayListUnmanaged(u32),
52metadata_string_bytes: std.ArrayListUnmanaged(u8),
53
5354pub const expected_args_len = 16;
5455pub const expected_attrs_len = 16;
5556pub const expected_fields_len = 32;
5657pub const expected_gep_indices_len = 8;
5758pub const expected_cases_len = 8;
5859pub const expected_incoming_len = 8;
59pub const expected_intrinsic_name_len = 64;
6060
6161pub const Options = struct {
6262 allocator: Allocator,
63 use_lib_llvm: bool = false,
6463 strip: bool = true,
6564 name: []const u8 = &.{},
6665 target: std.Target = builtin.target,
......@@ -77,11 +76,11 @@ pub const String = enum(u32) {
7776 return self.toIndex() == null;
7877 }
7978
80 pub fn slice(self: String, b: *const Builder) ?[:0]const u8 {
79 pub fn slice(self: String, builder: *const Builder) ?[]const u8 {
8180 const index = self.toIndex() orelse return null;
82 const start = b.string_indices.items[index];
83 const end = b.string_indices.items[index + 1];
84 return b.string_bytes.items[start .. end - 1 :0];
81 const start = builder.string_indices.items[index];
82 const end = builder.string_indices.items[index + 1];
83 return builder.string_bytes.items[start..end];
8584 }
8685
8786 const FormatData = struct {
......@@ -94,17 +93,21 @@ pub const String = enum(u32) {
9493 _: std.fmt.FormatOptions,
9594 writer: anytype,
9695 ) @TypeOf(writer).Error!void {
97 if (comptime std.mem.indexOfNone(u8, fmt_str, "@\"")) |_|
96 if (comptime std.mem.indexOfNone(u8, fmt_str, "\"r")) |_|
9897 @compileError("invalid format string: '" ++ fmt_str ++ "'");
9998 assert(data.string != .none);
100 const sentinel_slice = data.string.slice(data.builder) orelse
99 const string_slice = data.string.slice(data.builder) orelse
101100 return writer.print("{d}", .{@intFromEnum(data.string)});
102 try printEscapedString(sentinel_slice[0 .. sentinel_slice.len + comptime @intFromBool(
103 std.mem.indexOfScalar(u8, fmt_str, '@') != null,
104 )], if (comptime std.mem.indexOfScalar(u8, fmt_str, '"')) |_|
105 .always_quote
106 else
107 .quote_unless_valid_identifier, writer);
101 if (comptime std.mem.indexOfScalar(u8, fmt_str, 'r')) |_|
102 return writer.writeAll(string_slice);
103 try printEscapedString(
104 string_slice,
105 if (comptime std.mem.indexOfScalar(u8, fmt_str, '"')) |_|
106 .always_quote
107 else
108 .quote_unless_valid_identifier,
109 writer,
110 );
108111 }
109112 pub fn fmt(self: String, builder: *const Builder) std.fmt.Formatter(format) {
110113 return .{ .data = .{ .string = self, .builder = builder } };
......@@ -130,6 +133,72 @@ pub const String = enum(u32) {
130133 };
131134};
132135
136pub const BinaryOpcode = enum(u4) {
137 add = 0,
138 sub = 1,
139 mul = 2,
140 udiv = 3,
141 sdiv = 4,
142 urem = 5,
143 srem = 6,
144 shl = 7,
145 lshr = 8,
146 ashr = 9,
147 @"and" = 10,
148 @"or" = 11,
149 xor = 12,
150};
151
152pub const CastOpcode = enum(u4) {
153 trunc = 0,
154 zext = 1,
155 sext = 2,
156 fptoui = 3,
157 fptosi = 4,
158 uitofp = 5,
159 sitofp = 6,
160 fptrunc = 7,
161 fpext = 8,
162 ptrtoint = 9,
163 inttoptr = 10,
164 bitcast = 11,
165 addrspacecast = 12,
166};
167
168pub const CmpPredicate = enum(u6) {
169 fcmp_false = 0,
170 fcmp_oeq = 1,
171 fcmp_ogt = 2,
172 fcmp_oge = 3,
173 fcmp_olt = 4,
174 fcmp_ole = 5,
175 fcmp_one = 6,
176 fcmp_ord = 7,
177 fcmp_uno = 8,
178 fcmp_ueq = 9,
179 fcmp_ugt = 10,
180 fcmp_uge = 11,
181 fcmp_ult = 12,
182 fcmp_ule = 13,
183 fcmp_une = 14,
184 fcmp_true = 15,
185 icmp_eq = 32,
186 icmp_ne = 33,
187 icmp_ugt = 34,
188 icmp_uge = 35,
189 icmp_ult = 36,
190 icmp_ule = 37,
191 icmp_sgt = 38,
192 icmp_sge = 39,
193 icmp_slt = 40,
194 icmp_sle = 41,
195};
196
197pub const StrtabString = struct {
198 offset: usize,
199 size: usize,
200};
201
133202pub const Type = enum(u32) {
134203 void,
135204 half,
......@@ -178,20 +247,20 @@ pub const Type = enum(u32) {
178247 named_structure,
179248 };
180249
181 pub const Simple = enum {
182 void,
183 half,
184 bfloat,
185 float,
186 double,
187 fp128,
188 x86_fp80,
189 ppc_fp128,
190 x86_amx,
191 x86_mmx,
192 label,
193 token,
194 metadata,
250 pub const Simple = enum(u5) {
251 void = 2,
252 half = 10,
253 bfloat = 23,
254 float = 3,
255 double = 4,
256 fp128 = 14,
257 x86_fp80 = 13,
258 ppc_fp128 = 15,
259 x86_amx = 24,
260 x86_mmx = 17,
261 label = 5,
262 token = 22,
263 metadata = 16,
195264 };
196265
197266 pub const Function = struct {
......@@ -579,7 +648,6 @@ pub const Type = enum(u32) {
579648 var visited: IsSizedVisited = .{};
580649 defer visited.deinit(builder.gpa);
581650 const result = try self.isSizedVisited(&visited, builder);
582 if (builder.useLibLlvm()) assert(result == self.toLlvm(builder).isSized().toBool());
583651 return result;
584652 }
585653
......@@ -766,11 +834,6 @@ pub const Type = enum(u32) {
766834 return .{ .data = .{ .type = self, .builder = builder } };
767835 }
768836
769 pub fn toLlvm(self: Type, builder: *const Builder) *llvm.Type {
770 assert(builder.useLibLlvm());
771 return builder.llvm.types.items[@intFromEnum(self)];
772 }
773
774837 const IsSizedVisited = std.AutoHashMapUnmanaged(Type, void);
775838 fn isSizedVisited(
776839 self: Type,
......@@ -1051,14 +1114,21 @@ pub const Attribute = union(Kind) {
10511114 .no_sanitize_hwaddress,
10521115 .sanitize_address_dyninit,
10531116 => |kind| {
1054 const field = @typeInfo(Attribute).Union.fields[@intFromEnum(kind)];
1117 const field = comptime blk: {
1118 @setEvalBranchQuota(10_000);
1119 for (@typeInfo(Attribute).Union.fields) |field| {
1120 if (std.mem.eql(u8, field.name, @tagName(kind))) break :blk field;
1121 }
1122 unreachable;
1123 };
10551124 comptime assert(std.mem.eql(u8, @tagName(kind), field.name));
10561125 return @unionInit(Attribute, field.name, switch (field.type) {
10571126 void => {},
10581127 u32 => storage.value,
10591128 Alignment, String, Type, UwTable => @enumFromInt(storage.value),
10601129 AllocKind, AllocSize, FpClass, Memory, VScaleRange => @bitCast(storage.value),
1061 else => @compileError("bad payload type: " ++ @typeName(field.type)),
1130 else => @compileError("bad payload type: " ++ field.name ++ ": " ++
1131 @typeName(field.type)),
10621132 });
10631133 },
10641134 .string, .none => unreachable,
......@@ -1246,109 +1316,104 @@ pub const Attribute = union(Kind) {
12461316 fn toStorage(self: Index, builder: *const Builder) Storage {
12471317 return builder.attributes.keys()[@intFromEnum(self)];
12481318 }
1249
1250 fn toLlvm(self: Index, builder: *const Builder) *llvm.Attribute {
1251 assert(builder.useLibLlvm());
1252 return builder.llvm.attributes.items[@intFromEnum(self)];
1253 }
12541319 };
12551320
12561321 pub const Kind = enum(u32) {
12571322 // Parameter Attributes
1258 zeroext,
1259 signext,
1260 inreg,
1261 byval,
1262 byref,
1263 preallocated,
1264 inalloca,
1265 sret,
1266 elementtype,
1267 @"align",
1268 @"noalias",
1269 nocapture,
1270 nofree,
1271 nest,
1272 returned,
1273 nonnull,
1274 dereferenceable,
1275 dereferenceable_or_null,
1276 swiftself,
1277 swiftasync,
1278 swifterror,
1279 immarg,
1280 noundef,
1281 nofpclass,
1282 alignstack,
1283 allocalign,
1284 allocptr,
1285 readnone,
1286 readonly,
1287 writeonly,
1323 zeroext = 34,
1324 signext = 24,
1325 inreg = 5,
1326 byval = 3,
1327 byref = 69,
1328 preallocated = 65,
1329 inalloca = 38,
1330 sret = 29, // TODO: ?
1331 elementtype = 77,
1332 @"align" = 1,
1333 @"noalias" = 9,
1334 nocapture = 11,
1335 nofree = 62,
1336 nest = 8,
1337 returned = 22,
1338 nonnull = 39,
1339 dereferenceable = 41,
1340 dereferenceable_or_null = 42,
1341 swiftself = 46,
1342 swiftasync = 75,
1343 swifterror = 47,
1344 immarg = 60,
1345 noundef = 68,
1346 nofpclass = 87,
1347 alignstack = 25,
1348 allocalign = 80,
1349 allocptr = 81,
1350 readnone = 20,
1351 readonly = 21,
1352 writeonly = 52,
12881353
12891354 // Function Attributes
12901355 //alignstack,
1291 allockind,
1292 allocsize,
1293 alwaysinline,
1294 builtin,
1295 cold,
1296 convergent,
1297 disable_sanitizer_information,
1298 fn_ret_thunk_extern,
1299 hot,
1300 inlinehint,
1301 jumptable,
1302 memory,
1303 minsize,
1304 naked,
1305 nobuiltin,
1306 nocallback,
1307 noduplicate,
1356 allockind = 82,
1357 allocsize = 51,
1358 alwaysinline = 2,
1359 builtin = 35,
1360 cold = 36,
1361 convergent = 43,
1362 disable_sanitizer_information = 78,
1363 fn_ret_thunk_extern = 84,
1364 hot = 72,
1365 inlinehint = 4,
1366 jumptable = 40,
1367 memory = 86,
1368 minsize = 6,
1369 naked = 7,
1370 nobuiltin = 10,
1371 nocallback = 71,
1372 noduplicate = 12,
13081373 //nofree,
1309 noimplicitfloat,
1310 @"noinline",
1311 nomerge,
1312 nonlazybind,
1313 noprofile,
1314 skipprofile,
1315 noredzone,
1316 noreturn,
1317 norecurse,
1318 willreturn,
1319 nosync,
1320 nounwind,
1321 nosanitize_bounds,
1322 nosanitize_coverage,
1323 null_pointer_is_valid,
1324 optforfuzzing,
1325 optnone,
1326 optsize,
1374 noimplicitfloat = 13,
1375 @"noinline" = 14,
1376 nomerge = 66,
1377 nonlazybind = 15,
1378 noprofile = 73,
1379 skipprofile = 85,
1380 noredzone = 16,
1381 noreturn = 17,
1382 norecurse = 48,
1383 willreturn = 61,
1384 nosync = 63,
1385 nounwind = 18,
1386 nosanitize_bounds = 79,
1387 nosanitize_coverage = 76,
1388 null_pointer_is_valid = 67,
1389 optforfuzzing = 57,
1390 optnone = 37,
1391 optsize = 19,
13271392 //preallocated,
1328 returns_twice,
1329 safestack,
1330 sanitize_address,
1331 sanitize_memory,
1332 sanitize_thread,
1333 sanitize_hwaddress,
1334 sanitize_memtag,
1335 speculative_load_hardening,
1336 speculatable,
1337 ssp,
1338 sspstrong,
1339 sspreq,
1340 strictfp,
1341 uwtable,
1342 nocf_check,
1343 shadowcallstack,
1344 mustprogress,
1345 vscale_range,
1393 returns_twice = 23,
1394 safestack = 44,
1395 sanitize_address = 30,
1396 sanitize_memory = 32,
1397 sanitize_thread = 31,
1398 sanitize_hwaddress = 55,
1399 sanitize_memtag = 64,
1400 speculative_load_hardening = 59,
1401 speculatable = 53,
1402 ssp = 26,
1403 sspstrong = 28,
1404 sspreq = 27,
1405 strictfp = 54,
1406 uwtable = 33,
1407 nocf_check = 56,
1408 shadowcallstack = 58,
1409 mustprogress = 70,
1410 vscale_range = 74,
13461411
13471412 // Global Attributes
1348 no_sanitize_address,
1349 no_sanitize_hwaddress,
1413 no_sanitize_address = 100,
1414 no_sanitize_hwaddress = 101,
13501415 //sanitize_memtag,
1351 sanitize_address_dyninit,
1416 sanitize_address_dyninit = 102,
13521417
13531418 string = std.math.maxInt(u31),
13541419 none = std.math.maxInt(u32),
......@@ -1368,11 +1433,6 @@ pub const Attribute = union(Kind) {
13681433 const str: String = @enumFromInt(@intFromEnum(self));
13691434 return if (str.isAnon()) null else str;
13701435 }
1371
1372 fn toLlvm(self: Kind, builder: *const Builder) *c_uint {
1373 assert(builder.useLibLlvm());
1374 return &builder.llvm.attribute_kind_ids.?[@intFromEnum(self)];
1375 }
13761436 };
13771437
13781438 pub const FpClass = packed struct(u32) {
......@@ -1494,12 +1554,12 @@ pub const Attribute = union(Kind) {
14941554
14951555 fn toStorage(self: Attribute) Storage {
14961556 return switch (self) {
1497 inline else => |value| .{ .kind = @as(Kind, self), .value = switch (@TypeOf(value)) {
1557 inline else => |value, tag| .{ .kind = @as(Kind, self), .value = switch (@TypeOf(value)) {
14981558 void => 0,
14991559 u32 => value,
15001560 Alignment, String, Type, UwTable => @intFromEnum(value),
15011561 AllocKind, AllocSize, FpClass, Memory, VScaleRange => @bitCast(value),
1502 else => @compileError("bad payload type: " ++ @typeName(@TypeOf(value))),
1562 else => @compileError("bad payload type: " ++ @tagName(tag) ++ @typeName(@TypeOf(value))),
15031563 } },
15041564 .string => |string_attr| .{
15051565 .kind = Kind.fromString(string_attr.kind),
......@@ -1709,18 +1769,18 @@ pub const FunctionAttributes = enum(u32) {
17091769 }
17101770};
17111771
1712pub const Linkage = enum {
1713 private,
1714 internal,
1715 weak,
1716 weak_odr,
1717 linkonce,
1718 linkonce_odr,
1719 available_externally,
1720 appending,
1721 common,
1722 extern_weak,
1723 external,
1772pub const Linkage = enum(u4) {
1773 private = 9,
1774 internal = 3,
1775 weak = 1,
1776 weak_odr = 10,
1777 linkonce = 4,
1778 linkonce_odr = 11,
1779 available_externally = 12,
1780 appending = 2,
1781 common = 8,
1782 extern_weak = 7,
1783 external = 0,
17241784
17251785 pub fn format(
17261786 self: Linkage,
......@@ -1731,20 +1791,16 @@ pub const Linkage = enum {
17311791 if (self != .external) try writer.print(" {s}", .{@tagName(self)});
17321792 }
17331793
1734 fn toLlvm(self: Linkage) llvm.Linkage {
1735 return switch (self) {
1736 .private => .Private,
1737 .internal => .Internal,
1738 .weak => .WeakAny,
1739 .weak_odr => .WeakODR,
1740 .linkonce => .LinkOnceAny,
1741 .linkonce_odr => .LinkOnceODR,
1742 .available_externally => .AvailableExternally,
1743 .appending => .Appending,
1744 .common => .Common,
1745 .extern_weak => .ExternalWeak,
1746 .external => .External,
1747 };
1794 fn formatOptional(
1795 data: ?Linkage,
1796 comptime _: []const u8,
1797 _: std.fmt.FormatOptions,
1798 writer: anytype,
1799 ) @TypeOf(writer).Error!void {
1800 if (data) |linkage| try writer.print(" {s}", .{@tagName(linkage)});
1801 }
1802 pub fn fmtOptional(self: ?Linkage) std.fmt.Formatter(formatOptional) {
1803 return .{ .data = self };
17481804 }
17491805};
17501806
......@@ -1763,10 +1819,10 @@ pub const Preemption = enum {
17631819 }
17641820};
17651821
1766pub const Visibility = enum {
1767 default,
1768 hidden,
1769 protected,
1822pub const Visibility = enum(u2) {
1823 default = 0,
1824 hidden = 1,
1825 protected = 2,
17701826
17711827 pub fn format(
17721828 self: Visibility,
......@@ -1776,20 +1832,12 @@ pub const Visibility = enum {
17761832 ) @TypeOf(writer).Error!void {
17771833 if (self != .default) try writer.print(" {s}", .{@tagName(self)});
17781834 }
1779
1780 fn toLlvm(self: Visibility) llvm.Visibility {
1781 return switch (self) {
1782 .default => .Default,
1783 .hidden => .Hidden,
1784 .protected => .Protected,
1785 };
1786 }
17871835};
17881836
1789pub const DllStorageClass = enum {
1790 default,
1791 dllimport,
1792 dllexport,
1837pub const DllStorageClass = enum(u2) {
1838 default = 0,
1839 dllimport = 1,
1840 dllexport = 2,
17931841
17941842 pub fn format(
17951843 self: DllStorageClass,
......@@ -1799,22 +1847,14 @@ pub const DllStorageClass = enum {
17991847 ) @TypeOf(writer).Error!void {
18001848 if (self != .default) try writer.print(" {s}", .{@tagName(self)});
18011849 }
1802
1803 fn toLlvm(self: DllStorageClass) llvm.DLLStorageClass {
1804 return switch (self) {
1805 .default => .Default,
1806 .dllimport => .DLLImport,
1807 .dllexport => .DLLExport,
1808 };
1809 }
18101850};
18111851
1812pub const ThreadLocal = enum {
1813 default,
1814 generaldynamic,
1815 localdynamic,
1816 initialexec,
1817 localexec,
1852pub const ThreadLocal = enum(u3) {
1853 default = 0,
1854 generaldynamic = 1,
1855 localdynamic = 2,
1856 initialexec = 3,
1857 localexec = 4,
18181858
18191859 pub fn format(
18201860 self: ThreadLocal,
......@@ -1826,24 +1866,14 @@ pub const ThreadLocal = enum {
18261866 try writer.print("{s}thread_local", .{prefix});
18271867 if (self != .generaldynamic) try writer.print("({s})", .{@tagName(self)});
18281868 }
1829
1830 fn toLlvm(self: ThreadLocal) llvm.ThreadLocalMode {
1831 return switch (self) {
1832 .default => .NotThreadLocal,
1833 .generaldynamic => .GeneralDynamicTLSModel,
1834 .localdynamic => .LocalDynamicTLSModel,
1835 .initialexec => .InitialExecTLSModel,
1836 .localexec => .LocalExecTLSModel,
1837 };
1838 }
18391869};
18401870
18411871pub const Mutability = enum { global, constant };
18421872
1843pub const UnnamedAddr = enum {
1844 default,
1845 unnamed_addr,
1846 local_unnamed_addr,
1873pub const UnnamedAddr = enum(u2) {
1874 default = 0,
1875 unnamed_addr = 1,
1876 local_unnamed_addr = 2,
18471877
18481878 pub fn format(
18491879 self: UnnamedAddr,
......@@ -1971,6 +2001,10 @@ pub const Alignment = enum(u6) {
19712001 return if (self == .default) null else @as(u64, 1) << @intFromEnum(self);
19722002 }
19732003
2004 pub fn toLlvm(self: Alignment) u6 {
2005 return if (self == .default) 0 else (@intFromEnum(self) + 1);
2006 }
2007
19742008 pub fn format(
19752009 self: Alignment,
19762010 comptime prefix: []const u8,
......@@ -2100,11 +2134,6 @@ pub const CallConv = enum(u10) {
21002134 _ => try writer.print(" cc{d}", .{@intFromEnum(self)}),
21012135 }
21022136 }
2103
2104 fn toLlvm(self: CallConv) llvm.CallConv {
2105 // These enum values appear in LLVM IR, and so are guaranteed to be stable.
2106 return @enumFromInt(@intFromEnum(self));
2107 }
21082137};
21092138
21102139pub const Global = struct {
......@@ -2117,6 +2146,7 @@ pub const Global = struct {
21172146 externally_initialized: ExternallyInitialized = .default,
21182147 type: Type,
21192148 partition: String = .none,
2149 dbg: Metadata = .none,
21202150 kind: union(enum) {
21212151 alias: Alias.Index,
21222152 variable: Variable.Index,
......@@ -2153,6 +2183,18 @@ pub const Global = struct {
21532183 return builder.globals.keys()[@intFromEnum(self.unwrap(builder))];
21542184 }
21552185
2186 pub fn strtab(self: Index, builder: *const Builder) StrtabString {
2187 const name_index = self.name(builder).toIndex() orelse return .{
2188 .offset = 0,
2189 .size = 0,
2190 };
2191
2192 return .{
2193 .offset = builder.string_indices.items[name_index],
2194 .size = builder.string_indices.items[name_index + 1] - builder.string_indices.items[name_index],
2195 };
2196 }
2197
21562198 pub fn typeOf(self: Index, builder: *const Builder) Type {
21572199 return self.ptrConst(builder).type;
21582200 }
......@@ -2162,32 +2204,25 @@ pub const Global = struct {
21622204 }
21632205
21642206 pub fn setLinkage(self: Index, linkage: Linkage, builder: *Builder) void {
2165 if (builder.useLibLlvm()) self.toLlvm(builder).setLinkage(linkage.toLlvm());
21662207 self.ptr(builder).linkage = linkage;
21672208 self.updateDsoLocal(builder);
21682209 }
21692210
21702211 pub fn setVisibility(self: Index, visibility: Visibility, builder: *Builder) void {
2171 if (builder.useLibLlvm()) self.toLlvm(builder).setVisibility(visibility.toLlvm());
21722212 self.ptr(builder).visibility = visibility;
21732213 self.updateDsoLocal(builder);
21742214 }
21752215
21762216 pub fn setDllStorageClass(self: Index, class: DllStorageClass, builder: *Builder) void {
2177 if (builder.useLibLlvm()) self.toLlvm(builder).setDLLStorageClass(class.toLlvm());
21782217 self.ptr(builder).dll_storage_class = class;
21792218 }
21802219
21812220 pub fn setUnnamedAddr(self: Index, unnamed_addr: UnnamedAddr, builder: *Builder) void {
2182 if (builder.useLibLlvm()) self.toLlvm(builder).setUnnamedAddr(
2183 llvm.Bool.fromBool(unnamed_addr != .default),
2184 );
21852221 self.ptr(builder).unnamed_addr = unnamed_addr;
21862222 }
21872223
2188 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
2189 assert(builder.useLibLlvm());
2190 return builder.llvm.globals.items[@intFromEnum(self.unwrap(builder))];
2224 pub fn setDebugMetadata(self: Index, dbg: Metadata, builder: *Builder) void {
2225 self.ptr(builder).dbg = dbg;
21912226 }
21922227
21932228 const FormatData = struct {
......@@ -2220,13 +2255,10 @@ pub const Global = struct {
22202255
22212256 pub fn replace(self: Index, other: Index, builder: *Builder) Allocator.Error!void {
22222257 try builder.ensureUnusedGlobalCapacity(.empty);
2223 if (builder.useLibLlvm())
2224 try builder.llvm.replacements.ensureUnusedCapacity(builder.gpa, 1);
22252258 self.replaceAssumeCapacity(other, builder);
22262259 }
22272260
22282261 pub fn delete(self: Index, builder: *Builder) void {
2229 if (builder.useLibLlvm()) self.toLlvm(builder).eraseGlobalValue();
22302262 self.ptr(builder).kind = .{ .replaced = .none };
22312263 }
22322264
......@@ -2254,12 +2286,8 @@ pub const Global = struct {
22542286 const old_name = self.name(builder);
22552287 if (new_name == old_name) return;
22562288 const index = @intFromEnum(self.unwrap(builder));
2257 if (builder.useLibLlvm())
2258 builder.llvm.globals.appendAssumeCapacity(builder.llvm.globals.items[index]);
22592289 _ = builder.addGlobalAssumeCapacity(new_name, builder.globals.values()[index]);
2260 if (builder.useLibLlvm()) _ = builder.llvm.globals.pop();
22612290 builder.globals.swapRemoveAt(index);
2262 self.updateName(builder);
22632291 if (!old_name.isAnon()) return;
22642292 builder.next_unnamed_global = @enumFromInt(@intFromEnum(builder.next_unnamed_global) - 1);
22652293 if (builder.next_unnamed_global == old_name) return;
......@@ -2272,23 +2300,10 @@ pub const Global = struct {
22722300 self.renameAssumeCapacity(other_name, builder);
22732301 }
22742302
2275 fn updateName(self: Index, builder: *const Builder) void {
2276 if (!builder.useLibLlvm()) return;
2277 const index = @intFromEnum(self.unwrap(builder));
2278 const name_slice = self.name(builder).slice(builder) orelse "";
2279 builder.llvm.globals.items[index].setValueName(name_slice.ptr, name_slice.len);
2280 }
2281
22822303 fn replaceAssumeCapacity(self: Index, other: Index, builder: *Builder) void {
22832304 if (self.eql(other, builder)) return;
22842305 builder.next_replaced_global = @enumFromInt(@intFromEnum(builder.next_replaced_global) - 1);
22852306 self.renameAssumeCapacity(builder.next_replaced_global, builder);
2286 if (builder.useLibLlvm()) {
2287 const self_llvm = self.toLlvm(builder);
2288 self_llvm.replaceAllUsesWith(other.toLlvm(builder));
2289 self_llvm.removeGlobalValue();
2290 builder.llvm.replacements.putAssumeCapacityNoClobber(self_llvm, other);
2291 }
22922307 self.ptr(builder).kind = .{ .replaced = other.unwrap(builder) };
22932308 }
22942309
......@@ -2345,13 +2360,8 @@ pub const Alias = struct {
23452360 }
23462361
23472362 pub fn setAliasee(self: Index, aliasee: Constant, builder: *Builder) void {
2348 if (builder.useLibLlvm()) self.toLlvm(builder).setAliasee(aliasee.toLlvm(builder));
23492363 self.ptr(builder).aliasee = aliasee;
23502364 }
2351
2352 fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
2353 return self.ptrConst(builder).global.toLlvm(builder);
2354 }
23552365 };
23562366};
23572367
......@@ -2404,14 +2414,10 @@ pub const Variable = struct {
24042414 }
24052415
24062416 pub fn setThreadLocal(self: Index, thread_local: ThreadLocal, builder: *Builder) void {
2407 if (builder.useLibLlvm()) self.toLlvm(builder).setThreadLocalMode(thread_local.toLlvm());
24082417 self.ptr(builder).thread_local = thread_local;
24092418 }
24102419
24112420 pub fn setMutability(self: Index, mutability: Mutability, builder: *Builder) void {
2412 if (builder.useLibLlvm()) self.toLlvm(builder).setGlobalConstant(
2413 llvm.Bool.fromBool(mutability == .constant),
2414 );
24152421 self.ptr(builder).mutability = mutability;
24162422 }
24172423
......@@ -2424,67 +2430,25 @@ pub const Variable = struct {
24242430 const variable = self.ptrConst(builder);
24252431 const global = variable.global.ptr(builder);
24262432 const initializer_type = initializer.typeOf(builder);
2427 if (builder.useLibLlvm() and global.type != initializer_type) {
2428 try builder.llvm.replacements.ensureUnusedCapacity(builder.gpa, 1);
2429 // LLVM does not allow us to change the type of globals. So we must
2430 // create a new global with the correct type, copy all its attributes,
2431 // and then update all references to point to the new global,
2432 // delete the original, and rename the new one to the old one's name.
2433 // This is necessary because LLVM does not support const bitcasting
2434 // a struct with padding bytes, which is needed to lower a const union value
2435 // to LLVM, when a field other than the most-aligned is active. Instead,
2436 // we must lower to an unnamed struct, and pointer cast at usage sites
2437 // of the global. Such an unnamed struct is the cause of the global type
2438 // mismatch, because we don't have the LLVM type until the *value* is created,
2439 // whereas the global needs to be created based on the type alone, because
2440 // lowering the value may reference the global as a pointer.
2441 // Related: https://github.com/ziglang/zig/issues/13265
2442 const old_global = &builder.llvm.globals.items[@intFromEnum(variable.global)];
2443 const new_global = builder.llvm.module.?.addGlobalInAddressSpace(
2444 initializer_type.toLlvm(builder),
2445 "",
2446 @intFromEnum(global.addr_space),
2447 );
2448 new_global.setLinkage(global.linkage.toLlvm());
2449 new_global.setUnnamedAddr(llvm.Bool.fromBool(global.unnamed_addr != .default));
2450 new_global.setAlignment(@intCast(variable.alignment.toByteUnits() orelse 0));
2451 if (variable.section != .none)
2452 new_global.setSection(variable.section.slice(builder).?);
2453 old_global.*.replaceAllUsesWith(new_global);
2454 builder.llvm.replacements.putAssumeCapacityNoClobber(old_global.*, variable.global);
2455 new_global.takeName(old_global.*);
2456 old_global.*.removeGlobalValue();
2457 old_global.* = new_global;
2458 self.ptr(builder).mutability = .global;
2459 }
24602433 global.type = initializer_type;
24612434 }
2462 if (builder.useLibLlvm()) self.toLlvm(builder).setInitializer(switch (initializer) {
2463 .no_init => null,
2464 else => initializer.toLlvm(builder),
2465 });
24662435 self.ptr(builder).init = initializer;
24672436 }
24682437
24692438 pub fn setSection(self: Index, section: String, builder: *Builder) void {
2470 if (builder.useLibLlvm()) self.toLlvm(builder).setSection(section.slice(builder).?);
24712439 self.ptr(builder).section = section;
24722440 }
24732441
24742442 pub fn setAlignment(self: Index, alignment: Alignment, builder: *Builder) void {
2475 if (builder.useLibLlvm())
2476 self.toLlvm(builder).setAlignment(@intCast(alignment.toByteUnits() orelse 0));
24772443 self.ptr(builder).alignment = alignment;
24782444 }
24792445
24802446 pub fn getAlignment(self: Index, builder: *Builder) Alignment {
2481 if (builder.useLibLlvm())
2482 return Alignment.fromByteUnits(self.toLlvm(builder).getAlignment());
24832447 return self.ptr(builder).alignment;
24842448 }
24852449
2486 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
2487 return self.ptrConst(builder).global.toLlvm(builder);
2450 pub fn setGlobalVariableExpression(self: Index, expression: Metadata, builder: *Builder) void {
2451 self.ptrConst(builder).global.setDebugMetadata(expression, builder);
24882452 }
24892453 };
24902454};
......@@ -2633,6 +2597,10 @@ pub const Intrinsic = enum {
26332597 @"threadlocal.address",
26342598 vscale,
26352599
2600 // Debug
2601 @"dbg.declare",
2602 @"dbg.value",
2603
26362604 // AMDGPU
26372605 @"amdgcn.workitem.id.x",
26382606 @"amdgcn.workitem.id.y",
......@@ -3727,6 +3695,25 @@ pub const Intrinsic = enum {
37273695 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
37283696 },
37293697
3698 .@"dbg.declare" = .{
3699 .ret_len = 0,
3700 .params = &.{
3701 .{ .kind = .{ .type = .metadata } },
3702 .{ .kind = .{ .type = .metadata } },
3703 .{ .kind = .{ .type = .metadata } },
3704 },
3705 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3706 },
3707 .@"dbg.value" = .{
3708 .ret_len = 0,
3709 .params = &.{
3710 .{ .kind = .{ .type = .metadata } },
3711 .{ .kind = .{ .type = .metadata } },
3712 .{ .kind = .{ .type = .metadata } },
3713 },
3714 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3715 },
3716
37303717 .@"amdgcn.workitem.id.x" = .{
37313718 .ret_len = 1,
37323719 .params = &.{
......@@ -3809,7 +3796,9 @@ pub const Function = struct {
38093796 blocks: []const Block = &.{},
38103797 instructions: std.MultiArrayList(Instruction) = .{},
38113798 names: [*]const String = &[0]String{},
3812 metadata: ?[*]const Metadata = null,
3799 value_indices: [*]const u32 = &[0]u32{},
3800 debug_locations: std.AutoHashMapUnmanaged(Instruction.Index, Metadata) = .{},
3801 debug_values: []const Instruction.Index = &.{},
38133802 extra: []const u32 = &.{},
38143803
38153804 pub const Index = enum(u32) {
......@@ -3853,7 +3842,6 @@ pub const Function = struct {
38533842 }
38543843
38553844 pub fn setCallConv(self: Index, call_conv: CallConv, builder: *Builder) void {
3856 if (builder.useLibLlvm()) self.toLlvm(builder).setFunctionCallConv(call_conv.toLlvm());
38573845 self.ptr(builder).call_conv = call_conv;
38583846 }
38593847
......@@ -3862,94 +3850,19 @@ pub const Function = struct {
38623850 new_function_attributes: FunctionAttributes,
38633851 builder: *Builder,
38643852 ) void {
3865 if (builder.useLibLlvm()) {
3866 const llvm_function = self.toLlvm(builder);
3867 const old_function_attributes = self.ptrConst(builder).attributes;
3868 for (0..@max(
3869 old_function_attributes.slice(builder).len,
3870 new_function_attributes.slice(builder).len,
3871 )) |function_attribute_index| {
3872 const llvm_attribute_index =
3873 @as(llvm.AttributeIndex, @intCast(function_attribute_index)) -% 1;
3874 const old_attributes_slice =
3875 old_function_attributes.get(function_attribute_index, builder).slice(builder);
3876 const new_attributes_slice =
3877 new_function_attributes.get(function_attribute_index, builder).slice(builder);
3878 var old_attribute_index: usize = 0;
3879 var new_attribute_index: usize = 0;
3880 while (true) {
3881 const old_attribute_kind = if (old_attribute_index < old_attributes_slice.len)
3882 old_attributes_slice[old_attribute_index].getKind(builder)
3883 else
3884 .none;
3885 const new_attribute_kind = if (new_attribute_index < new_attributes_slice.len)
3886 new_attributes_slice[new_attribute_index].getKind(builder)
3887 else
3888 .none;
3889 switch (std.math.order(
3890 @intFromEnum(old_attribute_kind),
3891 @intFromEnum(new_attribute_kind),
3892 )) {
3893 .lt => {
3894 // Removed
3895 if (old_attribute_kind.toString()) |attribute_name| {
3896 const attribute_name_slice = attribute_name.slice(builder).?;
3897 llvm_function.removeStringAttributeAtIndex(
3898 llvm_attribute_index,
3899 attribute_name_slice.ptr,
3900 @intCast(attribute_name_slice.len),
3901 );
3902 } else {
3903 const llvm_kind_id = old_attribute_kind.toLlvm(builder).*;
3904 assert(llvm_kind_id != 0);
3905 llvm_function.removeEnumAttributeAtIndex(
3906 llvm_attribute_index,
3907 llvm_kind_id,
3908 );
3909 }
3910 old_attribute_index += 1;
3911 continue;
3912 },
3913 .eq => {
3914 // Iteration finished
3915 if (old_attribute_kind == .none) break;
3916 // No change
3917 if (old_attributes_slice[old_attribute_index] ==
3918 new_attributes_slice[new_attribute_index])
3919 {
3920 old_attribute_index += 1;
3921 new_attribute_index += 1;
3922 continue;
3923 }
3924 old_attribute_index += 1;
3925 },
3926 .gt => {},
3927 }
3928 // New or changed
3929 llvm_function.addAttributeAtIndex(
3930 llvm_attribute_index,
3931 new_attributes_slice[new_attribute_index].toLlvm(builder),
3932 );
3933 new_attribute_index += 1;
3934 }
3935 }
3936 }
39373853 self.ptr(builder).attributes = new_function_attributes;
39383854 }
39393855
39403856 pub fn setSection(self: Index, section: String, builder: *Builder) void {
3941 if (builder.useLibLlvm()) self.toLlvm(builder).setSection(section.slice(builder).?);
39423857 self.ptr(builder).section = section;
39433858 }
39443859
39453860 pub fn setAlignment(self: Index, alignment: Alignment, builder: *Builder) void {
3946 if (builder.useLibLlvm())
3947 self.toLlvm(builder).setAlignment(@intCast(alignment.toByteUnits() orelse 0));
39483861 self.ptr(builder).alignment = alignment;
39493862 }
39503863
3951 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
3952 return self.ptrConst(builder).global.toLlvm(builder);
3864 pub fn setSubprogram(self: Index, subprogram: Metadata, builder: *Builder) void {
3865 self.ptrConst(builder).global.setDebugMetadata(subprogram, builder);
39533866 }
39543867 };
39553868
......@@ -4098,6 +4011,143 @@ pub const Function = struct {
40984011 va_arg,
40994012 xor,
41004013 zext,
4014
4015 pub fn toBinaryOpcode(self: Tag) BinaryOpcode {
4016 return switch (self) {
4017 .add,
4018 .@"add nsw",
4019 .@"add nuw",
4020 .@"add nuw nsw",
4021 .fadd,
4022 .@"fadd fast",
4023 => .add,
4024 .sub,
4025 .@"sub nsw",
4026 .@"sub nuw",
4027 .@"sub nuw nsw",
4028 .fsub,
4029 .@"fsub fast",
4030 => .sub,
4031 .sdiv,
4032 .@"sdiv exact",
4033 .fdiv,
4034 .@"fdiv fast",
4035 => .sdiv,
4036 .fmul,
4037 .@"fmul fast",
4038 .mul,
4039 .@"mul nsw",
4040 .@"mul nuw",
4041 .@"mul nuw nsw",
4042 => .mul,
4043 .srem,
4044 .frem,
4045 .@"frem fast",
4046 => .srem,
4047 .udiv,
4048 .@"udiv exact",
4049 => .udiv,
4050 .shl,
4051 .@"shl nsw",
4052 .@"shl nuw",
4053 .@"shl nuw nsw",
4054 => .shl,
4055 .lshr,
4056 .@"lshr exact",
4057 => .lshr,
4058 .ashr,
4059 .@"ashr exact",
4060 => .ashr,
4061 .@"and" => .@"and",
4062 .@"or" => .@"or",
4063 .xor => .xor,
4064 .urem => .urem,
4065 else => unreachable,
4066 };
4067 }
4068
4069 pub fn toCastOpcode(self: Tag) CastOpcode {
4070 return switch (self) {
4071 .trunc => .trunc,
4072 .zext => .zext,
4073 .sext => .sext,
4074 .fptoui => .fptoui,
4075 .fptosi => .fptosi,
4076 .uitofp => .uitofp,
4077 .sitofp => .sitofp,
4078 .fptrunc => .fptrunc,
4079 .fpext => .fpext,
4080 .ptrtoint => .ptrtoint,
4081 .inttoptr => .inttoptr,
4082 .bitcast => .bitcast,
4083 .addrspacecast => .addrspacecast,
4084 else => unreachable,
4085 };
4086 }
4087
4088 pub fn toCmpPredicate(self: Tag) CmpPredicate {
4089 return switch (self) {
4090 .@"fcmp false",
4091 .@"fcmp fast false",
4092 => .fcmp_false,
4093 .@"fcmp oeq",
4094 .@"fcmp fast oeq",
4095 => .fcmp_oeq,
4096 .@"fcmp oge",
4097 .@"fcmp fast oge",
4098 => .fcmp_oge,
4099 .@"fcmp ogt",
4100 .@"fcmp fast ogt",
4101 => .fcmp_ogt,
4102 .@"fcmp ole",
4103 .@"fcmp fast ole",
4104 => .fcmp_ole,
4105 .@"fcmp olt",
4106 .@"fcmp fast olt",
4107 => .fcmp_olt,
4108 .@"fcmp one",
4109 .@"fcmp fast one",
4110 => .fcmp_one,
4111 .@"fcmp ord",
4112 .@"fcmp fast ord",
4113 => .fcmp_ord,
4114 .@"fcmp true",
4115 .@"fcmp fast true",
4116 => .fcmp_true,
4117 .@"fcmp ueq",
4118 .@"fcmp fast ueq",
4119 => .fcmp_ueq,
4120 .@"fcmp uge",
4121 .@"fcmp fast uge",
4122 => .fcmp_uge,
4123 .@"fcmp ugt",
4124 .@"fcmp fast ugt",
4125 => .fcmp_ugt,
4126 .@"fcmp ule",
4127 .@"fcmp fast ule",
4128 => .fcmp_ule,
4129 .@"fcmp ult",
4130 .@"fcmp fast ult",
4131 => .fcmp_ult,
4132 .@"fcmp une",
4133 .@"fcmp fast une",
4134 => .fcmp_une,
4135 .@"fcmp uno",
4136 .@"fcmp fast uno",
4137 => .fcmp_uno,
4138 .@"icmp eq" => .icmp_eq,
4139 .@"icmp ne" => .icmp_ne,
4140 .@"icmp sge" => .icmp_sge,
4141 .@"icmp sgt" => .icmp_sgt,
4142 .@"icmp sle" => .icmp_sle,
4143 .@"icmp slt" => .icmp_slt,
4144 .@"icmp uge" => .icmp_uge,
4145 .@"icmp ugt" => .icmp_ugt,
4146 .@"icmp ule" => .icmp_ule,
4147 .@"icmp ult" => .icmp_ult,
4148 else => unreachable,
4149 };
4150 }
41014151 };
41024152
41034153 pub const Index = enum(u32) {
......@@ -4108,6 +4158,10 @@ pub const Function = struct {
41084158 return function.names[@intFromEnum(self)];
41094159 }
41104160
4161 pub fn valueIndex(self: Instruction.Index, function: *const Function) u32 {
4162 return function.value_indices[@intFromEnum(self)];
4163 }
4164
41114165 pub fn toValue(self: Instruction.Index) Value {
41124166 return @enumFromInt(@intFromEnum(self));
41134167 }
......@@ -4136,6 +4190,7 @@ pub const Function = struct {
41364190 .@"store atomic",
41374191 .@"switch",
41384192 .@"unreachable",
4193 .block,
41394194 => false,
41404195 .call,
41414196 .@"call fast",
......@@ -4240,7 +4295,7 @@ pub const Function = struct {
42404295 => wip.builder.structTypeAssumeCapacity(.normal, &.{
42414296 wip.extraData(CmpXchg, instruction.data).cmp.typeOfWip(wip),
42424297 .i1,
4243 }) catch unreachable,
4298 }),
42444299 .extractelement => wip.extraData(ExtractElement, instruction.data)
42454300 .val.typeOfWip(wip).childType(wip.builder),
42464301 .extractvalue => {
......@@ -4427,7 +4482,7 @@ pub const Function = struct {
44274482 function.extraData(CmpXchg, instruction.data)
44284483 .cmp.typeOf(function_index, builder),
44294484 .i1,
4430 }) catch unreachable,
4485 }),
44314486 .extractelement => function.extraData(ExtractElement, instruction.data)
44324487 .val.typeOf(function_index, builder).childType(builder),
44334488 .extractvalue => {
......@@ -4557,20 +4612,6 @@ pub const Function = struct {
45574612 ) std.fmt.Formatter(format) {
45584613 return .{ .data = .{ .instruction = self, .function = function, .builder = builder } };
45594614 }
4560
4561 fn toLlvm(self: Instruction.Index, wip: *const WipFunction) *llvm.Value {
4562 assert(wip.builder.useLibLlvm());
4563 const llvm_value = wip.llvm.instructions.items[@intFromEnum(self)];
4564 const global = wip.builder.llvm.replacements.get(llvm_value) orelse return llvm_value;
4565 return global.toLlvm(wip.builder);
4566 }
4567
4568 fn llvmName(self: Instruction.Index, wip: *const WipFunction) [:0]const u8 {
4569 return if (wip.builder.strip)
4570 ""
4571 else
4572 wip.names.items[@intFromEnum(self)].slice(wip.builder).?;
4573 }
45744615 };
45754616
45764617 pub const ExtraIndex = u32;
......@@ -4664,43 +4705,22 @@ pub const Function = struct {
46644705 val: Value,
46654706
46664707 pub const Operation = enum(u5) {
4667 xchg,
4668 add,
4669 sub,
4670 @"and",
4671 nand,
4672 @"or",
4673 xor,
4674 max,
4675 min,
4676 umax,
4677 umin,
4678 fadd,
4679 fsub,
4680 fmax,
4681 fmin,
4708 xchg = 0,
4709 add = 1,
4710 sub = 2,
4711 @"and" = 3,
4712 nand = 4,
4713 @"or" = 5,
4714 xor = 6,
4715 max = 7,
4716 min = 8,
4717 umax = 9,
4718 umin = 10,
4719 fadd = 11,
4720 fsub = 12,
4721 fmax = 13,
4722 fmin = 14,
46824723 none = std.math.maxInt(u5),
4683
4684 fn toLlvm(self: Operation) llvm.AtomicRMWBinOp {
4685 return switch (self) {
4686 .xchg => .Xchg,
4687 .add => .Add,
4688 .sub => .Sub,
4689 .@"and" => .And,
4690 .nand => .Nand,
4691 .@"or" => .Or,
4692 .xor => .Xor,
4693 .max => .Max,
4694 .min => .Min,
4695 .umax => .UMax,
4696 .umin => .UMin,
4697 .fadd => .FAdd,
4698 .fsub => .FSub,
4699 .fmax => .FMax,
4700 .fmin => .FMin,
4701 .none => unreachable,
4702 };
4703 }
47044724 };
47054725 };
47064726
......@@ -4764,7 +4784,9 @@ pub const Function = struct {
47644784
47654785 pub fn deinit(self: *Function, gpa: Allocator) void {
47664786 gpa.free(self.extra);
4767 if (self.metadata) |metadata| gpa.free(metadata[0..self.instructions.len]);
4787 gpa.free(self.debug_values);
4788 self.debug_locations.deinit(gpa);
4789 gpa.free(self.value_indices[0..self.instructions.len]);
47684790 gpa.free(self.names[0..self.instructions.len]);
47694791 self.instructions.deinit(gpa);
47704792 gpa.free(self.blocks);
......@@ -4822,7 +4844,7 @@ pub const Function = struct {
48224844 Instruction.Alloca.Info,
48234845 Instruction.Call.Info,
48244846 => @bitCast(value),
4825 else => @compileError("bad field type: " ++ @typeName(field.type)),
4847 else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),
48264848 };
48274849 return .{
48284850 .data = result,
......@@ -4838,16 +4860,14 @@ pub const Function = struct {
48384860pub const WipFunction = struct {
48394861 builder: *Builder,
48404862 function: Function.Index,
4841 llvm: if (build_options.have_llvm) struct {
4842 builder: *llvm.Builder,
4843 blocks: std.ArrayListUnmanaged(*llvm.BasicBlock),
4844 instructions: std.ArrayListUnmanaged(*llvm.Value),
4845 } else void,
4863 last_debug_location: Metadata,
4864 current_debug_location: Metadata,
48464865 cursor: Cursor,
48474866 blocks: std.ArrayListUnmanaged(Block),
48484867 instructions: std.MultiArrayList(Instruction),
48494868 names: std.ArrayListUnmanaged(String),
4850 metadata: std.ArrayListUnmanaged(Metadata),
4869 debug_locations: std.AutoArrayHashMapUnmanaged(Instruction.Index, Metadata),
4870 debug_values: std.AutoArrayHashMapUnmanaged(Instruction.Index, void),
48514871 extra: std.ArrayListUnmanaged(u32),
48524872
48534873 pub const Cursor = struct { block: Block.Index, instruction: u32 = 0 };
......@@ -4873,35 +4893,23 @@ pub const WipFunction = struct {
48734893 pub fn toInst(self: Index, function: *const Function) Instruction.Index {
48744894 return function.blocks[@intFromEnum(self)].instruction;
48754895 }
4876
4877 pub fn toLlvm(self: Index, wip: *const WipFunction) *llvm.BasicBlock {
4878 assert(wip.builder.useLibLlvm());
4879 return wip.llvm.blocks.items[@intFromEnum(self)];
4880 }
48814896 };
48824897 };
48834898
48844899 pub const Instruction = Function.Instruction;
48854900
48864901 pub fn init(builder: *Builder, function: Function.Index) Allocator.Error!WipFunction {
4887 if (builder.useLibLlvm()) {
4888 const llvm_function = function.toLlvm(builder);
4889 while (llvm_function.getFirstBasicBlock()) |bb| bb.deleteBasicBlock();
4890 }
4891
4892 var self = WipFunction{
4902 var self: WipFunction = .{
48934903 .builder = builder,
48944904 .function = function,
4895 .llvm = if (builder.useLibLlvm()) .{
4896 .builder = builder.llvm.context.createBuilder(),
4897 .blocks = .{},
4898 .instructions = .{},
4899 } else undefined,
4905 .last_debug_location = .none,
4906 .current_debug_location = .none,
49004907 .cursor = undefined,
49014908 .blocks = .{},
49024909 .instructions = .{},
49034910 .names = .{},
4904 .metadata = .{},
4911 .debug_locations = .{},
4912 .debug_values = .{},
49054913 .extra = .{},
49064914 };
49074915 errdefer self.deinit();
......@@ -4909,15 +4917,14 @@ pub const WipFunction = struct {
49094917 const params_len = function.typeOf(self.builder).functionParameters(self.builder).len;
49104918 try self.ensureUnusedExtraCapacity(params_len, NoExtra, 0);
49114919 try self.instructions.ensureUnusedCapacity(self.builder.gpa, params_len);
4912 if (!self.builder.strip) try self.names.ensureUnusedCapacity(self.builder.gpa, params_len);
4913 if (self.builder.useLibLlvm())
4914 try self.llvm.instructions.ensureUnusedCapacity(self.builder.gpa, params_len);
4920 if (!self.builder.strip) {
4921 try self.names.ensureUnusedCapacity(self.builder.gpa, params_len);
4922 }
49154923 for (0..params_len) |param_index| {
49164924 self.instructions.appendAssumeCapacity(.{ .tag = .arg, .data = @intCast(param_index) });
4917 if (!self.builder.strip) self.names.appendAssumeCapacity(.empty); // TODO: param names
4918 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
4919 function.toLlvm(self.builder).getParam(@intCast(param_index)),
4920 );
4925 if (!self.builder.strip) {
4926 self.names.appendAssumeCapacity(.empty); // TODO: param names
4927 }
49214928 }
49224929
49234930 return self;
......@@ -4934,7 +4941,6 @@ pub const WipFunction = struct {
49344941
49354942 pub fn block(self: *WipFunction, incoming: u32, name: []const u8) Allocator.Error!Block.Index {
49364943 try self.blocks.ensureUnusedCapacity(self.builder.gpa, 1);
4937 if (self.builder.useLibLlvm()) try self.llvm.blocks.ensureUnusedCapacity(self.builder.gpa, 1);
49384944
49394945 const index: Block.Index = @enumFromInt(self.blocks.items.len);
49404946 const final_name = if (self.builder.strip) .empty else try self.builder.string(name);
......@@ -4943,41 +4949,24 @@ pub const WipFunction = struct {
49434949 .incoming = incoming,
49444950 .instructions = .{},
49454951 });
4946 if (self.builder.useLibLlvm()) self.llvm.blocks.appendAssumeCapacity(
4947 self.builder.llvm.context.appendBasicBlock(
4948 self.function.toLlvm(self.builder),
4949 final_name.slice(self.builder).?,
4950 ),
4951 );
49524952 return index;
49534953 }
49544954
49554955 pub fn ret(self: *WipFunction, val: Value) Allocator.Error!Instruction.Index {
49564956 assert(val.typeOfWip(self) == self.function.typeOf(self.builder).functionReturn(self.builder));
49574957 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);
4958 const instruction = try self.addInst(null, .{ .tag = .ret, .data = @intFromEnum(val) });
4959 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
4960 self.llvm.builder.buildRet(val.toLlvm(self)),
4961 );
4962 return instruction;
4958 return try self.addInst(null, .{ .tag = .ret, .data = @intFromEnum(val) });
49634959 }
49644960
49654961 pub fn retVoid(self: *WipFunction) Allocator.Error!Instruction.Index {
49664962 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);
4967 const instruction = try self.addInst(null, .{ .tag = .@"ret void", .data = undefined });
4968 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
4969 self.llvm.builder.buildRetVoid(),
4970 );
4971 return instruction;
4963 return try self.addInst(null, .{ .tag = .@"ret void", .data = undefined });
49724964 }
49734965
49744966 pub fn br(self: *WipFunction, dest: Block.Index) Allocator.Error!Instruction.Index {
49754967 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);
49764968 const instruction = try self.addInst(null, .{ .tag = .br, .data = @intFromEnum(dest) });
49774969 dest.ptr(self).branches += 1;
4978 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
4979 self.llvm.builder.buildBr(dest.toLlvm(self)),
4980 );
49814970 return instruction;
49824971 }
49834972
......@@ -4999,9 +4988,6 @@ pub const WipFunction = struct {
49994988 });
50004989 then.ptr(self).branches += 1;
50014990 @"else".ptr(self).branches += 1;
5002 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5003 self.llvm.builder.buildCondBr(cond.toLlvm(self), then.toLlvm(self), @"else".toLlvm(self)),
5004 );
50054991 return instruction;
50064992 }
50074993
......@@ -5022,8 +5008,6 @@ pub const WipFunction = struct {
50225008 extra.trail.nextMut(extra.data.cases_len, Block.Index, wip)[self.index] = dest;
50235009 self.index += 1;
50245010 dest.ptr(wip).branches += 1;
5025 if (wip.builder.useLibLlvm())
5026 self.instruction.toLlvm(wip).addCase(val.toLlvm(wip.builder), dest.toLlvm(wip));
50275011 }
50285012
50295013 pub fn finish(self: WipSwitch, wip: *WipFunction) void {
......@@ -5050,18 +5034,12 @@ pub const WipFunction = struct {
50505034 });
50515035 _ = self.extra.addManyAsSliceAssumeCapacity(cases_len * 2);
50525036 default.ptr(self).branches += 1;
5053 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5054 self.llvm.builder.buildSwitch(val.toLlvm(self), default.toLlvm(self), @intCast(cases_len)),
5055 );
50565037 return .{ .index = 0, .instruction = instruction };
50575038 }
50585039
50595040 pub fn @"unreachable"(self: *WipFunction) Allocator.Error!Instruction.Index {
50605041 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);
50615042 const instruction = try self.addInst(null, .{ .tag = .@"unreachable", .data = undefined });
5062 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5063 self.llvm.builder.buildUnreachable(),
5064 );
50655043 return instruction;
50665044 }
50675045
......@@ -5079,17 +5057,6 @@ pub const WipFunction = struct {
50795057 }
50805058 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);
50815059 const instruction = try self.addInst(name, .{ .tag = tag, .data = @intFromEnum(val) });
5082 if (self.builder.useLibLlvm()) {
5083 switch (tag) {
5084 .fneg => self.llvm.builder.setFastMath(false),
5085 .@"fneg fast" => self.llvm.builder.setFastMath(true),
5086 else => unreachable,
5087 }
5088 self.llvm.instructions.appendAssumeCapacity(switch (tag) {
5089 .fneg, .@"fneg fast" => &llvm.Builder.buildFNeg,
5090 else => unreachable,
5091 }(self.llvm.builder, val.toLlvm(self), instruction.llvmName(self)));
5092 }
50935060 return instruction.toValue();
50945061 }
50955062
......@@ -5157,56 +5124,6 @@ pub const WipFunction = struct {
51575124 .tag = tag,
51585125 .data = self.addExtraAssumeCapacity(Instruction.Binary{ .lhs = lhs, .rhs = rhs }),
51595126 });
5160 if (self.builder.useLibLlvm()) {
5161 switch (tag) {
5162 .fadd,
5163 .fdiv,
5164 .fmul,
5165 .frem,
5166 .fsub,
5167 => self.llvm.builder.setFastMath(false),
5168 .@"fadd fast",
5169 .@"fdiv fast",
5170 .@"fmul fast",
5171 .@"frem fast",
5172 .@"fsub fast",
5173 => self.llvm.builder.setFastMath(true),
5174 else => {},
5175 }
5176 self.llvm.instructions.appendAssumeCapacity(switch (tag) {
5177 .add => &llvm.Builder.buildAdd,
5178 .@"add nsw" => &llvm.Builder.buildNSWAdd,
5179 .@"add nuw" => &llvm.Builder.buildNUWAdd,
5180 .@"and" => &llvm.Builder.buildAnd,
5181 .ashr => &llvm.Builder.buildAShr,
5182 .@"ashr exact" => &llvm.Builder.buildAShrExact,
5183 .fadd, .@"fadd fast" => &llvm.Builder.buildFAdd,
5184 .fdiv, .@"fdiv fast" => &llvm.Builder.buildFDiv,
5185 .fmul, .@"fmul fast" => &llvm.Builder.buildFMul,
5186 .frem, .@"frem fast" => &llvm.Builder.buildFRem,
5187 .fsub, .@"fsub fast" => &llvm.Builder.buildFSub,
5188 .lshr => &llvm.Builder.buildLShr,
5189 .@"lshr exact" => &llvm.Builder.buildLShrExact,
5190 .mul => &llvm.Builder.buildMul,
5191 .@"mul nsw" => &llvm.Builder.buildNSWMul,
5192 .@"mul nuw" => &llvm.Builder.buildNUWMul,
5193 .@"or" => &llvm.Builder.buildOr,
5194 .sdiv => &llvm.Builder.buildSDiv,
5195 .@"sdiv exact" => &llvm.Builder.buildExactSDiv,
5196 .shl => &llvm.Builder.buildShl,
5197 .@"shl nsw" => &llvm.Builder.buildNSWShl,
5198 .@"shl nuw" => &llvm.Builder.buildNUWShl,
5199 .srem => &llvm.Builder.buildSRem,
5200 .sub => &llvm.Builder.buildSub,
5201 .@"sub nsw" => &llvm.Builder.buildNSWSub,
5202 .@"sub nuw" => &llvm.Builder.buildNUWSub,
5203 .udiv => &llvm.Builder.buildUDiv,
5204 .@"udiv exact" => &llvm.Builder.buildExactUDiv,
5205 .urem => &llvm.Builder.buildURem,
5206 .xor => &llvm.Builder.buildXor,
5207 else => unreachable,
5208 }(self.llvm.builder, lhs.toLlvm(self), rhs.toLlvm(self), instruction.llvmName(self)));
5209 }
52105127 return instruction.toValue();
52115128 }
52125129
......@@ -5226,13 +5143,6 @@ pub const WipFunction = struct {
52265143 .index = index,
52275144 }),
52285145 });
5229 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5230 self.llvm.builder.buildExtractElement(
5231 val.toLlvm(self),
5232 index.toLlvm(self),
5233 instruction.llvmName(self),
5234 ),
5235 );
52365146 return instruction.toValue();
52375147 }
52385148
......@@ -5254,14 +5164,6 @@ pub const WipFunction = struct {
52545164 .index = index,
52555165 }),
52565166 });
5257 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5258 self.llvm.builder.buildInsertElement(
5259 val.toLlvm(self),
5260 elem.toLlvm(self),
5261 index.toLlvm(self),
5262 instruction.llvmName(self),
5263 ),
5264 );
52655167 return instruction.toValue();
52665168 }
52675169
......@@ -5284,14 +5186,6 @@ pub const WipFunction = struct {
52845186 .mask = mask,
52855187 }),
52865188 });
5287 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5288 self.llvm.builder.buildShuffleVector(
5289 lhs.toLlvm(self),
5290 rhs.toLlvm(self),
5291 mask.toLlvm(self),
5292 instruction.llvmName(self),
5293 ),
5294 );
52955189 return instruction.toValue();
52965190 }
52975191
......@@ -5303,10 +5197,9 @@ pub const WipFunction = struct {
53035197 ) Allocator.Error!Value {
53045198 const scalar_ty = try ty.changeLength(1, self.builder);
53055199 const mask_ty = try ty.changeScalar(.i32, self.builder);
5306 const zero = try self.builder.intConst(.i32, 0);
53075200 const poison = try self.builder.poisonValue(scalar_ty);
5308 const mask = try self.builder.splatValue(mask_ty, zero);
5309 const scalar = try self.insertElement(poison, elem, zero.toValue(), name);
5201 const mask = try self.builder.splatValue(mask_ty, .@"0");
5202 const scalar = try self.insertElement(poison, elem, .@"0", name);
53105203 return self.shuffleVector(scalar, poison, mask, name);
53115204 }
53125205
......@@ -5327,13 +5220,6 @@ pub const WipFunction = struct {
53275220 }),
53285221 });
53295222 self.extra.appendSliceAssumeCapacity(indices);
5330 if (self.builder.useLibLlvm()) {
5331 const llvm_name = instruction.llvmName(self);
5332 var cur = val.toLlvm(self);
5333 for (indices) |index|
5334 cur = self.llvm.builder.buildExtractValue(cur, @intCast(index), llvm_name);
5335 self.llvm.instructions.appendAssumeCapacity(cur);
5336 }
53375223 return instruction.toValue();
53385224 }
53395225
......@@ -5356,35 +5242,6 @@ pub const WipFunction = struct {
53565242 }),
53575243 });
53585244 self.extra.appendSliceAssumeCapacity(indices);
5359 if (self.builder.useLibLlvm()) {
5360 const ExpectedContents = [expected_gep_indices_len]*llvm.Value;
5361 var stack align(@alignOf(ExpectedContents)) =
5362 std.heap.stackFallback(@sizeOf(ExpectedContents), self.builder.gpa);
5363 const allocator = stack.get();
5364
5365 const llvm_name = instruction.llvmName(self);
5366 const llvm_vals = try allocator.alloc(*llvm.Value, indices.len);
5367 defer allocator.free(llvm_vals);
5368 llvm_vals[0] = val.toLlvm(self);
5369 for (llvm_vals[1..], llvm_vals[0 .. llvm_vals.len - 1], indices[0 .. indices.len - 1]) |
5370 *cur_val,
5371 prev_val,
5372 index,
5373 | cur_val.* = self.llvm.builder.buildExtractValue(prev_val, @intCast(index), llvm_name);
5374
5375 var depth: usize = llvm_vals.len;
5376 var cur = elem.toLlvm(self);
5377 while (depth > 0) {
5378 depth -= 1;
5379 cur = self.llvm.builder.buildInsertValue(
5380 llvm_vals[depth],
5381 cur,
5382 @intCast(indices[depth]),
5383 llvm_name,
5384 );
5385 }
5386 self.llvm.instructions.appendAssumeCapacity(cur);
5387 }
53885245 return instruction.toValue();
53895246 }
53905247
......@@ -5420,19 +5277,13 @@ pub const WipFunction = struct {
54205277 },
54215278 .data = self.addExtraAssumeCapacity(Instruction.Alloca{
54225279 .type = ty,
5423 .len = len,
5280 .len = switch (len) {
5281 .none => .@"1",
5282 else => len,
5283 },
54245284 .info = .{ .alignment = alignment, .addr_space = addr_space },
54255285 }),
54265286 });
5427 if (self.builder.useLibLlvm()) {
5428 const llvm_instruction = self.llvm.builder.buildAllocaInAddressSpace(
5429 ty.toLlvm(self.builder),
5430 @intFromEnum(addr_space),
5431 instruction.llvmName(self),
5432 );
5433 if (alignment.toByteUnits()) |bytes| llvm_instruction.setAlignment(@intCast(bytes));
5434 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);
5435 }
54365287 return instruction.toValue();
54375288 }
54385289
......@@ -5478,17 +5329,6 @@ pub const WipFunction = struct {
54785329 .ptr = ptr,
54795330 }),
54805331 });
5481 if (self.builder.useLibLlvm()) {
5482 const llvm_instruction = self.llvm.builder.buildLoad(
5483 ty.toLlvm(self.builder),
5484 ptr.toLlvm(self),
5485 instruction.llvmName(self),
5486 );
5487 if (access_kind == .@"volatile") llvm_instruction.setVolatile(.True);
5488 if (ordering != .none) llvm_instruction.setOrdering(ordering.toLlvm());
5489 if (alignment.toByteUnits()) |bytes| llvm_instruction.setAlignment(@intCast(bytes));
5490 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);
5491 }
54925332 return instruction.toValue();
54935333 }
54945334
......@@ -5532,13 +5372,6 @@ pub const WipFunction = struct {
55325372 .ptr = ptr,
55335373 }),
55345374 });
5535 if (self.builder.useLibLlvm()) {
5536 const llvm_instruction = self.llvm.builder.buildStore(val.toLlvm(self), ptr.toLlvm(self));
5537 if (access_kind == .@"volatile") llvm_instruction.setVolatile(.True);
5538 if (ordering != .none) llvm_instruction.setOrdering(ordering.toLlvm());
5539 if (alignment.toByteUnits()) |bytes| llvm_instruction.setAlignment(@intCast(bytes));
5540 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);
5541 }
55425375 return instruction;
55435376 }
55445377
......@@ -5556,13 +5389,6 @@ pub const WipFunction = struct {
55565389 .success_ordering = ordering,
55575390 }),
55585391 });
5559 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5560 self.llvm.builder.buildFence(
5561 ordering.toLlvm(),
5562 llvm.Bool.fromBool(sync_scope == .singlethread),
5563 "",
5564 ),
5565 );
55665392 return instruction;
55675393 }
55685394
......@@ -5605,25 +5431,6 @@ pub const WipFunction = struct {
56055431 .new = new,
56065432 }),
56075433 });
5608 if (self.builder.useLibLlvm()) {
5609 const llvm_instruction = self.llvm.builder.buildAtomicCmpXchg(
5610 ptr.toLlvm(self),
5611 cmp.toLlvm(self),
5612 new.toLlvm(self),
5613 success_ordering.toLlvm(),
5614 failure_ordering.toLlvm(),
5615 llvm.Bool.fromBool(sync_scope == .singlethread),
5616 );
5617 if (kind == .weak) llvm_instruction.setWeak(.True);
5618 if (access_kind == .@"volatile") llvm_instruction.setVolatile(.True);
5619 if (alignment.toByteUnits()) |bytes| llvm_instruction.setAlignment(@intCast(bytes));
5620 const llvm_name = instruction.llvmName(self);
5621 if (llvm_name.len > 0) llvm_instruction.setValueName(
5622 llvm_name.ptr,
5623 @intCast(llvm_name.len),
5624 );
5625 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);
5626 }
56275434 return instruction.toValue();
56285435 }
56295436
......@@ -5656,23 +5463,6 @@ pub const WipFunction = struct {
56565463 .val = val,
56575464 }),
56585465 });
5659 if (self.builder.useLibLlvm()) {
5660 const llvm_instruction = self.llvm.builder.buildAtomicRmw(
5661 operation.toLlvm(),
5662 ptr.toLlvm(self),
5663 val.toLlvm(self),
5664 ordering.toLlvm(),
5665 llvm.Bool.fromBool(sync_scope == .singlethread),
5666 );
5667 if (access_kind == .@"volatile") llvm_instruction.setVolatile(.True);
5668 if (alignment.toByteUnits()) |bytes| llvm_instruction.setAlignment(@intCast(bytes));
5669 const llvm_name = instruction.llvmName(self);
5670 if (llvm_name.len > 0) llvm_instruction.setValueName(
5671 llvm_name.ptr,
5672 @intCast(llvm_name.len),
5673 );
5674 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);
5675 }
56765466 return instruction.toValue();
56775467 }
56785468
......@@ -5732,28 +5522,6 @@ pub const WipFunction = struct {
57325522 }),
57335523 });
57345524 self.extra.appendSliceAssumeCapacity(@ptrCast(indices));
5735 if (self.builder.useLibLlvm()) {
5736 const ExpectedContents = [expected_gep_indices_len]*llvm.Value;
5737 var stack align(@alignOf(ExpectedContents)) =
5738 std.heap.stackFallback(@sizeOf(ExpectedContents), self.builder.gpa);
5739 const allocator = stack.get();
5740
5741 const llvm_indices = try allocator.alloc(*llvm.Value, indices.len);
5742 defer allocator.free(llvm_indices);
5743 for (llvm_indices, indices) |*llvm_index, index| llvm_index.* = index.toLlvm(self);
5744
5745 self.llvm.instructions.appendAssumeCapacity(switch (kind) {
5746 .normal => &llvm.Builder.buildGEP,
5747 .inbounds => &llvm.Builder.buildInBoundsGEP,
5748 }(
5749 self.llvm.builder,
5750 ty.toLlvm(self.builder),
5751 base.toLlvm(self),
5752 llvm_indices.ptr,
5753 @intCast(llvm_indices.len),
5754 instruction.llvmName(self),
5755 ));
5756 }
57575525 return instruction.toValue();
57585526 }
57595527
......@@ -5765,9 +5533,7 @@ pub const WipFunction = struct {
57655533 name: []const u8,
57665534 ) Allocator.Error!Value {
57675535 assert(ty.isStruct(self.builder));
5768 return self.gep(.inbounds, ty, base, &.{
5769 try self.builder.intValue(.i32, 0), try self.builder.intValue(.i32, index),
5770 }, name);
5536 return self.gep(.inbounds, ty, base, &.{ .@"0", try self.builder.intValue(.i32, index) }, name);
57715537 }
57725538
57735539 pub fn conv(
......@@ -5815,22 +5581,6 @@ pub const WipFunction = struct {
58155581 .type = ty,
58165582 }),
58175583 });
5818 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(switch (tag) {
5819 .addrspacecast => &llvm.Builder.buildAddrSpaceCast,
5820 .bitcast => &llvm.Builder.buildBitCast,
5821 .fpext => &llvm.Builder.buildFPExt,
5822 .fptosi => &llvm.Builder.buildFPToSI,
5823 .fptoui => &llvm.Builder.buildFPToUI,
5824 .fptrunc => &llvm.Builder.buildFPTrunc,
5825 .inttoptr => &llvm.Builder.buildIntToPtr,
5826 .ptrtoint => &llvm.Builder.buildPtrToInt,
5827 .sext => &llvm.Builder.buildSExt,
5828 .sitofp => &llvm.Builder.buildSIToFP,
5829 .trunc => &llvm.Builder.buildTrunc,
5830 .uitofp => &llvm.Builder.buildUIToFP,
5831 .zext => &llvm.Builder.buildZExt,
5832 else => unreachable,
5833 }(self.llvm.builder, val.toLlvm(self), ty.toLlvm(self.builder), instruction.llvmName(self)));
58345584 return instruction.toValue();
58355585 }
58365586
......@@ -5843,7 +5593,7 @@ pub const WipFunction = struct {
58435593 ) Allocator.Error!Value {
58445594 return self.cmpTag(switch (cond) {
58455595 inline else => |tag| @field(Instruction.Tag, "icmp " ++ @tagName(tag)),
5846 }, @intFromEnum(cond), lhs, rhs, name);
5596 }, lhs, rhs, name);
58475597 }
58485598
58495599 pub fn fcmp(
......@@ -5861,7 +5611,7 @@ pub const WipFunction = struct {
58615611 .fast => "fast ",
58625612 } ++ @tagName(cond_tag)),
58635613 },
5864 }, @intFromEnum(cond), lhs, rhs, name);
5614 }, lhs, rhs, name);
58655615 }
58665616
58675617 pub const WipPhi = struct {
......@@ -5877,7 +5627,7 @@ pub const WipFunction = struct {
58775627 vals: []const Value,
58785628 blocks: []const Block.Index,
58795629 wip: *WipFunction,
5880 ) (if (build_options.have_llvm) Allocator.Error else error{})!void {
5630 ) void {
58815631 const incoming_len = self.block.ptrConst(wip).incoming;
58825632 assert(vals.len == incoming_len and blocks.len == incoming_len);
58835633 const instruction = wip.instructions.get(@intFromEnum(self.instruction));
......@@ -5885,26 +5635,6 @@ pub const WipFunction = struct {
58855635 for (vals) |val| assert(val.typeOfWip(wip) == extra.data.type);
58865636 @memcpy(extra.trail.nextMut(incoming_len, Value, wip), vals);
58875637 @memcpy(extra.trail.nextMut(incoming_len, Block.Index, wip), blocks);
5888 if (wip.builder.useLibLlvm()) {
5889 const ExpectedContents = extern struct {
5890 values: [expected_incoming_len]*llvm.Value,
5891 blocks: [expected_incoming_len]*llvm.BasicBlock,
5892 };
5893 var stack align(@alignOf(ExpectedContents)) =
5894 std.heap.stackFallback(@sizeOf(ExpectedContents), wip.builder.gpa);
5895 const allocator = stack.get();
5896
5897 const llvm_vals = try allocator.alloc(*llvm.Value, incoming_len);
5898 defer allocator.free(llvm_vals);
5899 const llvm_blocks = try allocator.alloc(*llvm.BasicBlock, incoming_len);
5900 defer allocator.free(llvm_blocks);
5901
5902 for (llvm_vals, vals) |*llvm_val, incoming_val| llvm_val.* = incoming_val.toLlvm(wip);
5903 for (llvm_blocks, blocks) |*llvm_block, incoming_block|
5904 llvm_block.* = incoming_block.toLlvm(wip);
5905 self.instruction.toLlvm(wip)
5906 .addIncoming(llvm_vals.ptr, llvm_blocks.ptr, @intCast(incoming_len));
5907 }
59085638 }
59095639 };
59105640
......@@ -5970,53 +5700,6 @@ pub const WipFunction = struct {
59705700 }),
59715701 });
59725702 self.extra.appendSliceAssumeCapacity(@ptrCast(args));
5973 if (self.builder.useLibLlvm()) {
5974 const ExpectedContents = [expected_args_len]*llvm.Value;
5975 var stack align(@alignOf(ExpectedContents)) =
5976 std.heap.stackFallback(@sizeOf(ExpectedContents), self.builder.gpa);
5977 const allocator = stack.get();
5978
5979 const llvm_args = try allocator.alloc(*llvm.Value, args.len);
5980 defer allocator.free(llvm_args);
5981 for (llvm_args, args) |*llvm_arg, arg_val| llvm_arg.* = arg_val.toLlvm(self);
5982
5983 switch (kind) {
5984 .normal,
5985 .musttail,
5986 .notail,
5987 .tail,
5988 => self.llvm.builder.setFastMath(false),
5989 .fast,
5990 .musttail_fast,
5991 .notail_fast,
5992 .tail_fast,
5993 => self.llvm.builder.setFastMath(true),
5994 }
5995 const llvm_instruction = self.llvm.builder.buildCall(
5996 ty.toLlvm(self.builder),
5997 callee.toLlvm(self),
5998 llvm_args.ptr,
5999 @intCast(llvm_args.len),
6000 switch (ret_ty) {
6001 .void => "",
6002 else => instruction.llvmName(self),
6003 },
6004 );
6005 llvm_instruction.setInstructionCallConv(call_conv.toLlvm());
6006 llvm_instruction.setTailCallKind(switch (kind) {
6007 .normal, .fast => .None,
6008 .musttail, .musttail_fast => .MustTail,
6009 .notail, .notail_fast => .NoTail,
6010 .tail, .tail_fast => .Tail,
6011 });
6012 for (0.., function_attributes.slice(self.builder)) |index, attributes| {
6013 for (attributes.slice(self.builder)) |attribute| llvm_instruction.addCallSiteAttribute(
6014 @as(llvm.AttributeIndex, @intCast(index)) -% 1,
6015 attribute.toLlvm(self.builder),
6016 );
6017 }
6018 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);
6019 }
60205703 return instruction.toValue();
60215704 }
60225705
......@@ -6117,16 +5800,25 @@ pub const WipFunction = struct {
61175800 .type = ty,
61185801 }),
61195802 });
6120 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
6121 self.llvm.builder.buildVAArg(
6122 list.toLlvm(self),
6123 ty.toLlvm(self.builder),
6124 instruction.llvmName(self),
6125 ),
6126 );
61275803 return instruction.toValue();
61285804 }
61295805
5806 pub fn debugValue(self: *WipFunction, value: Value) Allocator.Error!Metadata {
5807 if (self.builder.strip) return .none;
5808 return switch (value.unwrap()) {
5809 .instruction => |instr_index| blk: {
5810 const gop = try self.debug_values.getOrPut(self.builder.gpa, instr_index);
5811
5812 const metadata: Metadata = @enumFromInt(Metadata.first_local_metadata + gop.index);
5813 if (!gop.found_existing) gop.key_ptr.* = instr_index;
5814
5815 break :blk metadata;
5816 },
5817 .constant => |constant| try self.builder.debugConstant(constant),
5818 .metadata => |metadata| metadata,
5819 };
5820 }
5821
61305822 pub fn finish(self: *WipFunction) Allocator.Error!void {
61315823 const gpa = self.builder.gpa;
61325824 const function = self.function.ptr(self.builder);
......@@ -6146,6 +5838,7 @@ pub const WipFunction = struct {
61465838 @intFromEnum(instruction)
61475839 ].toValue(),
61485840 .constant => |constant| constant.toValue(),
5841 .metadata => |metadata| metadata.toValue(),
61495842 };
61505843 }
61515844 } = .{ .items = try gpa.alloc(Instruction.Index, self.instructions.len) };
......@@ -6154,9 +5847,15 @@ pub const WipFunction = struct {
61545847 const names = try gpa.alloc(String, final_instructions_len);
61555848 errdefer gpa.free(names);
61565849
6157 const metadata =
6158 if (self.builder.strip) null else try gpa.alloc(Metadata, final_instructions_len);
6159 errdefer if (metadata) |new_metadata| gpa.free(new_metadata);
5850 const value_indices = try gpa.alloc(u32, final_instructions_len);
5851 errdefer gpa.free(value_indices);
5852
5853 var debug_locations: std.AutoHashMapUnmanaged(Instruction.Index, Metadata) = .{};
5854 errdefer debug_locations.deinit(gpa);
5855 try debug_locations.ensureUnusedCapacity(gpa, @intCast(self.debug_locations.count()));
5856
5857 const debug_values = try gpa.alloc(Instruction.Index, self.debug_values.count());
5858 errdefer gpa.free(debug_values);
61605859
61615860 var wip_extra: struct {
61625861 index: Instruction.ExtraIndex = 0,
......@@ -6179,7 +5878,7 @@ pub const WipFunction = struct {
61795878 Instruction.Alloca.Info,
61805879 Instruction.Call.Info,
61815880 => @bitCast(value),
6182 else => @compileError("bad field type: " ++ @typeName(field.type)),
5881 else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),
61835882 };
61845883 wip_extra.index += 1;
61855884 }
......@@ -6210,8 +5909,10 @@ pub const WipFunction = struct {
62105909 gpa.free(function.blocks);
62115910 function.blocks = &.{};
62125911 gpa.free(function.names[0..function.instructions.len]);
6213 if (function.metadata) |old_metadata| gpa.free(old_metadata[0..function.instructions.len]);
6214 function.metadata = null;
5912 function.debug_locations.deinit(gpa);
5913 function.debug_locations = .{};
5914 gpa.free(function.debug_values);
5915 function.debug_values = &.{};
62155916 gpa.free(function.extra);
62165917 function.extra = &.{};
62175918
......@@ -6238,33 +5939,76 @@ pub const WipFunction = struct {
62385939
62395940 var wip_name: struct {
62405941 next_name: String = @enumFromInt(0),
5942 next_unique_name: std.AutoHashMap(String, String),
5943 builder: *Builder,
62415944
6242 fn map(wip_name: *@This(), old_name: String) String {
6243 if (old_name != .empty) return old_name;
5945 fn map(wip_name: *@This(), name: String, sep: []const u8) Allocator.Error!String {
5946 switch (name) {
5947 .none => return .none,
5948 .empty => {
5949 assert(wip_name.next_name != .none);
5950 defer wip_name.next_name = @enumFromInt(@intFromEnum(wip_name.next_name) + 1);
5951 return wip_name.next_name;
5952 },
5953 _ => {
5954 assert(!name.isAnon());
5955 const gop = try wip_name.next_unique_name.getOrPut(name);
5956 if (!gop.found_existing) {
5957 gop.value_ptr.* = @enumFromInt(0);
5958 return name;
5959 }
62445960
6245 const new_name = wip_name.next_name;
6246 wip_name.next_name = @enumFromInt(@intFromEnum(new_name) + 1);
6247 return new_name;
5961 while (true) {
5962 gop.value_ptr.* = @enumFromInt(@intFromEnum(gop.value_ptr.*) + 1);
5963 const unique_name = try wip_name.builder.fmt("{r}{s}{r}", .{
5964 name.fmt(wip_name.builder),
5965 sep,
5966 gop.value_ptr.fmt(wip_name.builder),
5967 });
5968 const unique_gop = try wip_name.next_unique_name.getOrPut(unique_name);
5969 if (!unique_gop.found_existing) {
5970 unique_gop.value_ptr.* = @enumFromInt(0);
5971 return unique_name;
5972 }
5973 }
5974 },
5975 }
62485976 }
6249 } = .{};
5977 } = .{
5978 .next_unique_name = std.AutoHashMap(String, String).init(gpa),
5979 .builder = self.builder,
5980 };
5981 defer wip_name.next_unique_name.deinit();
5982
5983 var value_index: u32 = 0;
62505984 for (0..params_len) |param_index| {
62515985 const old_argument_index: Instruction.Index = @enumFromInt(param_index);
62525986 const new_argument_index: Instruction.Index = @enumFromInt(function.instructions.len);
62535987 const argument = self.instructions.get(@intFromEnum(old_argument_index));
62545988 assert(argument.tag == .arg);
62555989 assert(argument.data == param_index);
5990 value_indices[function.instructions.len] = value_index;
5991 value_index += 1;
62565992 function.instructions.appendAssumeCapacity(argument);
6257 names[@intFromEnum(new_argument_index)] = wip_name.map(
5993 names[@intFromEnum(new_argument_index)] = try wip_name.map(
62585994 if (self.builder.strip) .empty else self.names.items[@intFromEnum(old_argument_index)],
5995 ".",
62595996 );
5997 if (self.debug_locations.get(old_argument_index)) |location| {
5998 debug_locations.putAssumeCapacity(new_argument_index, location);
5999 }
6000 if (self.debug_values.getIndex(old_argument_index)) |index| {
6001 debug_values[index] = new_argument_index;
6002 }
62606003 }
62616004 for (self.blocks.items) |current_block| {
62626005 const new_block_index: Instruction.Index = @enumFromInt(function.instructions.len);
6006 value_indices[function.instructions.len] = value_index;
62636007 function.instructions.appendAssumeCapacity(.{
62646008 .tag = .block,
62656009 .data = current_block.incoming,
62666010 });
6267 names[@intFromEnum(new_block_index)] = wip_name.map(current_block.name);
6011 names[@intFromEnum(new_block_index)] = try wip_name.map(current_block.name, "");
62686012 for (current_block.instructions.items) |old_instruction_index| {
62696013 const new_instruction_index: Instruction.Index =
62706014 @enumFromInt(function.instructions.len);
......@@ -6565,10 +6309,21 @@ pub const WipFunction = struct {
65656309 },
65666310 }
65676311 function.instructions.appendAssumeCapacity(instruction);
6568 names[@intFromEnum(new_instruction_index)] = wip_name.map(if (self.builder.strip)
6312 names[@intFromEnum(new_instruction_index)] = try wip_name.map(if (self.builder.strip)
65696313 if (old_instruction_index.hasResultWip(self)) .empty else .none
65706314 else
6571 self.names.items[@intFromEnum(old_instruction_index)]);
6315 self.names.items[@intFromEnum(old_instruction_index)], ".");
6316
6317 if (self.debug_locations.get(old_instruction_index)) |location| {
6318 debug_locations.putAssumeCapacity(new_instruction_index, location);
6319 }
6320
6321 if (self.debug_values.getIndex(old_instruction_index)) |index| {
6322 debug_values[index] = new_instruction_index;
6323 }
6324
6325 value_indices[@intFromEnum(new_instruction_index)] = value_index;
6326 if (old_instruction_index.hasResultWip(self)) value_index += 1;
65726327 }
65736328 }
65746329
......@@ -6576,28 +6331,25 @@ pub const WipFunction = struct {
65766331 function.extra = wip_extra.finish();
65776332 function.blocks = blocks;
65786333 function.names = names.ptr;
6579 function.metadata = if (metadata) |new_metadata| new_metadata.ptr else null;
6334 function.value_indices = value_indices.ptr;
6335 function.debug_locations = debug_locations;
6336 function.debug_values = debug_values;
65806337 }
65816338
65826339 pub fn deinit(self: *WipFunction) void {
65836340 self.extra.deinit(self.builder.gpa);
6584 self.metadata.deinit(self.builder.gpa);
6341 self.debug_values.deinit(self.builder.gpa);
6342 self.debug_locations.deinit(self.builder.gpa);
65856343 self.names.deinit(self.builder.gpa);
65866344 self.instructions.deinit(self.builder.gpa);
65876345 for (self.blocks.items) |*b| b.instructions.deinit(self.builder.gpa);
65886346 self.blocks.deinit(self.builder.gpa);
6589 if (self.builder.useLibLlvm()) {
6590 self.llvm.instructions.deinit(self.builder.gpa);
6591 self.llvm.blocks.deinit(self.builder.gpa);
6592 self.llvm.builder.dispose();
6593 }
65946347 self.* = undefined;
65956348 }
65966349
65976350 fn cmpTag(
65986351 self: *WipFunction,
65996352 tag: Instruction.Tag,
6600 cond: u32,
66016353 lhs: Value,
66026354 rhs: Value,
66036355 name: []const u8,
......@@ -6657,113 +6409,6 @@ pub const WipFunction = struct {
66576409 .rhs = rhs,
66586410 }),
66596411 });
6660 if (self.builder.useLibLlvm()) {
6661 switch (tag) {
6662 .@"fcmp false",
6663 .@"fcmp oeq",
6664 .@"fcmp oge",
6665 .@"fcmp ogt",
6666 .@"fcmp ole",
6667 .@"fcmp olt",
6668 .@"fcmp one",
6669 .@"fcmp ord",
6670 .@"fcmp true",
6671 .@"fcmp ueq",
6672 .@"fcmp uge",
6673 .@"fcmp ugt",
6674 .@"fcmp ule",
6675 .@"fcmp ult",
6676 .@"fcmp une",
6677 .@"fcmp uno",
6678 => self.llvm.builder.setFastMath(false),
6679 .@"fcmp fast false",
6680 .@"fcmp fast oeq",
6681 .@"fcmp fast oge",
6682 .@"fcmp fast ogt",
6683 .@"fcmp fast ole",
6684 .@"fcmp fast olt",
6685 .@"fcmp fast one",
6686 .@"fcmp fast ord",
6687 .@"fcmp fast true",
6688 .@"fcmp fast ueq",
6689 .@"fcmp fast uge",
6690 .@"fcmp fast ugt",
6691 .@"fcmp fast ule",
6692 .@"fcmp fast ult",
6693 .@"fcmp fast une",
6694 .@"fcmp fast uno",
6695 => self.llvm.builder.setFastMath(true),
6696 .@"icmp eq",
6697 .@"icmp ne",
6698 .@"icmp sge",
6699 .@"icmp sgt",
6700 .@"icmp sle",
6701 .@"icmp slt",
6702 .@"icmp uge",
6703 .@"icmp ugt",
6704 .@"icmp ule",
6705 .@"icmp ult",
6706 => {},
6707 else => unreachable,
6708 }
6709 self.llvm.instructions.appendAssumeCapacity(switch (tag) {
6710 .@"fcmp false",
6711 .@"fcmp fast false",
6712 .@"fcmp fast oeq",
6713 .@"fcmp fast oge",
6714 .@"fcmp fast ogt",
6715 .@"fcmp fast ole",
6716 .@"fcmp fast olt",
6717 .@"fcmp fast one",
6718 .@"fcmp fast ord",
6719 .@"fcmp fast true",
6720 .@"fcmp fast ueq",
6721 .@"fcmp fast uge",
6722 .@"fcmp fast ugt",
6723 .@"fcmp fast ule",
6724 .@"fcmp fast ult",
6725 .@"fcmp fast une",
6726 .@"fcmp fast uno",
6727 .@"fcmp oeq",
6728 .@"fcmp oge",
6729 .@"fcmp ogt",
6730 .@"fcmp ole",
6731 .@"fcmp olt",
6732 .@"fcmp one",
6733 .@"fcmp ord",
6734 .@"fcmp true",
6735 .@"fcmp ueq",
6736 .@"fcmp uge",
6737 .@"fcmp ugt",
6738 .@"fcmp ule",
6739 .@"fcmp ult",
6740 .@"fcmp une",
6741 .@"fcmp uno",
6742 => self.llvm.builder.buildFCmp(
6743 @enumFromInt(cond),
6744 lhs.toLlvm(self),
6745 rhs.toLlvm(self),
6746 instruction.llvmName(self),
6747 ),
6748 .@"icmp eq",
6749 .@"icmp ne",
6750 .@"icmp sge",
6751 .@"icmp sgt",
6752 .@"icmp sle",
6753 .@"icmp slt",
6754 .@"icmp uge",
6755 .@"icmp ugt",
6756 .@"icmp ule",
6757 .@"icmp ult",
6758 => self.llvm.builder.buildICmp(
6759 @enumFromInt(cond),
6760 lhs.toLlvm(self),
6761 rhs.toLlvm(self),
6762 instruction.llvmName(self),
6763 ),
6764 else => unreachable,
6765 });
6766 }
67676412 return instruction.toValue();
67686413 }
67696414
......@@ -6785,16 +6430,6 @@ pub const WipFunction = struct {
67856430 .data = self.addExtraAssumeCapacity(Instruction.Phi{ .type = ty }),
67866431 });
67876432 _ = self.extra.addManyAsSliceAssumeCapacity(incoming * 2);
6788 if (self.builder.useLibLlvm()) {
6789 switch (tag) {
6790 .phi => self.llvm.builder.setFastMath(false),
6791 .@"phi fast" => self.llvm.builder.setFastMath(true),
6792 else => unreachable,
6793 }
6794 self.llvm.instructions.appendAssumeCapacity(
6795 self.llvm.builder.buildPhi(ty.toLlvm(self.builder), instruction.llvmName(self)),
6796 );
6797 }
67986433 return .{ .block = self.cursor.block, .instruction = instruction };
67996434 }
68006435
......@@ -6822,19 +6457,6 @@ pub const WipFunction = struct {
68226457 .rhs = rhs,
68236458 }),
68246459 });
6825 if (self.builder.useLibLlvm()) {
6826 switch (tag) {
6827 .select => self.llvm.builder.setFastMath(false),
6828 .@"select fast" => self.llvm.builder.setFastMath(true),
6829 else => unreachable,
6830 }
6831 self.llvm.instructions.appendAssumeCapacity(self.llvm.builder.buildSelect(
6832 cond.toLlvm(self),
6833 lhs.toLlvm(self),
6834 rhs.toLlvm(self),
6835 instruction.llvmName(self),
6836 ));
6837 }
68386460 return instruction.toValue();
68396461 }
68406462
......@@ -6857,28 +6479,27 @@ pub const WipFunction = struct {
68576479 ) Allocator.Error!Instruction.Index {
68586480 const block_instructions = &self.cursor.block.ptr(self).instructions;
68596481 try self.instructions.ensureUnusedCapacity(self.builder.gpa, 1);
6860 if (!self.builder.strip) try self.names.ensureUnusedCapacity(self.builder.gpa, 1);
6482 if (!self.builder.strip) {
6483 try self.names.ensureUnusedCapacity(self.builder.gpa, 1);
6484 try self.debug_locations.ensureUnusedCapacity(self.builder.gpa, 1);
6485 }
68616486 try block_instructions.ensureUnusedCapacity(self.builder.gpa, 1);
6862 if (self.builder.useLibLlvm())
6863 try self.llvm.instructions.ensureUnusedCapacity(self.builder.gpa, 1);
68646487 const final_name = if (name) |n|
68656488 if (self.builder.strip) .empty else try self.builder.string(n)
68666489 else
68676490 .none;
68686491
6869 if (self.builder.useLibLlvm()) self.llvm.builder.positionBuilder(
6870 self.cursor.block.toLlvm(self),
6871 for (block_instructions.items[self.cursor.instruction..]) |instruction_index| {
6872 const llvm_instruction =
6873 self.llvm.instructions.items[@intFromEnum(instruction_index)];
6874 // TODO: remove when constant propagation is implemented
6875 if (!llvm_instruction.isConstant().toBool()) break llvm_instruction;
6876 } else null,
6877 );
6878
68796492 const index: Instruction.Index = @enumFromInt(self.instructions.len);
68806493 self.instructions.appendAssumeCapacity(instruction);
6881 if (!self.builder.strip) self.names.appendAssumeCapacity(final_name);
6494 if (!self.builder.strip) {
6495 self.names.appendAssumeCapacity(final_name);
6496 if (block_instructions.items.len == 0 or
6497 self.current_debug_location != self.last_debug_location)
6498 {
6499 self.debug_locations.putAssumeCapacity(index, self.current_debug_location);
6500 self.last_debug_location = self.current_debug_location;
6501 }
6502 }
68826503 block_instructions.insertAssumeCapacity(self.cursor.instruction, index);
68836504 self.cursor.instruction += 1;
68846505 return index;
......@@ -6901,7 +6522,7 @@ pub const WipFunction = struct {
69016522 Instruction.Alloca.Info,
69026523 Instruction.Call.Info,
69036524 => @bitCast(value),
6904 else => @compileError("bad field type: " ++ @typeName(field.type)),
6525 else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),
69056526 });
69066527 }
69076528 return result;
......@@ -6949,7 +6570,7 @@ pub const WipFunction = struct {
69496570 Instruction.Alloca.Info,
69506571 Instruction.Call.Info,
69516572 => @bitCast(value),
6952 else => @compileError("bad field type: " ++ @typeName(field.type)),
6573 else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),
69536574 };
69546575 return .{
69556576 .data = result,
......@@ -6977,24 +6598,6 @@ pub const FloatCondition = enum(u4) {
69776598 ult = 12,
69786599 ule = 13,
69796600 une = 14,
6980
6981 fn toLlvm(self: FloatCondition) llvm.RealPredicate {
6982 return switch (self) {
6983 .oeq => .OEQ,
6984 .ogt => .OGT,
6985 .oge => .OGE,
6986 .olt => .OLT,
6987 .ole => .OLE,
6988 .one => .ONE,
6989 .ord => .ORD,
6990 .uno => .UNO,
6991 .ueq => .UEQ,
6992 .ugt => .UGT,
6993 .uge => .UGE,
6994 .ult => .ULT,
6995 .uno => .UNE,
6996 };
6997 }
69986601};
69996602
70006603pub const IntegerCondition = enum(u6) {
......@@ -7008,20 +6611,6 @@ pub const IntegerCondition = enum(u6) {
70086611 sge = 39,
70096612 slt = 40,
70106613 sle = 41,
7011
7012 fn toLlvm(self: IntegerCondition) llvm.IntPredicate {
7013 return switch (self) {
7014 .eq => .EQ,
7015 .ne => .NE,
7016 .ugt => .UGT,
7017 .uge => .UGE,
7018 .ult => .ULT,
7019 .sgt => .SGT,
7020 .sge => .SGE,
7021 .slt => .SLT,
7022 .sle => .SLE,
7023 };
7024 }
70256614};
70266615
70276616pub const MemoryAccessKind = enum(u1) {
......@@ -7058,10 +6647,10 @@ pub const AtomicOrdering = enum(u3) {
70586647 none = 0,
70596648 unordered = 1,
70606649 monotonic = 2,
7061 acquire = 4,
7062 release = 5,
7063 acq_rel = 6,
7064 seq_cst = 7,
6650 acquire = 3,
6651 release = 4,
6652 acq_rel = 5,
6653 seq_cst = 6,
70656654
70666655 pub fn format(
70676656 self: AtomicOrdering,
......@@ -7071,18 +6660,6 @@ pub const AtomicOrdering = enum(u3) {
70716660 ) @TypeOf(writer).Error!void {
70726661 if (self != .none) try writer.print("{s}{s}", .{ prefix, @tagName(self) });
70736662 }
7074
7075 fn toLlvm(self: AtomicOrdering) llvm.AtomicOrdering {
7076 return switch (self) {
7077 .none => .NotAtomic,
7078 .unordered => .Unordered,
7079 .monotonic => .Monotonic,
7080 .acquire => .Acquire,
7081 .release => .Release,
7082 .acq_rel => .AcquireRelease,
7083 .seq_cst => .SequentiallyConsistent,
7084 };
7085 }
70866663};
70876664
70886665const MemoryAccessInfo = packed struct(u32) {
......@@ -7095,7 +6672,8 @@ const MemoryAccessInfo = packed struct(u32) {
70956672 _: u13 = undefined,
70966673};
70976674
7098pub const FastMath = packed struct(u32) {
6675pub const FastMath = packed struct(u8) {
6676 unsafe_algebra: bool = false, // Legacy
70996677 nnan: bool = false,
71006678 ninf: bool = false,
71016679 nsz: bool = false,
......@@ -7130,11 +6708,13 @@ pub const FastMathKind = enum {
71306708pub const Constant = enum(u32) {
71316709 false,
71326710 true,
6711 @"0",
6712 @"1",
71336713 none,
7134 no_init = 1 << 31,
6714 no_init = (1 << 30) - 1,
71356715 _,
71366716
7137 const first_global: Constant = @enumFromInt(1 << 30);
6717 const first_global: Constant = @enumFromInt(1 << 29);
71386718
71396719 pub const Tag = enum(u7) {
71406720 positive_integer,
......@@ -7152,7 +6732,6 @@ pub const Constant = enum(u32) {
71526732 packed_structure,
71536733 array,
71546734 string,
7155 string_null,
71566735 vector,
71576736 splat,
71586737 zeroinitializer,
......@@ -7212,6 +6791,49 @@ pub const Constant = enum(u32) {
72126791 @"asm sideeffect inteldialect unwind",
72136792 @"asm alignstack inteldialect unwind",
72146793 @"asm sideeffect alignstack inteldialect unwind",
6794
6795 pub fn toBinaryOpcode(self: Tag) BinaryOpcode {
6796 return switch (self) {
6797 .add,
6798 .@"add nsw",
6799 .@"add nuw",
6800 => .add,
6801 .sub,
6802 .@"sub nsw",
6803 .@"sub nuw",
6804 => .sub,
6805 .mul,
6806 .@"mul nsw",
6807 .@"mul nuw",
6808 => .mul,
6809 .shl => .shl,
6810 .lshr => .lshr,
6811 .ashr => .ashr,
6812 .@"and" => .@"and",
6813 .@"or" => .@"or",
6814 .xor => .xor,
6815 else => unreachable,
6816 };
6817 }
6818
6819 pub fn toCastOpcode(self: Tag) CastOpcode {
6820 return switch (self) {
6821 .trunc => .trunc,
6822 .zext => .zext,
6823 .sext => .sext,
6824 .fptoui => .fptoui,
6825 .fptosi => .fptosi,
6826 .uitofp => .uitofp,
6827 .sitofp => .sitofp,
6828 .fptrunc => .fptrunc,
6829 .fpext => .fpext,
6830 .ptrtoint => .ptrtoint,
6831 .inttoptr => .inttoptr,
6832 .bitcast => .bitcast,
6833 .addrspacecast => .addrspacecast,
6834 else => unreachable,
6835 };
6836 }
72156837 };
72166838
72176839 pub const Item = struct {
......@@ -7364,11 +6986,8 @@ pub const Constant = enum(u32) {
73646986 .vector,
73656987 => builder.constantExtraData(Aggregate, item.data).type,
73666988 .splat => builder.constantExtraData(Splat, item.data).type,
7367 .string,
7368 .string_null,
7369 => builder.arrayTypeAssumeCapacity(
7370 @as(String, @enumFromInt(item.data)).slice(builder).?.len +
7371 @intFromBool(item.tag == .string_null),
6989 .string => builder.arrayTypeAssumeCapacity(
6990 @as(String, @enumFromInt(item.data)).slice(builder).?.len,
73726991 .i8,
73736992 ),
73746993 .blockaddress => builder.ptrTypeAssumeCapacity(
......@@ -7574,7 +7193,7 @@ pub const Constant = enum(u32) {
75747193 @ptrCast(data.builder.constant_limbs.items[item.data..][0..Integer.limbs]);
75757194 const limbs = data.builder.constant_limbs
75767195 .items[item.data + Integer.limbs ..][0..extra.limbs_len];
7577 const bigint = std.math.big.int.Const{
7196 const bigint: std.math.big.int.Const = .{
75787197 .limbs = limbs,
75797198 .positive = tag == .positive_integer,
75807199 };
......@@ -7616,17 +7235,31 @@ pub const Constant = enum(u32) {
76167235 };
76177236 }
76187237 };
7238 const Mantissa64 = std.meta.FieldType(Float.Repr(f64), .mantissa);
76197239 const Exponent32 = std.meta.FieldType(Float.Repr(f32), .exponent);
76207240 const Exponent64 = std.meta.FieldType(Float.Repr(f64), .exponent);
7241
76217242 const repr: Float.Repr(f32) = @bitCast(item.data);
7243 const denormal_shift = switch (repr.exponent) {
7244 std.math.minInt(Exponent32) => @as(
7245 std.math.Log2Int(Mantissa64),
7246 @clz(repr.mantissa),
7247 ) + 1,
7248 else => 0,
7249 };
76227250 try writer.print("0x{X:0>16}", .{@as(u64, @bitCast(Float.Repr(f64){
76237251 .mantissa = std.math.shl(
7624 std.meta.FieldType(Float.Repr(f64), .mantissa),
7252 Mantissa64,
76257253 repr.mantissa,
7626 std.math.floatMantissaBits(f64) - std.math.floatMantissaBits(f32),
7254 std.math.floatMantissaBits(f64) - std.math.floatMantissaBits(f32) +
7255 denormal_shift,
76277256 ),
76287257 .exponent = switch (repr.exponent) {
7629 std.math.minInt(Exponent32) => std.math.minInt(Exponent64),
7258 std.math.minInt(Exponent32) => if (repr.mantissa > 0)
7259 @as(Exponent64, std.math.floatExponentMin(f32) +
7260 std.math.floatExponentMax(f64)) - denormal_shift
7261 else
7262 std.math.minInt(Exponent64),
76307263 else => @as(Exponent64, repr.exponent) +
76317264 (std.math.floatExponentMax(f64) - std.math.floatExponentMax(f32)),
76327265 std.math.maxInt(Exponent32) => std.math.maxInt(Exponent64),
......@@ -7703,13 +7336,9 @@ pub const Constant = enum(u32) {
77037336 }
77047337 try writer.writeByte('>');
77057338 },
7706 inline .string,
7707 .string_null,
7708 => |tag| try writer.print("c{\"" ++ switch (tag) {
7709 .string => "",
7710 .string_null => "@",
7711 else => unreachable,
7712 } ++ "}", .{@as(String, @enumFromInt(item.data)).fmt(data.builder)}),
7339 .string => try writer.print("c{\"}", .{
7340 @as(String, @enumFromInt(item.data)).fmt(data.builder),
7341 }),
77137342 .blockaddress => |tag| {
77147343 const extra = data.builder.constantExtraData(BlockAddress, item.data);
77157344 const function = extra.function.ptrConst(data.builder);
......@@ -7859,40 +7488,37 @@ pub const Constant = enum(u32) {
78597488 pub fn fmt(self: Constant, builder: *Builder) std.fmt.Formatter(format) {
78607489 return .{ .data = .{ .constant = self, .builder = builder } };
78617490 }
7862
7863 pub fn toLlvm(self: Constant, builder: *const Builder) *llvm.Value {
7864 assert(builder.useLibLlvm());
7865 const llvm_value = switch (self.unwrap()) {
7866 .constant => |constant| builder.llvm.constants.items[constant],
7867 .global => |global| return global.toLlvm(builder),
7868 };
7869 const global = builder.llvm.replacements.get(llvm_value) orelse return llvm_value;
7870 return global.toLlvm(builder);
7871 }
78727491};
78737492
78747493pub const Value = enum(u32) {
78757494 none = std.math.maxInt(u31),
78767495 false = first_constant + @intFromEnum(Constant.false),
78777496 true = first_constant + @intFromEnum(Constant.true),
7497 @"0" = first_constant + @intFromEnum(Constant.@"0"),
7498 @"1" = first_constant + @intFromEnum(Constant.@"1"),
78787499 _,
78797500
7880 const first_constant = 1 << 31;
7501 const first_constant = 1 << 30;
7502 const first_metadata = 1 << 31;
78817503
78827504 pub fn unwrap(self: Value) union(enum) {
78837505 instruction: Function.Instruction.Index,
78847506 constant: Constant,
7507 metadata: Metadata,
78857508 } {
78867509 return if (@intFromEnum(self) < first_constant)
78877510 .{ .instruction = @enumFromInt(@intFromEnum(self)) }
7511 else if (@intFromEnum(self) < first_metadata)
7512 .{ .constant = @enumFromInt(@intFromEnum(self) - first_constant) }
78887513 else
7889 .{ .constant = @enumFromInt(@intFromEnum(self) - first_constant) };
7514 .{ .metadata = @enumFromInt(@intFromEnum(self) - first_metadata) };
78907515 }
78917516
78927517 pub fn typeOfWip(self: Value, wip: *const WipFunction) Type {
78937518 return switch (self.unwrap()) {
78947519 .instruction => |instruction| instruction.typeOfWip(wip),
78957520 .constant => |constant| constant.typeOf(wip.builder),
7521 .metadata => .metadata,
78967522 };
78977523 }
78987524
......@@ -7900,12 +7526,13 @@ pub const Value = enum(u32) {
79007526 return switch (self.unwrap()) {
79017527 .instruction => |instruction| instruction.typeOf(function, builder),
79027528 .constant => |constant| constant.typeOf(builder),
7529 .metadata => .metadata,
79037530 };
79047531 }
79057532
79067533 pub fn toConst(self: Value) ?Constant {
79077534 return switch (self.unwrap()) {
7908 .instruction => null,
7535 .instruction, .metadata => null,
79097536 .constant => |constant| constant,
79107537 };
79117538 }
......@@ -7931,397 +7558,854 @@ pub const Value = enum(u32) {
79317558 .constant = constant,
79327559 .builder = data.builder,
79337560 }, fmt_str, fmt_opts, writer),
7561 .metadata => unreachable,
79347562 }
79357563 }
79367564 pub fn fmt(self: Value, function: Function.Index, builder: *Builder) std.fmt.Formatter(format) {
79377565 return .{ .data = .{ .value = self, .function = function, .builder = builder } };
79387566 }
7567};
79397568
7940 pub fn toLlvm(self: Value, wip: *const WipFunction) *llvm.Value {
7941 return switch (self.unwrap()) {
7942 .instruction => |instruction| instruction.toLlvm(wip),
7943 .constant => |constant| constant.toLlvm(wip.builder),
7944 };
7569pub const MetadataString = enum(u32) {
7570 none = 0,
7571 _,
7572
7573 pub fn slice(self: MetadataString, builder: *const Builder) []const u8 {
7574 const index = @intFromEnum(self);
7575 const start = builder.metadata_string_indices.items[index];
7576 const end = builder.metadata_string_indices.items[index + 1];
7577 return builder.metadata_string_bytes.items[start..end];
79457578 }
7946};
79477579
7948pub const Metadata = enum(u32) { _ };
7580 const Adapter = struct {
7581 builder: *const Builder,
7582 pub fn hash(_: Adapter, key: []const u8) u32 {
7583 return @truncate(std.hash.Wyhash.hash(0, key));
7584 }
7585 pub fn eql(ctx: Adapter, lhs_key: []const u8, _: void, rhs_index: usize) bool {
7586 const rhs_metadata_string: MetadataString = @enumFromInt(rhs_index);
7587 return std.mem.eql(u8, lhs_key, rhs_metadata_string.slice(ctx.builder));
7588 }
7589 };
79497590
7950pub const InitError = error{
7951 InvalidLlvmTriple,
7952} || Allocator.Error;
7591 const FormatData = struct {
7592 metadata_string: MetadataString,
7593 builder: *const Builder,
7594 };
7595 fn format(
7596 data: FormatData,
7597 comptime _: []const u8,
7598 _: std.fmt.FormatOptions,
7599 writer: anytype,
7600 ) @TypeOf(writer).Error!void {
7601 try printEscapedString(data.metadata_string.slice(data.builder), .always_quote, writer);
7602 }
7603 fn fmt(self: MetadataString, builder: *const Builder) std.fmt.Formatter(format) {
7604 return .{ .data = .{ .metadata_string = self, .builder = builder } };
7605 }
7606};
79537607
7954pub fn init(options: Options) InitError!Builder {
7955 var self = Builder{
7956 .gpa = options.allocator,
7957 .use_lib_llvm = options.use_lib_llvm,
7958 .strip = options.strip,
7608pub const Metadata = enum(u32) {
7609 none = 0,
7610 _,
79597611
7960 .llvm = undefined,
7612 const first_forward_reference = 1 << 29;
7613 const first_local_metadata = 1 << 30;
79617614
7962 .source_filename = .none,
7963 .data_layout = .none,
7964 .target_triple = .none,
7965 .module_asm = .{},
7615 pub const Tag = enum(u6) {
7616 none,
7617 file,
7618 compile_unit,
7619 @"compile_unit optimized",
7620 subprogram,
7621 @"subprogram local",
7622 @"subprogram definition",
7623 @"subprogram local definition",
7624 @"subprogram optimized",
7625 @"subprogram optimized local",
7626 @"subprogram optimized definition",
7627 @"subprogram optimized local definition",
7628 lexical_block,
7629 location,
7630 basic_bool_type,
7631 basic_unsigned_type,
7632 basic_signed_type,
7633 basic_float_type,
7634 composite_struct_type,
7635 composite_union_type,
7636 composite_enumeration_type,
7637 composite_array_type,
7638 composite_vector_type,
7639 derived_pointer_type,
7640 derived_member_type,
7641 subroutine_type,
7642 enumerator_unsigned,
7643 enumerator_signed_positive,
7644 enumerator_signed_negative,
7645 subrange,
7646 tuple,
7647 module_flag,
7648 expression,
7649 local_var,
7650 parameter,
7651 global_var,
7652 @"global_var local",
7653 global_var_expression,
7654 constant,
7655
7656 pub fn isInline(tag: Tag) bool {
7657 return switch (tag) {
7658 .none,
7659 .expression,
7660 .constant,
7661 => true,
7662 .file,
7663 .compile_unit,
7664 .@"compile_unit optimized",
7665 .subprogram,
7666 .@"subprogram local",
7667 .@"subprogram definition",
7668 .@"subprogram local definition",
7669 .@"subprogram optimized",
7670 .@"subprogram optimized local",
7671 .@"subprogram optimized definition",
7672 .@"subprogram optimized local definition",
7673 .lexical_block,
7674 .location,
7675 .basic_bool_type,
7676 .basic_unsigned_type,
7677 .basic_signed_type,
7678 .basic_float_type,
7679 .composite_struct_type,
7680 .composite_union_type,
7681 .composite_enumeration_type,
7682 .composite_array_type,
7683 .composite_vector_type,
7684 .derived_pointer_type,
7685 .derived_member_type,
7686 .subroutine_type,
7687 .enumerator_unsigned,
7688 .enumerator_signed_positive,
7689 .enumerator_signed_negative,
7690 .subrange,
7691 .tuple,
7692 .module_flag,
7693 .local_var,
7694 .parameter,
7695 .global_var,
7696 .@"global_var local",
7697 .global_var_expression,
7698 => false,
7699 };
7700 }
7701 };
79667702
7967 .string_map = .{},
7968 .string_indices = .{},
7969 .string_bytes = .{},
7703 pub fn isInline(self: Metadata, builder: *const Builder) bool {
7704 return builder.metadata_items.items(.tag)[@intFromEnum(self)].isInline();
7705 }
79707706
7971 .types = .{},
7972 .next_unnamed_type = @enumFromInt(0),
7973 .next_unique_type_id = .{},
7974 .type_map = .{},
7975 .type_items = .{},
7976 .type_extra = .{},
7707 pub fn unwrap(self: Metadata, builder: *const Builder) Metadata {
7708 var metadata = self;
7709 while (@intFromEnum(metadata) >= Metadata.first_forward_reference and
7710 @intFromEnum(metadata) < Metadata.first_local_metadata)
7711 {
7712 const index = @intFromEnum(metadata) - Metadata.first_forward_reference;
7713 metadata = builder.metadata_forward_references.items[index];
7714 assert(metadata != .none);
7715 }
7716 return metadata;
7717 }
79777718
7978 .attributes = .{},
7979 .attributes_map = .{},
7980 .attributes_indices = .{},
7981 .attributes_extra = .{},
7719 pub const Item = struct {
7720 tag: Tag,
7721 data: ExtraIndex,
79827722
7983 .globals = .{},
7984 .next_unnamed_global = @enumFromInt(0),
7985 .next_replaced_global = .none,
7986 .next_unique_global_id = .{},
7987 .aliases = .{},
7988 .variables = .{},
7989 .functions = .{},
7723 const ExtraIndex = u32;
7724 };
79907725
7991 .constant_map = .{},
7992 .constant_items = .{},
7993 .constant_extra = .{},
7994 .constant_limbs = .{},
7726 pub const DIFlags = packed struct(u32) {
7727 Visibility: enum(u2) { Zero, Private, Protected, Public } = .Zero,
7728 FwdDecl: bool = false,
7729 AppleBlock: bool = false,
7730 ReservedBit4: u1 = 0,
7731 Virtual: bool = false,
7732 Artificial: bool = false,
7733 Explicit: bool = false,
7734 Prototyped: bool = false,
7735 ObjcClassComplete: bool = false,
7736 ObjectPointer: bool = false,
7737 Vector: bool = false,
7738 StaticMember: bool = false,
7739 LValueReference: bool = false,
7740 RValueReference: bool = false,
7741 ExportSymbols: bool = false,
7742 Inheritance: enum(u2) {
7743 Zero,
7744 SingleInheritance,
7745 MultipleInheritance,
7746 VirtualInheritance,
7747 } = .Zero,
7748 IntroducedVirtual: bool = false,
7749 BitField: bool = false,
7750 NoReturn: bool = false,
7751 ReservedBit21: u1 = 0,
7752 TypePassbyValue: bool = false,
7753 TypePassbyReference: bool = false,
7754 EnumClass: bool = false,
7755 Thunk: bool = false,
7756 NonTrivial: bool = false,
7757 BigEndian: bool = false,
7758 LittleEndian: bool = false,
7759 AllCallsDescribed: bool = false,
7760 Unused: u2 = 0,
7761
7762 pub fn format(
7763 self: DIFlags,
7764 comptime _: []const u8,
7765 _: std.fmt.FormatOptions,
7766 writer: anytype,
7767 ) @TypeOf(writer).Error!void {
7768 var need_pipe = false;
7769 inline for (@typeInfo(DIFlags).Struct.fields) |field| {
7770 switch (@typeInfo(field.type)) {
7771 .Bool => if (@field(self, field.name)) {
7772 if (need_pipe) try writer.writeAll(" | ") else need_pipe = true;
7773 try writer.print("DIFlag{s}", .{field.name});
7774 },
7775 .Enum => if (@field(self, field.name) != .Zero) {
7776 if (need_pipe) try writer.writeAll(" | ") else need_pipe = true;
7777 try writer.print("DIFlag{s}", .{@tagName(@field(self, field.name))});
7778 },
7779 .Int => assert(@field(self, field.name) == 0),
7780 else => @compileError("bad field type: " ++ field.name ++ ": " ++
7781 @typeName(field.type)),
7782 }
7783 }
7784 if (!need_pipe) try writer.writeByte('0');
7785 }
79957786 };
7996 if (self.useLibLlvm()) self.llvm = .{
7997 .context = llvm.Context.create(),
7998 .module = null,
7999 .target = null,
8000 .di_builder = null,
8001 .di_compile_unit = null,
8002 .attribute_kind_ids = null,
8003 .attributes = .{},
8004 .types = .{},
8005 .globals = .{},
8006 .constants = .{},
8007 .replacements = .{},
7787
7788 pub const File = struct {
7789 filename: MetadataString,
7790 directory: MetadataString,
80087791 };
8009 errdefer self.deinit();
80107792
8011 try self.string_indices.append(self.gpa, 0);
8012 assert(try self.string("") == .empty);
7793 pub const CompileUnit = struct {
7794 pub const Options = struct {
7795 optimized: bool,
7796 };
80137797
8014 if (options.name.len > 0) self.source_filename = try self.string(options.name);
8015 if (self.useLibLlvm()) {
8016 initializeLLVMTarget(options.target.cpu.arch);
8017 self.llvm.module = llvm.Module.createWithName(
8018 (self.source_filename.slice(&self) orelse ""),
8019 self.llvm.context,
8020 );
8021 }
7798 file: Metadata,
7799 producer: MetadataString,
7800 enums: Metadata,
7801 globals: Metadata,
7802 };
80227803
8023 if (options.triple.len > 0) {
8024 self.target_triple = try self.string(options.triple);
7804 pub const Subprogram = struct {
7805 pub const Options = struct {
7806 di_flags: DIFlags,
7807 sp_flags: DISPFlags,
7808 };
80257809
8026 if (self.useLibLlvm()) {
8027 var error_message: [*:0]const u8 = undefined;
8028 var target: *llvm.Target = undefined;
8029 if (llvm.Target.getFromTriple(
8030 self.target_triple.slice(&self).?,
8031 &target,
8032 &error_message,
8033 ).toBool()) {
8034 defer llvm.disposeMessage(error_message);
8035
8036 log.err("LLVM failed to parse '{s}': {s}", .{
8037 self.target_triple.slice(&self).?,
8038 error_message,
8039 });
8040 return InitError.InvalidLlvmTriple;
7810 pub const DISPFlags = packed struct(u32) {
7811 Virtuality: enum(u2) { Zero, Virtual, PureVirtual } = .Zero,
7812 LocalToUnit: bool = false,
7813 Definition: bool = false,
7814 Optimized: bool = false,
7815 Pure: bool = false,
7816 Elemental: bool = false,
7817 Recursive: bool = false,
7818 MainSubprogram: bool = false,
7819 Deleted: bool = false,
7820 ReservedBit10: u1 = 0,
7821 ObjCDirect: bool = false,
7822 Unused: u20 = 0,
7823
7824 pub fn format(
7825 self: DISPFlags,
7826 comptime _: []const u8,
7827 _: std.fmt.FormatOptions,
7828 writer: anytype,
7829 ) @TypeOf(writer).Error!void {
7830 var need_pipe = false;
7831 inline for (@typeInfo(DISPFlags).Struct.fields) |field| {
7832 switch (@typeInfo(field.type)) {
7833 .Bool => if (@field(self, field.name)) {
7834 if (need_pipe) try writer.writeAll(" | ") else need_pipe = true;
7835 try writer.print("DISPFlag{s}", .{field.name});
7836 },
7837 .Enum => if (@field(self, field.name) != .Zero) {
7838 if (need_pipe) try writer.writeAll(" | ") else need_pipe = true;
7839 try writer.print("DISPFlag{s}", .{@tagName(@field(self, field.name))});
7840 },
7841 .Int => assert(@field(self, field.name) == 0),
7842 else => @compileError("bad field type: " ++ field.name ++ ": " ++
7843 @typeName(field.type)),
7844 }
7845 }
7846 if (!need_pipe) try writer.writeByte('0');
80417847 }
8042 self.llvm.target = target;
8043 self.llvm.module.?.setTarget(self.target_triple.slice(&self).?);
7848 };
7849
7850 file: Metadata,
7851 name: MetadataString,
7852 linkage_name: MetadataString,
7853 line: u32,
7854 scope_line: u32,
7855 ty: Metadata,
7856 di_flags: DIFlags,
7857 compile_unit: Metadata,
7858 };
7859
7860 pub const LexicalBlock = struct {
7861 scope: Metadata,
7862 file: Metadata,
7863 line: u32,
7864 column: u32,
7865 };
7866
7867 pub const Location = struct {
7868 line: u32,
7869 column: u32,
7870 scope: Metadata,
7871 inlined_at: Metadata,
7872 };
7873
7874 pub const BasicType = struct {
7875 name: MetadataString,
7876 size_in_bits_lo: u32,
7877 size_in_bits_hi: u32,
7878
7879 pub fn bitSize(self: BasicType) u64 {
7880 return @as(u64, self.size_in_bits_hi) << 32 | self.size_in_bits_lo;
80447881 }
8045 }
7882 };
80467883
8047 {
8048 const static_len = @typeInfo(Type).Enum.fields.len - 1;
8049 try self.type_map.ensureTotalCapacity(self.gpa, static_len);
8050 try self.type_items.ensureTotalCapacity(self.gpa, static_len);
8051 if (self.useLibLlvm()) try self.llvm.types.ensureTotalCapacity(self.gpa, static_len);
8052 inline for (@typeInfo(Type.Simple).Enum.fields) |simple_field| {
8053 const result = self.getOrPutTypeNoExtraAssumeCapacity(
8054 .{ .tag = .simple, .data = simple_field.value },
8055 );
8056 assert(result.new and result.type == @field(Type, simple_field.name));
8057 if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
8058 @field(llvm.Context, simple_field.name ++ "Type")(self.llvm.context),
8059 );
7884 pub const CompositeType = struct {
7885 name: MetadataString,
7886 file: Metadata,
7887 scope: Metadata,
7888 line: u32,
7889 underlying_type: Metadata,
7890 size_in_bits_lo: u32,
7891 size_in_bits_hi: u32,
7892 align_in_bits_lo: u32,
7893 align_in_bits_hi: u32,
7894 fields_tuple: Metadata,
7895
7896 pub fn bitSize(self: CompositeType) u64 {
7897 return @as(u64, self.size_in_bits_hi) << 32 | self.size_in_bits_lo;
80607898 }
8061 inline for (.{ 1, 8, 16, 29, 32, 64, 80, 128 }) |bits|
8062 assert(self.intTypeAssumeCapacity(bits) ==
8063 @field(Type, std.fmt.comptimePrint("i{d}", .{bits})));
8064 inline for (.{ 0, 4 }) |addr_space_index| {
8065 const addr_space: AddrSpace = @enumFromInt(addr_space_index);
8066 assert(self.ptrTypeAssumeCapacity(addr_space) ==
8067 @field(Type, std.fmt.comptimePrint("ptr{ }", .{addr_space})));
7899 pub fn bitAlign(self: CompositeType) u64 {
7900 return @as(u64, self.align_in_bits_hi) << 32 | self.align_in_bits_lo;
80687901 }
8069 }
7902 };
80707903
8071 {
8072 if (self.useLibLlvm()) {
8073 self.llvm.attribute_kind_ids = try self.gpa.create([Attribute.Kind.len]c_uint);
8074 @memset(self.llvm.attribute_kind_ids.?, 0);
7904 pub const DerivedType = struct {
7905 name: MetadataString,
7906 file: Metadata,
7907 scope: Metadata,
7908 line: u32,
7909 underlying_type: Metadata,
7910 size_in_bits_lo: u32,
7911 size_in_bits_hi: u32,
7912 align_in_bits_lo: u32,
7913 align_in_bits_hi: u32,
7914 offset_in_bits_lo: u32,
7915 offset_in_bits_hi: u32,
7916
7917 pub fn bitSize(self: DerivedType) u64 {
7918 return @as(u64, self.size_in_bits_hi) << 32 | self.size_in_bits_lo;
80757919 }
8076 try self.attributes_indices.append(self.gpa, 0);
8077 assert(try self.attrs(&.{}) == .none);
8078 assert(try self.fnAttrs(&.{}) == .none);
8079 }
7920 pub fn bitAlign(self: DerivedType) u64 {
7921 return @as(u64, self.align_in_bits_hi) << 32 | self.align_in_bits_lo;
7922 }
7923 pub fn bitOffset(self: DerivedType) u64 {
7924 return @as(u64, self.offset_in_bits_hi) << 32 | self.offset_in_bits_lo;
7925 }
7926 };
80807927
8081 assert(try self.intConst(.i1, 0) == .false);
8082 assert(try self.intConst(.i1, 1) == .true);
8083 assert(try self.noneConst(.token) == .none);
7928 pub const SubroutineType = struct {
7929 types_tuple: Metadata,
7930 };
80847931
8085 return self;
8086}
7932 pub const Enumerator = struct {
7933 name: MetadataString,
7934 bit_width: u32,
7935 limbs_index: u32,
7936 limbs_len: u32,
7937 };
80877938
8088pub fn deinit(self: *Builder) void {
8089 if (self.useLibLlvm()) {
8090 var replacement_it = self.llvm.replacements.keyIterator();
8091 while (replacement_it.next()) |replacement| replacement.*.deleteGlobalValue();
8092 self.llvm.replacements.deinit(self.gpa);
8093 self.llvm.constants.deinit(self.gpa);
8094 self.llvm.globals.deinit(self.gpa);
8095 self.llvm.types.deinit(self.gpa);
8096 self.llvm.attributes.deinit(self.gpa);
8097 if (self.llvm.attribute_kind_ids) |attribute_kind_ids| self.gpa.destroy(attribute_kind_ids);
8098 if (self.llvm.di_builder) |di_builder| di_builder.dispose();
8099 if (self.llvm.module) |module| module.dispose();
8100 self.llvm.context.dispose();
8101 }
7939 pub const Subrange = struct {
7940 lower_bound: Metadata,
7941 count: Metadata,
7942 };
81027943
8103 self.module_asm.deinit(self.gpa);
7944 pub const Expression = struct {
7945 elements_len: u32,
81047946
8105 self.string_map.deinit(self.gpa);
8106 self.string_indices.deinit(self.gpa);
8107 self.string_bytes.deinit(self.gpa);
7947 // elements: [elements_len]u32
7948 };
81087949
8109 self.types.deinit(self.gpa);
8110 self.next_unique_type_id.deinit(self.gpa);
8111 self.type_map.deinit(self.gpa);
8112 self.type_items.deinit(self.gpa);
8113 self.type_extra.deinit(self.gpa);
7950 pub const Tuple = struct {
7951 elements_len: u32,
81147952
8115 self.attributes.deinit(self.gpa);
8116 self.attributes_map.deinit(self.gpa);
8117 self.attributes_indices.deinit(self.gpa);
8118 self.attributes_extra.deinit(self.gpa);
7953 // elements: [elements_len]Metadata
7954 };
81197955
8120 self.globals.deinit(self.gpa);
8121 self.next_unique_global_id.deinit(self.gpa);
8122 self.aliases.deinit(self.gpa);
8123 self.variables.deinit(self.gpa);
8124 for (self.functions.items) |*function| function.deinit(self.gpa);
8125 self.functions.deinit(self.gpa);
7956 pub const ModuleFlag = struct {
7957 behavior: Metadata,
7958 name: MetadataString,
7959 constant: Metadata,
7960 };
81267961
8127 self.constant_map.deinit(self.gpa);
8128 self.constant_items.deinit(self.gpa);
8129 self.constant_extra.deinit(self.gpa);
8130 self.constant_limbs.deinit(self.gpa);
7962 pub const LocalVar = struct {
7963 name: MetadataString,
7964 file: Metadata,
7965 scope: Metadata,
7966 line: u32,
7967 ty: Metadata,
7968 };
81317969
8132 self.* = undefined;
8133}
7970 pub const Parameter = struct {
7971 name: MetadataString,
7972 file: Metadata,
7973 scope: Metadata,
7974 line: u32,
7975 ty: Metadata,
7976 arg_no: u32,
7977 };
7978
7979 pub const GlobalVar = struct {
7980 pub const Options = struct {
7981 local: bool,
7982 };
7983
7984 name: MetadataString,
7985 linkage_name: MetadataString,
7986 file: Metadata,
7987 scope: Metadata,
7988 line: u32,
7989 ty: Metadata,
7990 variable: Variable.Index,
7991 };
7992
7993 pub const GlobalVarExpression = struct {
7994 variable: Metadata,
7995 expression: Metadata,
7996 };
7997
7998 pub fn toValue(self: Metadata) Value {
7999 return @enumFromInt(Value.first_metadata + @intFromEnum(self));
8000 }
8001
8002 const Formatter = struct {
8003 builder: *Builder,
8004 need_comma: bool,
8005 map: std.AutoArrayHashMapUnmanaged(Metadata, void) = .{},
8006
8007 const FormatData = struct {
8008 formatter: *Formatter,
8009 prefix: []const u8 = "",
8010 node: Node,
8011
8012 const Node = union(enum) {
8013 none,
8014 @"inline": Metadata,
8015 index: u32,
8016
8017 local_value: ValueData,
8018 local_metadata: ValueData,
8019 local_inline: Metadata,
8020 local_index: u32,
8021
8022 string: MetadataString,
8023 bool: bool,
8024 u32: u32,
8025 u64: u64,
8026 di_flags: DIFlags,
8027 sp_flags: Subprogram.DISPFlags,
8028 raw: []const u8,
8029
8030 const ValueData = struct {
8031 value: Value,
8032 function: Function.Index,
8033 };
8034 };
8035 };
8036 fn format(
8037 data: FormatData,
8038 comptime fmt_str: []const u8,
8039 fmt_opts: std.fmt.FormatOptions,
8040 writer: anytype,
8041 ) @TypeOf(writer).Error!void {
8042 if (data.node == .none) return;
8043
8044 const is_specialized = fmt_str.len > 0 and fmt_str[0] == 'S';
8045 const recurse_fmt_str = if (is_specialized) fmt_str[1..] else fmt_str;
8046
8047 if (data.formatter.need_comma) try writer.writeAll(", ");
8048 defer data.formatter.need_comma = true;
8049 try writer.writeAll(data.prefix);
81348050
8135pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
8136 switch (arch) {
8137 .aarch64, .aarch64_be, .aarch64_32 => {
8138 llvm.LLVMInitializeAArch64Target();
8139 llvm.LLVMInitializeAArch64TargetInfo();
8140 llvm.LLVMInitializeAArch64TargetMC();
8141 llvm.LLVMInitializeAArch64AsmPrinter();
8142 llvm.LLVMInitializeAArch64AsmParser();
8143 },
8144 .amdgcn => {
8145 llvm.LLVMInitializeAMDGPUTarget();
8146 llvm.LLVMInitializeAMDGPUTargetInfo();
8147 llvm.LLVMInitializeAMDGPUTargetMC();
8148 llvm.LLVMInitializeAMDGPUAsmPrinter();
8149 llvm.LLVMInitializeAMDGPUAsmParser();
8150 },
8151 .thumb, .thumbeb, .arm, .armeb => {
8152 llvm.LLVMInitializeARMTarget();
8153 llvm.LLVMInitializeARMTargetInfo();
8154 llvm.LLVMInitializeARMTargetMC();
8155 llvm.LLVMInitializeARMAsmPrinter();
8156 llvm.LLVMInitializeARMAsmParser();
8157 },
8158 .avr => {
8159 llvm.LLVMInitializeAVRTarget();
8160 llvm.LLVMInitializeAVRTargetInfo();
8161 llvm.LLVMInitializeAVRTargetMC();
8162 llvm.LLVMInitializeAVRAsmPrinter();
8163 llvm.LLVMInitializeAVRAsmParser();
8164 },
8165 .bpfel, .bpfeb => {
8166 llvm.LLVMInitializeBPFTarget();
8167 llvm.LLVMInitializeBPFTargetInfo();
8168 llvm.LLVMInitializeBPFTargetMC();
8169 llvm.LLVMInitializeBPFAsmPrinter();
8170 llvm.LLVMInitializeBPFAsmParser();
8171 },
8172 .hexagon => {
8173 llvm.LLVMInitializeHexagonTarget();
8174 llvm.LLVMInitializeHexagonTargetInfo();
8175 llvm.LLVMInitializeHexagonTargetMC();
8176 llvm.LLVMInitializeHexagonAsmPrinter();
8177 llvm.LLVMInitializeHexagonAsmParser();
8178 },
8179 .lanai => {
8180 llvm.LLVMInitializeLanaiTarget();
8181 llvm.LLVMInitializeLanaiTargetInfo();
8182 llvm.LLVMInitializeLanaiTargetMC();
8183 llvm.LLVMInitializeLanaiAsmPrinter();
8184 llvm.LLVMInitializeLanaiAsmParser();
8185 },
8186 .mips, .mipsel, .mips64, .mips64el => {
8187 llvm.LLVMInitializeMipsTarget();
8188 llvm.LLVMInitializeMipsTargetInfo();
8189 llvm.LLVMInitializeMipsTargetMC();
8190 llvm.LLVMInitializeMipsAsmPrinter();
8191 llvm.LLVMInitializeMipsAsmParser();
8192 },
8193 .msp430 => {
8194 llvm.LLVMInitializeMSP430Target();
8195 llvm.LLVMInitializeMSP430TargetInfo();
8196 llvm.LLVMInitializeMSP430TargetMC();
8197 llvm.LLVMInitializeMSP430AsmPrinter();
8198 llvm.LLVMInitializeMSP430AsmParser();
8199 },
8200 .nvptx, .nvptx64 => {
8201 llvm.LLVMInitializeNVPTXTarget();
8202 llvm.LLVMInitializeNVPTXTargetInfo();
8203 llvm.LLVMInitializeNVPTXTargetMC();
8204 llvm.LLVMInitializeNVPTXAsmPrinter();
8205 // There is no LLVMInitializeNVPTXAsmParser function available.
8206 },
8207 .powerpc, .powerpcle, .powerpc64, .powerpc64le => {
8208 llvm.LLVMInitializePowerPCTarget();
8209 llvm.LLVMInitializePowerPCTargetInfo();
8210 llvm.LLVMInitializePowerPCTargetMC();
8211 llvm.LLVMInitializePowerPCAsmPrinter();
8212 llvm.LLVMInitializePowerPCAsmParser();
8213 },
8214 .riscv32, .riscv64 => {
8215 llvm.LLVMInitializeRISCVTarget();
8216 llvm.LLVMInitializeRISCVTargetInfo();
8217 llvm.LLVMInitializeRISCVTargetMC();
8218 llvm.LLVMInitializeRISCVAsmPrinter();
8219 llvm.LLVMInitializeRISCVAsmParser();
8220 },
8221 .sparc, .sparc64, .sparcel => {
8222 llvm.LLVMInitializeSparcTarget();
8223 llvm.LLVMInitializeSparcTargetInfo();
8224 llvm.LLVMInitializeSparcTargetMC();
8225 llvm.LLVMInitializeSparcAsmPrinter();
8226 llvm.LLVMInitializeSparcAsmParser();
8227 },
8228 .s390x => {
8229 llvm.LLVMInitializeSystemZTarget();
8230 llvm.LLVMInitializeSystemZTargetInfo();
8231 llvm.LLVMInitializeSystemZTargetMC();
8232 llvm.LLVMInitializeSystemZAsmPrinter();
8233 llvm.LLVMInitializeSystemZAsmParser();
8234 },
8235 .wasm32, .wasm64 => {
8236 llvm.LLVMInitializeWebAssemblyTarget();
8237 llvm.LLVMInitializeWebAssemblyTargetInfo();
8238 llvm.LLVMInitializeWebAssemblyTargetMC();
8239 llvm.LLVMInitializeWebAssemblyAsmPrinter();
8240 llvm.LLVMInitializeWebAssemblyAsmParser();
8241 },
8242 .x86, .x86_64 => {
8243 llvm.LLVMInitializeX86Target();
8244 llvm.LLVMInitializeX86TargetInfo();
8245 llvm.LLVMInitializeX86TargetMC();
8246 llvm.LLVMInitializeX86AsmPrinter();
8247 llvm.LLVMInitializeX86AsmParser();
8248 },
8249 .xtensa => {
8250 if (build_options.llvm_has_xtensa) {
8251 llvm.LLVMInitializeXtensaTarget();
8252 llvm.LLVMInitializeXtensaTargetInfo();
8253 llvm.LLVMInitializeXtensaTargetMC();
8254 // There is no LLVMInitializeXtensaAsmPrinter function.
8255 llvm.LLVMInitializeXtensaAsmParser();
8051 const builder = data.formatter.builder;
8052 switch (data.node) {
8053 .none => unreachable,
8054 .@"inline" => |node| {
8055 const needed_comma = data.formatter.need_comma;
8056 defer data.formatter.need_comma = needed_comma;
8057 data.formatter.need_comma = false;
8058
8059 const item = builder.metadata_items.get(@intFromEnum(node));
8060 switch (item.tag) {
8061 .expression => {
8062 var extra = builder.metadataExtraDataTrail(Expression, item.data);
8063 const elements = extra.trail.next(extra.data.elements_len, u32, builder);
8064 try writer.writeAll("!DIExpression(");
8065 for (elements) |element| try format(.{
8066 .formatter = data.formatter,
8067 .node = .{ .u64 = element },
8068 }, "%", fmt_opts, writer);
8069 try writer.writeByte(')');
8070 },
8071 .constant => try Constant.format(.{
8072 .constant = @enumFromInt(item.data),
8073 .builder = builder,
8074 }, recurse_fmt_str, fmt_opts, writer),
8075 else => unreachable,
8076 }
8077 },
8078 .index => |node| try writer.print("!{d}", .{node}),
8079 inline .local_value, .local_metadata => |node, tag| try Value.format(.{
8080 .value = node.value,
8081 .function = node.function,
8082 .builder = builder,
8083 }, switch (tag) {
8084 .local_value => recurse_fmt_str,
8085 .local_metadata => "%",
8086 else => unreachable,
8087 }, fmt_opts, writer),
8088 inline .local_inline, .local_index => |node, tag| {
8089 if (comptime std.mem.eql(u8, recurse_fmt_str, "%"))
8090 try writer.print("{%} ", .{Type.metadata.fmt(builder)});
8091 try format(.{
8092 .formatter = data.formatter,
8093 .node = @unionInit(FormatData.Node, @tagName(tag)["local_".len..], node),
8094 }, "%", fmt_opts, writer);
8095 },
8096 .string => |node| try writer.print((if (is_specialized) "" else "!") ++ "{}", .{
8097 node.fmt(builder),
8098 }),
8099 inline .bool,
8100 .u32,
8101 .u64,
8102 .di_flags,
8103 .sp_flags,
8104 => |node| try writer.print("{}", .{node}),
8105 .raw => |node| try writer.writeAll(node),
82568106 }
8257 },
8258 .xcore => {
8259 llvm.LLVMInitializeXCoreTarget();
8260 llvm.LLVMInitializeXCoreTargetInfo();
8261 llvm.LLVMInitializeXCoreTargetMC();
8262 llvm.LLVMInitializeXCoreAsmPrinter();
8263 // There is no LLVMInitializeXCoreAsmParser function.
8264 },
8265 .m68k => {
8266 if (build_options.llvm_has_m68k) {
8267 llvm.LLVMInitializeM68kTarget();
8268 llvm.LLVMInitializeM68kTargetInfo();
8269 llvm.LLVMInitializeM68kTargetMC();
8270 llvm.LLVMInitializeM68kAsmPrinter();
8271 llvm.LLVMInitializeM68kAsmParser();
8107 }
8108 inline fn fmt(formatter: *Formatter, prefix: []const u8, node: anytype) switch (@TypeOf(node)) {
8109 Metadata => Allocator.Error,
8110 else => error{},
8111 }!std.fmt.Formatter(format) {
8112 const Node = @TypeOf(node);
8113 const MaybeNode = switch (@typeInfo(Node)) {
8114 .Optional => Node,
8115 .Null => ?noreturn,
8116 else => ?Node,
8117 };
8118 const Some = @typeInfo(MaybeNode).Optional.child;
8119 return .{ .data = .{
8120 .formatter = formatter,
8121 .prefix = prefix,
8122 .node = if (@as(MaybeNode, node)) |some| switch (@typeInfo(Some)) {
8123 .Enum => |enum_info| switch (Some) {
8124 Metadata => switch (some) {
8125 .none => .none,
8126 else => try formatter.refUnwrapped(some.unwrap(formatter.builder)),
8127 },
8128 MetadataString => .{ .string = some },
8129 else => if (enum_info.is_exhaustive)
8130 .{ .raw = @tagName(some) }
8131 else
8132 @compileError("unknown type to format: " ++ @typeName(Node)),
8133 },
8134 .EnumLiteral => .{ .raw = @tagName(some) },
8135 .Bool => .{ .bool = some },
8136 .Struct => switch (Some) {
8137 DIFlags => .{ .di_flags = some },
8138 Subprogram.DISPFlags => .{ .sp_flags = some },
8139 else => @compileError("unknown type to format: " ++ @typeName(Node)),
8140 },
8141 .Int, .ComptimeInt => .{ .u64 = some },
8142 .Pointer => .{ .raw = some },
8143 else => @compileError("unknown type to format: " ++ @typeName(Node)),
8144 } else switch (@typeInfo(Node)) {
8145 .Optional, .Null => .none,
8146 else => unreachable,
8147 },
8148 } };
8149 }
8150 inline fn fmtLocal(
8151 formatter: *Formatter,
8152 prefix: []const u8,
8153 value: Value,
8154 function: Function.Index,
8155 ) Allocator.Error!std.fmt.Formatter(format) {
8156 return .{ .data = .{
8157 .formatter = formatter,
8158 .prefix = prefix,
8159 .node = switch (value.unwrap()) {
8160 .instruction, .constant => .{ .local_value = .{
8161 .value = value,
8162 .function = function,
8163 } },
8164 .metadata => |metadata| if (value == .none) .none else node: {
8165 const unwrapped = metadata.unwrap(formatter.builder);
8166 break :node if (@intFromEnum(unwrapped) >= first_local_metadata)
8167 .{ .local_metadata = .{
8168 .value = function.ptrConst(formatter.builder).debug_values[
8169 @intFromEnum(unwrapped) - first_local_metadata
8170 ].toValue(),
8171 .function = function,
8172 } }
8173 else switch (try formatter.refUnwrapped(unwrapped)) {
8174 .@"inline" => |node| .{ .local_inline = node },
8175 .index => |node| .{ .local_index = node },
8176 else => unreachable,
8177 };
8178 },
8179 },
8180 } };
8181 }
8182 fn refUnwrapped(formatter: *Formatter, node: Metadata) Allocator.Error!FormatData.Node {
8183 assert(node != .none);
8184 assert(@intFromEnum(node) < first_forward_reference);
8185 const builder = formatter.builder;
8186 const unwrapped_metadata = node.unwrap(builder);
8187 const tag = formatter.builder.metadata_items.items(.tag)[@intFromEnum(unwrapped_metadata)];
8188 switch (tag) {
8189 .none => unreachable,
8190 .expression, .constant => return .{ .@"inline" = unwrapped_metadata },
8191 else => {
8192 assert(!tag.isInline());
8193 const gop = try formatter.map.getOrPutValue(builder.gpa, unwrapped_metadata, {});
8194 return .{ .index = @intCast(gop.index) };
8195 },
82728196 }
8273 },
8274 .csky => {
8275 if (build_options.llvm_has_csky) {
8276 llvm.LLVMInitializeCSKYTarget();
8277 llvm.LLVMInitializeCSKYTargetInfo();
8278 llvm.LLVMInitializeCSKYTargetMC();
8279 // There is no LLVMInitializeCSKYAsmPrinter function.
8280 llvm.LLVMInitializeCSKYAsmParser();
8197 }
8198
8199 inline fn specialized(
8200 formatter: *Formatter,
8201 distinct: enum { @"!", @"distinct !" },
8202 node: enum {
8203 DIFile,
8204 DICompileUnit,
8205 DISubprogram,
8206 DILexicalBlock,
8207 DILocation,
8208 DIBasicType,
8209 DICompositeType,
8210 DIDerivedType,
8211 DISubroutineType,
8212 DIEnumerator,
8213 DISubrange,
8214 DILocalVariable,
8215 DIGlobalVariable,
8216 DIGlobalVariableExpression,
8217 },
8218 nodes: anytype,
8219 writer: anytype,
8220 ) !void {
8221 comptime var fmt_str: []const u8 = "";
8222 const names = comptime std.meta.fieldNames(@TypeOf(nodes));
8223 comptime var fields: [2 + names.len]std.builtin.Type.StructField = undefined;
8224 inline for (fields[0..2], .{ "distinct", "node" }) |*field, name| {
8225 fmt_str = fmt_str ++ "{[" ++ name ++ "]s}";
8226 field.* = .{
8227 .name = name,
8228 .type = []const u8,
8229 .default_value = null,
8230 .is_comptime = false,
8231 .alignment = 0,
8232 };
82818233 }
8282 },
8283 .ve => {
8284 llvm.LLVMInitializeVETarget();
8285 llvm.LLVMInitializeVETargetInfo();
8286 llvm.LLVMInitializeVETargetMC();
8287 llvm.LLVMInitializeVEAsmPrinter();
8288 llvm.LLVMInitializeVEAsmParser();
8289 },
8290 .arc => {
8291 if (build_options.llvm_has_arc) {
8292 llvm.LLVMInitializeARCTarget();
8293 llvm.LLVMInitializeARCTargetInfo();
8294 llvm.LLVMInitializeARCTargetMC();
8295 llvm.LLVMInitializeARCAsmPrinter();
8296 // There is no LLVMInitializeARCAsmParser function.
8234 fmt_str = fmt_str ++ "(";
8235 inline for (fields[2..], names) |*field, name| {
8236 fmt_str = fmt_str ++ "{[" ++ name ++ "]S}";
8237 field.* = .{
8238 .name = name,
8239 .type = std.fmt.Formatter(format),
8240 .default_value = null,
8241 .is_comptime = false,
8242 .alignment = 0,
8243 };
82978244 }
8298 },
8245 fmt_str = fmt_str ++ ")\n";
8246
8247 var fmt_args: @Type(.{ .Struct = .{
8248 .layout = .Auto,
8249 .fields = &fields,
8250 .decls = &.{},
8251 .is_tuple = false,
8252 } }) = undefined;
8253 fmt_args.distinct = @tagName(distinct);
8254 fmt_args.node = @tagName(node);
8255 inline for (names) |name| @field(fmt_args, name) = try formatter.fmt(
8256 name ++ ": ",
8257 @field(nodes, name),
8258 );
8259 try writer.print(fmt_str, fmt_args);
8260 }
8261 };
8262};
82998263
8300 // LLVM backends that have no initialization functions.
8301 .tce,
8302 .tcele,
8303 .r600,
8304 .le32,
8305 .le64,
8306 .amdil,
8307 .amdil64,
8308 .hsail,
8309 .hsail64,
8310 .shave,
8311 .spir,
8312 .spir64,
8313 .kalimba,
8314 .renderscript32,
8315 .renderscript64,
8316 .dxil,
8317 .loongarch32,
8318 .loongarch64,
8319 => {},
8264pub fn init(options: Options) Allocator.Error!Builder {
8265 var self = Builder{
8266 .gpa = options.allocator,
8267 .strip = options.strip,
8268
8269 .source_filename = .none,
8270 .data_layout = .none,
8271 .target_triple = .none,
8272 .module_asm = .{},
8273
8274 .string_map = .{},
8275 .string_indices = .{},
8276 .string_bytes = .{},
8277
8278 .types = .{},
8279 .next_unnamed_type = @enumFromInt(0),
8280 .next_unique_type_id = .{},
8281 .type_map = .{},
8282 .type_items = .{},
8283 .type_extra = .{},
8284
8285 .attributes = .{},
8286 .attributes_map = .{},
8287 .attributes_indices = .{},
8288 .attributes_extra = .{},
8289
8290 .function_attributes_set = .{},
8291
8292 .globals = .{},
8293 .next_unnamed_global = @enumFromInt(0),
8294 .next_replaced_global = .none,
8295 .next_unique_global_id = .{},
8296 .aliases = .{},
8297 .variables = .{},
8298 .functions = .{},
8299
8300 .constant_map = .{},
8301 .constant_items = .{},
8302 .constant_extra = .{},
8303 .constant_limbs = .{},
8304
8305 .metadata_map = .{},
8306 .metadata_items = .{},
8307 .metadata_extra = .{},
8308 .metadata_limbs = .{},
8309 .metadata_forward_references = .{},
8310 .metadata_named = .{},
8311 .metadata_string_map = .{},
8312 .metadata_string_indices = .{},
8313 .metadata_string_bytes = .{},
8314 };
8315 errdefer self.deinit();
8316
8317 try self.string_indices.append(self.gpa, 0);
8318 assert(try self.string("") == .empty);
8319
8320 if (options.name.len > 0) self.source_filename = try self.string(options.name);
8321
8322 if (options.triple.len > 0) {
8323 self.target_triple = try self.string(options.triple);
8324 }
8325
8326 {
8327 const static_len = @typeInfo(Type).Enum.fields.len - 1;
8328 try self.type_map.ensureTotalCapacity(self.gpa, static_len);
8329 try self.type_items.ensureTotalCapacity(self.gpa, static_len);
8330 inline for (@typeInfo(Type.Simple).Enum.fields) |simple_field| {
8331 const result = self.getOrPutTypeNoExtraAssumeCapacity(
8332 .{ .tag = .simple, .data = simple_field.value },
8333 );
8334 assert(result.new and result.type == @field(Type, simple_field.name));
8335 }
8336 inline for (.{ 1, 8, 16, 29, 32, 64, 80, 128 }) |bits|
8337 assert(self.intTypeAssumeCapacity(bits) ==
8338 @field(Type, std.fmt.comptimePrint("i{d}", .{bits})));
8339 inline for (.{ 0, 4 }) |addr_space_index| {
8340 const addr_space: AddrSpace = @enumFromInt(addr_space_index);
8341 assert(self.ptrTypeAssumeCapacity(addr_space) ==
8342 @field(Type, std.fmt.comptimePrint("ptr{ }", .{addr_space})));
8343 }
8344 }
83208345
8321 .spu_2 => unreachable, // LLVM does not support this backend
8322 .spirv32 => unreachable, // LLVM does not support this backend
8323 .spirv64 => unreachable, // LLVM does not support this backend
8346 {
8347 try self.attributes_indices.append(self.gpa, 0);
8348 assert(try self.attrs(&.{}) == .none);
8349 assert(try self.fnAttrs(&.{}) == .none);
83248350 }
8351
8352 assert(try self.intConst(.i1, 0) == .false);
8353 assert(try self.intConst(.i1, 1) == .true);
8354 assert(try self.intConst(.i32, 0) == .@"0");
8355 assert(try self.intConst(.i32, 1) == .@"1");
8356 assert(try self.noneConst(.token) == .none);
8357 if (!self.strip) assert(try self.debugNone() == .none);
8358
8359 try self.metadata_string_indices.append(self.gpa, 0);
8360 assert(try self.metadataString("") == .none);
8361
8362 return self;
8363}
8364
8365pub fn deinit(self: *Builder) void {
8366 self.module_asm.deinit(self.gpa);
8367
8368 self.string_map.deinit(self.gpa);
8369 self.string_indices.deinit(self.gpa);
8370 self.string_bytes.deinit(self.gpa);
8371
8372 self.types.deinit(self.gpa);
8373 self.next_unique_type_id.deinit(self.gpa);
8374 self.type_map.deinit(self.gpa);
8375 self.type_items.deinit(self.gpa);
8376 self.type_extra.deinit(self.gpa);
8377
8378 self.attributes.deinit(self.gpa);
8379 self.attributes_map.deinit(self.gpa);
8380 self.attributes_indices.deinit(self.gpa);
8381 self.attributes_extra.deinit(self.gpa);
8382
8383 self.function_attributes_set.deinit(self.gpa);
8384
8385 self.globals.deinit(self.gpa);
8386 self.next_unique_global_id.deinit(self.gpa);
8387 self.aliases.deinit(self.gpa);
8388 self.variables.deinit(self.gpa);
8389 for (self.functions.items) |*function| function.deinit(self.gpa);
8390 self.functions.deinit(self.gpa);
8391
8392 self.constant_map.deinit(self.gpa);
8393 self.constant_items.deinit(self.gpa);
8394 self.constant_extra.deinit(self.gpa);
8395 self.constant_limbs.deinit(self.gpa);
8396
8397 self.metadata_map.deinit(self.gpa);
8398 self.metadata_items.deinit(self.gpa);
8399 self.metadata_extra.deinit(self.gpa);
8400 self.metadata_limbs.deinit(self.gpa);
8401 self.metadata_forward_references.deinit(self.gpa);
8402 self.metadata_named.deinit(self.gpa);
8403
8404 self.metadata_string_map.deinit(self.gpa);
8405 self.metadata_string_indices.deinit(self.gpa);
8406 self.metadata_string_bytes.deinit(self.gpa);
8407
8408 self.* = undefined;
83258409}
83268410
83278411pub fn setModuleAsm(self: *Builder) std.ArrayListUnmanaged(u8).Writer {
......@@ -8336,24 +8420,25 @@ pub fn appendModuleAsm(self: *Builder) std.ArrayListUnmanaged(u8).Writer {
83368420pub fn finishModuleAsm(self: *Builder) Allocator.Error!void {
83378421 if (self.module_asm.getLastOrNull()) |last| if (last != '\n')
83388422 try self.module_asm.append(self.gpa, '\n');
8339 if (self.useLibLlvm())
8340 self.llvm.module.?.setModuleInlineAsm(self.module_asm.items.ptr, self.module_asm.items.len);
83418423}
83428424
83438425pub fn string(self: *Builder, bytes: []const u8) Allocator.Error!String {
8344 try self.string_bytes.ensureUnusedCapacity(self.gpa, bytes.len + 1);
8426 try self.string_bytes.ensureUnusedCapacity(self.gpa, bytes.len);
83458427 try self.string_indices.ensureUnusedCapacity(self.gpa, 1);
83468428 try self.string_map.ensureUnusedCapacity(self.gpa, 1);
83478429
83488430 const gop = self.string_map.getOrPutAssumeCapacityAdapted(bytes, String.Adapter{ .builder = self });
83498431 if (!gop.found_existing) {
83508432 self.string_bytes.appendSliceAssumeCapacity(bytes);
8351 self.string_bytes.appendAssumeCapacity(0);
83528433 self.string_indices.appendAssumeCapacity(@intCast(self.string_bytes.items.len));
83538434 }
83548435 return String.fromIndex(gop.index);
83558436}
83568437
8438pub fn stringNull(self: *Builder, bytes: [:0]const u8) Allocator.Error!String {
8439 return self.string(bytes[0 .. bytes.len + 1]);
8440}
8441
83578442pub fn stringIfExists(self: *const Builder, bytes: []const u8) ?String {
83588443 return String.fromIndex(
83598444 self.string_map.getIndexAdapted(bytes, String.Adapter{ .builder = self }) orelse return null,
......@@ -8362,16 +8447,25 @@ pub fn stringIfExists(self: *const Builder, bytes: []const u8) ?String {
83628447
83638448pub fn fmt(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) Allocator.Error!String {
83648449 try self.string_map.ensureUnusedCapacity(self.gpa, 1);
8365 try self.string_bytes.ensureUnusedCapacity(self.gpa, @intCast(std.fmt.count(fmt_str ++ .{0}, fmt_args)));
8450 try self.string_bytes.ensureUnusedCapacity(self.gpa, @intCast(std.fmt.count(fmt_str, fmt_args)));
83668451 try self.string_indices.ensureUnusedCapacity(self.gpa, 1);
83678452 return self.fmtAssumeCapacity(fmt_str, fmt_args);
83688453}
83698454
83708455pub fn fmtAssumeCapacity(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) String {
8371 const start = self.string_bytes.items.len;
8372 self.string_bytes.writer(self.gpa).print(fmt_str ++ .{0}, fmt_args) catch unreachable;
8373 const bytes: []const u8 = self.string_bytes.items[start .. self.string_bytes.items.len - 1];
8456 self.string_bytes.writer(undefined).print(fmt_str, fmt_args) catch unreachable;
8457 return self.trailingStringAssumeCapacity();
8458}
8459
8460pub fn trailingString(self: *Builder) Allocator.Error!String {
8461 try self.string_indices.ensureUnusedCapacity(self.gpa, 1);
8462 try self.string_map.ensureUnusedCapacity(self.gpa, 1);
8463 return self.trailingStringAssumeCapacity();
8464}
83748465
8466pub fn trailingStringAssumeCapacity(self: *Builder) String {
8467 const start = self.string_indices.getLast();
8468 const bytes: []const u8 = self.string_bytes.items[start..];
83758469 const gop = self.string_map.getOrPutAssumeCapacityAdapted(bytes, String.Adapter{ .builder = self });
83768470 if (gop.found_existing) {
83778471 self.string_bytes.shrinkRetainingCapacity(start);
......@@ -8435,7 +8529,7 @@ pub fn structType(
84358529pub fn opaqueType(self: *Builder, name: String) Allocator.Error!Type {
84368530 try self.string_map.ensureUnusedCapacity(self.gpa, 1);
84378531 if (name.slice(self)) |id| {
8438 const count: usize = comptime std.fmt.count("{d}" ++ .{0}, .{std.math.maxInt(u32)});
8532 const count: usize = comptime std.fmt.count("{d}", .{std.math.maxInt(u32)});
84398533 try self.string_bytes.ensureUnusedCapacity(self.gpa, id.len + count);
84408534 }
84418535 try self.string_indices.ensureUnusedCapacity(self.gpa, 1);
......@@ -8449,98 +8543,17 @@ pub fn namedTypeSetBody(
84498543 self: *Builder,
84508544 named_type: Type,
84518545 body_type: Type,
8452) (if (build_options.have_llvm) Allocator.Error else error{})!void {
8546) void {
84538547 const named_item = self.type_items.items[@intFromEnum(named_type)];
84548548 self.type_extra.items[named_item.data + std.meta.fieldIndex(Type.NamedStructure, "body").?] =
84558549 @intFromEnum(body_type);
8456 if (self.useLibLlvm()) {
8457 const body_item = self.type_items.items[@intFromEnum(body_type)];
8458 var body_extra = self.typeExtraDataTrail(Type.Structure, body_item.data);
8459 const body_fields = body_extra.trail.next(body_extra.data.fields_len, Type, self);
8460 const llvm_fields = try self.gpa.alloc(*llvm.Type, body_fields.len);
8461 defer self.gpa.free(llvm_fields);
8462 for (llvm_fields, body_fields) |*llvm_field, body_field| llvm_field.* = body_field.toLlvm(self);
8463 self.llvm.types.items[@intFromEnum(named_type)].structSetBody(
8464 llvm_fields.ptr,
8465 @intCast(llvm_fields.len),
8466 switch (body_item.tag) {
8467 .structure => .False,
8468 .packed_structure => .True,
8469 else => unreachable,
8470 },
8471 );
8472 }
84738550}
84748551
84758552pub fn attr(self: *Builder, attribute: Attribute) Allocator.Error!Attribute.Index {
84768553 try self.attributes.ensureUnusedCapacity(self.gpa, 1);
8477 if (self.useLibLlvm()) try self.llvm.attributes.ensureUnusedCapacity(self.gpa, 1);
84788554
84798555 const gop = self.attributes.getOrPutAssumeCapacity(attribute.toStorage());
8480 if (!gop.found_existing) {
8481 gop.value_ptr.* = {};
8482 if (self.useLibLlvm()) self.llvm.attributes.appendAssumeCapacity(switch (attribute) {
8483 else => llvm_attr: {
8484 const llvm_kind_id = attribute.getKind().toLlvm(self);
8485 if (llvm_kind_id.* == 0) {
8486 const name = @tagName(attribute);
8487 llvm_kind_id.* = llvm.getEnumAttributeKindForName(name.ptr, name.len);
8488 assert(llvm_kind_id.* != 0);
8489 }
8490 break :llvm_attr switch (attribute) {
8491 else => switch (attribute) {
8492 inline else => |value| self.llvm.context.createEnumAttribute(
8493 llvm_kind_id.*,
8494 switch (@TypeOf(value)) {
8495 void => 0,
8496 u32 => value,
8497 Attribute.FpClass,
8498 Attribute.AllocKind,
8499 Attribute.Memory,
8500 => @as(u32, @bitCast(value)),
8501 Alignment => value.toByteUnits() orelse 0,
8502 Attribute.AllocSize,
8503 Attribute.VScaleRange,
8504 => @bitCast(value.toLlvm()),
8505 Attribute.UwTable => @intFromEnum(value),
8506 else => @compileError(
8507 "bad payload type: " ++ @typeName(@TypeOf(value)),
8508 ),
8509 },
8510 ),
8511 .byval,
8512 .byref,
8513 .preallocated,
8514 .inalloca,
8515 .sret,
8516 .elementtype,
8517 .string,
8518 .none,
8519 => unreachable,
8520 },
8521 .byval,
8522 .byref,
8523 .preallocated,
8524 .inalloca,
8525 .sret,
8526 .elementtype,
8527 => |ty| self.llvm.context.createTypeAttribute(llvm_kind_id.*, ty.toLlvm(self)),
8528 .string, .none => unreachable,
8529 };
8530 },
8531 .string => |string_attr| llvm_attr: {
8532 const kind = string_attr.kind.slice(self).?;
8533 const value = string_attr.value.slice(self).?;
8534 break :llvm_attr self.llvm.context.createStringAttribute(
8535 kind.ptr,
8536 @intCast(kind.len),
8537 value.ptr,
8538 @intCast(value.len),
8539 );
8540 },
8541 .none => unreachable,
8542 });
8543 }
8556 if (!gop.found_existing) gop.value_ptr.* = {};
85448557 return @enumFromInt(gop.index);
85458558}
85468559
......@@ -8557,12 +8570,16 @@ pub fn attrs(self: *Builder, attributes: []Attribute.Index) Allocator.Error!Attr
85578570}
85588571
85598572pub fn fnAttrs(self: *Builder, fn_attributes: []const Attributes) Allocator.Error!FunctionAttributes {
8560 return @enumFromInt(try self.attrGeneric(@ptrCast(
8573 try self.function_attributes_set.ensureUnusedCapacity(self.gpa, 1);
8574 const function_attributes: FunctionAttributes = @enumFromInt(try self.attrGeneric(@ptrCast(
85618575 fn_attributes[0..if (std.mem.lastIndexOfNone(Attributes, fn_attributes, &.{.none})) |last|
85628576 last + 1
85638577 else
85648578 0],
85658579 )));
8580
8581 _ = self.function_attributes_set.getOrPutAssumeCapacity(function_attributes);
8582 return function_attributes;
85668583}
85678584
85688585pub fn addGlobal(self: *Builder, name: String, global: Global) Allocator.Error!Global.Index {
......@@ -8586,7 +8603,6 @@ pub fn addGlobalAssumeCapacity(self: *Builder, name: String, global: Global) Glo
85868603 global_gop.value_ptr.* = global;
85878604 const global_index: Global.Index = @enumFromInt(global_gop.index);
85888605 global_index.updateDsoLocal(self);
8589 global_index.updateName(self);
85908606 return global_index;
85918607 }
85928608
......@@ -8622,12 +8638,6 @@ pub fn addAliasAssumeCapacity(
86228638 addr_space: AddrSpace,
86238639 aliasee: Constant,
86248640) Alias.Index {
8625 if (self.useLibLlvm()) self.llvm.globals.appendAssumeCapacity(self.llvm.module.?.addAlias(
8626 ty.toLlvm(self),
8627 @intFromEnum(addr_space),
8628 aliasee.toLlvm(self),
8629 name.slice(self).?,
8630 ));
86318641 const alias_index: Alias.Index = @enumFromInt(self.aliases.items.len);
86328642 self.aliases.appendAssumeCapacity(.{ .global = self.addGlobalAssumeCapacity(name, .{
86338643 .addr_space = addr_space,
......@@ -8656,13 +8666,6 @@ pub fn addVariableAssumeCapacity(
86568666 name: String,
86578667 addr_space: AddrSpace,
86588668) Variable.Index {
8659 if (self.useLibLlvm()) self.llvm.globals.appendAssumeCapacity(
8660 self.llvm.module.?.addGlobalInAddressSpace(
8661 ty.toLlvm(self),
8662 name.slice(self).?,
8663 @intFromEnum(addr_space),
8664 ),
8665 );
86668669 const variable_index: Variable.Index = @enumFromInt(self.variables.items.len);
86678670 self.variables.appendAssumeCapacity(.{ .global = self.addGlobalAssumeCapacity(name, .{
86688671 .addr_space = addr_space,
......@@ -8692,13 +8695,6 @@ pub fn addFunctionAssumeCapacity(
86928695 addr_space: AddrSpace,
86938696) Function.Index {
86948697 assert(ty.isFunction(self));
8695 if (self.useLibLlvm()) self.llvm.globals.appendAssumeCapacity(
8696 self.llvm.module.?.addFunctionInAddressSpace(
8697 name.slice(self).?,
8698 ty.toLlvm(self),
8699 @intFromEnum(addr_space),
8700 ),
8701 );
87028698 const function_index: Function.Index = @enumFromInt(self.functions.items.len);
87038699 self.functions.appendAssumeCapacity(.{ .global = self.addGlobalAssumeCapacity(name, .{
87048700 .addr_space = addr_space,
......@@ -8714,7 +8710,6 @@ pub fn getIntrinsic(
87148710 overload: []const Type,
87158711) Allocator.Error!Function.Index {
87168712 const ExpectedContents = extern union {
8717 name: [expected_intrinsic_name_len]u8,
87188713 attrs: extern struct {
87198714 params: [expected_args_len]Type,
87208715 fn_attrs: [FunctionAttributes.params_index + expected_args_len]Attributes,
......@@ -8727,12 +8722,10 @@ pub fn getIntrinsic(
87278722 const allocator = stack.get();
87288723
87298724 const name = name: {
8730 var buffer = std.ArrayList(u8).init(allocator);
8731 defer buffer.deinit();
8732
8733 try buffer.writer().print("llvm.{s}", .{@tagName(id)});
8734 for (overload) |ty| try buffer.writer().print(".{m}", .{ty.fmt(self)});
8735 break :name try self.string(buffer.items);
8725 const writer = self.string_bytes.writer(self.gpa);
8726 try writer.print("llvm.{s}", .{@tagName(id)});
8727 for (overload) |ty| try writer.print(".{m}", .{ty.fmt(self)});
8728 break :name try self.trailingString();
87368729 };
87378730 if (self.getGlobal(name)) |global| return global.ptrConst(self).kind.function;
87388731
......@@ -8826,7 +8819,6 @@ pub fn bigIntConst(self: *Builder, ty: Type, value: std.math.big.int.Const) Allo
88268819 try self.constant_map.ensureUnusedCapacity(self.gpa, 1);
88278820 try self.constant_items.ensureUnusedCapacity(self.gpa, 1);
88288821 try self.constant_limbs.ensureUnusedCapacity(self.gpa, Constant.Integer.limbs + value.limbs.len);
8829 if (self.useLibLlvm()) try self.llvm.constants.ensureUnusedCapacity(self.gpa, 1);
88308822 return self.bigIntConstAssumeCapacity(ty, value);
88318823}
88328824
......@@ -8977,16 +8969,6 @@ pub fn stringValue(self: *Builder, val: String) Allocator.Error!Value {
89778969 return (try self.stringConst(val)).toValue();
89788970}
89798971
8980pub fn stringNullConst(self: *Builder, val: String) Allocator.Error!Constant {
8981 try self.ensureUnusedTypeCapacity(1, Type.Array, 0);
8982 try self.ensureUnusedConstantCapacity(1, NoExtra, 0);
8983 return self.stringNullConstAssumeCapacity(val);
8984}
8985
8986pub fn stringNullValue(self: *Builder, val: String) Allocator.Error!Value {
8987 return (try self.stringNullConst(val)).toValue();
8988}
8989
89908972pub fn vectorConst(self: *Builder, ty: Type, vals: []const Constant) Allocator.Error!Constant {
89918973 try self.ensureUnusedConstantCapacity(1, Constant.Aggregate, vals.len);
89928974 return self.vectorConstAssumeCapacity(ty, vals);
......@@ -9244,72 +9226,20 @@ pub fn asmValue(
92449226 return (try self.asmConst(ty, info, assembly, constraints)).toValue();
92459227}
92469228
9247pub fn verify(self: *Builder) error{}!bool {
9248 if (self.useLibLlvm()) {
9249 var error_message: [*:0]const u8 = undefined;
9250 // verifyModule always allocs the error_message even if there is no error
9251 defer llvm.disposeMessage(error_message);
9252
9253 if (self.llvm.module.?.verify(.ReturnStatus, &error_message).toBool()) {
9254 log.err("failed verification of LLVM module:\n{s}\n", .{error_message});
9255 return false;
9256 }
9257 }
9258 return true;
9259}
9260
9261pub fn writeBitcodeToFile(self: *Builder, path: []const u8) Allocator.Error!bool {
9262 const path_z = try self.gpa.dupeZ(u8, path);
9263 defer self.gpa.free(path_z);
9264 return self.writeBitcodeToFileZ(path_z);
9265}
9266
9267pub fn writeBitcodeToFileZ(self: *Builder, path: [*:0]const u8) bool {
9268 if (self.useLibLlvm()) {
9269 const error_code = self.llvm.module.?.writeBitcodeToFile(path);
9270 if (error_code != 0) {
9271 log.err("failed dumping LLVM module to \"{s}\": {d}", .{ path, error_code });
9272 return false;
9273 }
9274 } else {
9275 log.err("writing bitcode without libllvm not implemented", .{});
9276 return false;
9277 }
9278 return true;
9279}
9280
92819229pub fn dump(self: *Builder) void {
9282 if (self.useLibLlvm())
9283 self.llvm.module.?.dump()
9284 else
9285 self.print(std.io.getStdErr().writer()) catch {};
9230 self.print(std.io.getStdErr().writer()) catch {};
92869231}
92879232
92889233pub fn printToFile(self: *Builder, path: []const u8) Allocator.Error!bool {
9289 const path_z = try self.gpa.dupeZ(u8, path);
9290 defer self.gpa.free(path_z);
9291 return self.printToFileZ(path_z);
9292}
9293
9294pub fn printToFileZ(self: *Builder, path: [*:0]const u8) bool {
9295 if (self.useLibLlvm()) {
9296 var error_message: [*:0]const u8 = undefined;
9297 if (self.llvm.module.?.printModuleToFile(path, &error_message).toBool()) {
9298 defer llvm.disposeMessage(error_message);
9299 log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, error_message });
9300 return false;
9301 }
9302 } else {
9303 var file = std.fs.cwd().createFileZ(path, .{}) catch |err| {
9304 log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) });
9305 return false;
9306 };
9307 defer file.close();
9308 self.print(file.writer()) catch |err| {
9309 log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) });
9310 return false;
9311 };
9312 }
9234 var file = std.fs.cwd().createFile(path, .{}) catch |err| {
9235 log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) });
9236 return false;
9237 };
9238 defer file.close();
9239 self.print(file.writer()) catch |err| {
9240 log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) });
9241 return false;
9242 };
93139243 return true;
93149244}
93159245
......@@ -9324,9 +9254,11 @@ pub fn printUnbuffered(
93249254 writer: anytype,
93259255) (@TypeOf(writer).Error || Allocator.Error)!void {
93269256 var need_newline = false;
9257 var metadata_formatter: Metadata.Formatter = .{ .builder = self, .need_comma = undefined };
9258 defer metadata_formatter.map.deinit(self.gpa);
93279259
93289260 if (self.source_filename != .none or self.data_layout != .none or self.target_triple != .none) {
9329 if (need_newline) try writer.writeByte('\n');
9261 if (need_newline) try writer.writeByte('\n') else need_newline = true;
93309262 if (self.source_filename != .none) try writer.print(
93319263 \\; ModuleID = '{s}'
93329264 \\source_filename = {"}
......@@ -9340,40 +9272,40 @@ pub fn printUnbuffered(
93409272 \\target triple = {"}
93419273 \\
93429274 , .{self.target_triple.fmt(self)});
9343 need_newline = true;
93449275 }
93459276
93469277 if (self.module_asm.items.len > 0) {
9347 if (need_newline) try writer.writeByte('\n');
9278 if (need_newline) try writer.writeByte('\n') else need_newline = true;
93489279 var line_it = std.mem.tokenizeScalar(u8, self.module_asm.items, '\n');
93499280 while (line_it.next()) |line| {
93509281 try writer.writeAll("module asm ");
93519282 try printEscapedString(line, .always_quote, writer);
93529283 try writer.writeByte('\n');
93539284 }
9354 need_newline = true;
93559285 }
93569286
93579287 if (self.types.count() > 0) {
9358 if (need_newline) try writer.writeByte('\n');
9288 if (need_newline) try writer.writeByte('\n') else need_newline = true;
93599289 for (self.types.keys(), self.types.values()) |id, ty| try writer.print(
93609290 \\%{} = type {}
93619291 \\
93629292 , .{ id.fmt(self), ty.fmt(self) });
9363 need_newline = true;
93649293 }
93659294
93669295 if (self.variables.items.len > 0) {
9367 if (need_newline) try writer.writeByte('\n');
9296 if (need_newline) try writer.writeByte('\n') else need_newline = true;
93689297 for (self.variables.items) |variable| {
93699298 if (variable.global.getReplacement(self) != .none) continue;
93709299 const global = variable.global.ptrConst(self);
9300 metadata_formatter.need_comma = true;
9301 defer metadata_formatter.need_comma = undefined;
93719302 try writer.print(
9372 \\{} ={}{}{}{}{ }{}{ }{} {s} {%}{ }{, }
9303 \\{} ={}{}{}{}{ }{}{ }{} {s} {%}{ }{, }{}
93739304 \\
93749305 , .{
93759306 variable.global.fmt(self),
9376 global.linkage,
9307 Linkage.fmtOptional(if (global.linkage == .external and
9308 variable.init != .no_init) null else global.linkage),
93779309 global.preemption,
93789310 global.visibility,
93799311 global.dll_storage_class,
......@@ -9385,18 +9317,20 @@ pub fn printUnbuffered(
93859317 global.type.fmt(self),
93869318 variable.init.fmt(self),
93879319 variable.alignment,
9320 try metadata_formatter.fmt("!dbg ", global.dbg),
93889321 });
93899322 }
9390 need_newline = true;
93919323 }
93929324
93939325 if (self.aliases.items.len > 0) {
9394 if (need_newline) try writer.writeByte('\n');
9326 if (need_newline) try writer.writeByte('\n') else need_newline = true;
93959327 for (self.aliases.items) |alias| {
93969328 if (alias.global.getReplacement(self) != .none) continue;
93979329 const global = alias.global.ptrConst(self);
9330 metadata_formatter.need_comma = true;
9331 defer metadata_formatter.need_comma = undefined;
93989332 try writer.print(
9399 \\{} ={}{}{}{}{ }{} alias {%}, {%}
9333 \\{} ={}{}{}{}{ }{} alias {%}, {%}{}
94009334 \\
94019335 , .{
94029336 alias.global.fmt(self),
......@@ -9408,9 +9342,9 @@ pub fn printUnbuffered(
94089342 global.unnamed_addr,
94099343 global.type.fmt(self),
94109344 alias.aliasee.fmt(self),
9345 try metadata_formatter.fmt("!dbg ", global.dbg),
94119346 });
94129347 }
9413 need_newline = true;
94149348 }
94159349
94169350 var attribute_groups: std.AutoArrayHashMapUnmanaged(Attributes, void) = .{};
......@@ -9418,7 +9352,7 @@ pub fn printUnbuffered(
94189352
94199353 for (0.., self.functions.items) |function_i, function| {
94209354 if (function.global.getReplacement(self) != .none) continue;
9421 if (need_newline) try writer.writeByte('\n');
9355 if (need_newline) try writer.writeByte('\n') else need_newline = true;
94229356 const function_index: Function.Index = @enumFromInt(function_i);
94239357 const global = function.global.ptrConst(self);
94249358 const params_len = global.type.functionParameters(self).len;
......@@ -9464,13 +9398,23 @@ pub fn printUnbuffered(
94649398 if (function_attributes != .none) try writer.print(" #{d}", .{
94659399 (try attribute_groups.getOrPutValue(self.gpa, function_attributes, {})).index,
94669400 });
9467 try writer.print("{ }", .{function.alignment});
9401 {
9402 metadata_formatter.need_comma = false;
9403 defer metadata_formatter.need_comma = undefined;
9404 try writer.print("{ }{}", .{
9405 function.alignment,
9406 try metadata_formatter.fmt(" !dbg ", global.dbg),
9407 });
9408 }
94689409 if (function.instructions.len > 0) {
94699410 var block_incoming_len: u32 = undefined;
94709411 try writer.writeAll(" {\n");
9412 var dbg: Metadata = .none;
94719413 for (params_len..function.instructions.len) |instruction_i| {
94729414 const instruction_index: Function.Instruction.Index = @enumFromInt(instruction_i);
94739415 const instruction = function.instructions.get(@intFromEnum(instruction_index));
9416 if (function.debug_locations.get(instruction_index)) |debug_location|
9417 dbg = debug_location;
94749418 switch (instruction.tag) {
94759419 .add,
94769420 .@"add nsw",
......@@ -9555,7 +9499,7 @@ pub fn printUnbuffered(
95559499 .xor,
95569500 => |tag| {
95579501 const extra = function.extraData(Function.Instruction.Binary, instruction.data);
9558 try writer.print(" %{} = {s} {%}, {}\n", .{
9502 try writer.print(" %{} = {s} {%}, {}", .{
95599503 instruction_index.name(&function).fmt(self),
95609504 @tagName(tag),
95619505 extra.lhs.fmt(function_index, self),
......@@ -9577,7 +9521,7 @@ pub fn printUnbuffered(
95779521 .zext,
95789522 => |tag| {
95799523 const extra = function.extraData(Function.Instruction.Cast, instruction.data);
9580 try writer.print(" %{} = {s} {%} to {%}\n", .{
9524 try writer.print(" %{} = {s} {%} to {%}", .{
95819525 instruction_index.name(&function).fmt(self),
95829526 @tagName(tag),
95839527 extra.val.fmt(function_index, self),
......@@ -9588,11 +9532,14 @@ pub fn printUnbuffered(
95889532 .@"alloca inalloca",
95899533 => |tag| {
95909534 const extra = function.extraData(Function.Instruction.Alloca, instruction.data);
9591 try writer.print(" %{} = {s} {%}{,%}{, }{, }\n", .{
9535 try writer.print(" %{} = {s} {%}{,%}{, }{, }", .{
95929536 instruction_index.name(&function).fmt(self),
95939537 @tagName(tag),
95949538 extra.type.fmt(self),
9595 extra.len.fmt(function_index, self),
9539 Value.fmt(switch (extra.len) {
9540 .@"1" => .none,
9541 else => extra.len,
9542 }, function_index, self),
95969543 extra.info.alignment,
95979544 extra.info.addr_space,
95989545 });
......@@ -9601,7 +9548,7 @@ pub fn printUnbuffered(
96019548 .atomicrmw => |tag| {
96029549 const extra =
96039550 function.extraData(Function.Instruction.AtomicRmw, instruction.data);
9604 try writer.print(" %{} = {s}{ } {s} {%}, {%}{ }{ }{, }\n", .{
9551 try writer.print(" %{} = {s}{ } {s} {%}, {%}{ }{ }{, }", .{
96059552 instruction_index.name(&function).fmt(self),
96069553 @tagName(tag),
96079554 extra.info.access_kind,
......@@ -9619,16 +9566,17 @@ pub fn printUnbuffered(
96199566 if (@intFromEnum(instruction_index) > params_len)
96209567 try writer.writeByte('\n');
96219568 try writer.print("{}:\n", .{name.fmt(self)});
9569 continue;
96229570 },
96239571 .br => |tag| {
96249572 const target: Function.Block.Index = @enumFromInt(instruction.data);
9625 try writer.print(" {s} {%}\n", .{
9573 try writer.print(" {s} {%}", .{
96269574 @tagName(tag), target.toInst(&function).fmt(function_index, self),
96279575 });
96289576 },
96299577 .br_cond => {
96309578 const extra = function.extraData(Function.Instruction.BrCond, instruction.data);
9631 try writer.print(" br {%}, {%}, {%}\n", .{
9579 try writer.print(" br {%}, {%}, {%}", .{
96329580 extra.cond.fmt(function_index, self),
96339581 extra.then.toInst(&function).fmt(function_index, self),
96349582 extra.@"else".toInst(&function).fmt(function_index, self),
......@@ -9668,10 +9616,12 @@ pub fn printUnbuffered(
96689616 });
96699617 for (0.., args) |arg_index, arg| {
96709618 if (arg_index > 0) try writer.writeAll(", ");
9671 try writer.print("{%}{} {}", .{
9619 metadata_formatter.need_comma = false;
9620 defer metadata_formatter.need_comma = undefined;
9621 try writer.print("{%}{}{}", .{
96729622 arg.typeOf(function_index, self).fmt(self),
96739623 extra.data.attributes.param(arg_index, self).fmt(self),
9674 arg.fmt(function_index, self),
9624 try metadata_formatter.fmtLocal(" ", arg, function_index),
96759625 });
96769626 }
96779627 try writer.writeByte(')');
......@@ -9683,14 +9633,13 @@ pub fn printUnbuffered(
96839633 {},
96849634 )).index,
96859635 });
9686 try writer.writeByte('\n');
96879636 },
96889637 .cmpxchg,
96899638 .@"cmpxchg weak",
96909639 => |tag| {
96919640 const extra =
96929641 function.extraData(Function.Instruction.CmpXchg, instruction.data);
9693 try writer.print(" %{} = {s}{ } {%}, {%}, {%}{ }{ }{ }{, }\n", .{
9642 try writer.print(" %{} = {s}{ } {%}, {%}, {%}{ }{ }{ }{, }", .{
96949643 instruction_index.name(&function).fmt(self),
96959644 @tagName(tag),
96969645 extra.info.access_kind,
......@@ -9706,7 +9655,7 @@ pub fn printUnbuffered(
97069655 .extractelement => |tag| {
97079656 const extra =
97089657 function.extraData(Function.Instruction.ExtractElement, instruction.data);
9709 try writer.print(" %{} = {s} {%}, {%}\n", .{
9658 try writer.print(" %{} = {s} {%}, {%}", .{
97109659 instruction_index.name(&function).fmt(self),
97119660 @tagName(tag),
97129661 extra.val.fmt(function_index, self),
......@@ -9725,7 +9674,6 @@ pub fn printUnbuffered(
97259674 extra.data.val.fmt(function_index, self),
97269675 });
97279676 for (indices) |index| try writer.print(", {d}", .{index});
9728 try writer.writeByte('\n');
97299677 },
97309678 .fence => |tag| {
97319679 const info: MemoryAccessInfo = @bitCast(instruction.data);
......@@ -9739,7 +9687,7 @@ pub fn printUnbuffered(
97399687 .@"fneg fast",
97409688 => |tag| {
97419689 const val: Value = @enumFromInt(instruction.data);
9742 try writer.print(" %{} = {s} {%}\n", .{
9690 try writer.print(" %{} = {s} {%}", .{
97439691 instruction_index.name(&function).fmt(self),
97449692 @tagName(tag),
97459693 val.fmt(function_index, self),
......@@ -9762,12 +9710,11 @@ pub fn printUnbuffered(
97629710 for (indices) |index| try writer.print(", {%}", .{
97639711 index.fmt(function_index, self),
97649712 });
9765 try writer.writeByte('\n');
97669713 },
97679714 .insertelement => |tag| {
97689715 const extra =
97699716 function.extraData(Function.Instruction.InsertElement, instruction.data);
9770 try writer.print(" %{} = {s} {%}, {%}, {%}\n", .{
9717 try writer.print(" %{} = {s} {%}, {%}, {%}", .{
97719718 instruction_index.name(&function).fmt(self),
97729719 @tagName(tag),
97739720 extra.val.fmt(function_index, self),
......@@ -9786,13 +9733,12 @@ pub fn printUnbuffered(
97869733 extra.data.elem.fmt(function_index, self),
97879734 });
97889735 for (indices) |index| try writer.print(", {d}", .{index});
9789 try writer.writeByte('\n');
97909736 },
97919737 .load,
97929738 .@"load atomic",
97939739 => |tag| {
97949740 const extra = function.extraData(Function.Instruction.Load, instruction.data);
9795 try writer.print(" %{} = {s}{ } {%}, {%}{ }{ }{, }\n", .{
9741 try writer.print(" %{} = {s}{ } {%}, {%}{ }{ }{, }", .{
97969742 instruction_index.name(&function).fmt(self),
97979743 @tagName(tag),
97989744 extra.info.access_kind,
......@@ -9822,23 +9768,22 @@ pub fn printUnbuffered(
98229768 incoming_block.toInst(&function).fmt(function_index, self),
98239769 });
98249770 }
9825 try writer.writeByte('\n');
98269771 },
98279772 .ret => |tag| {
98289773 const val: Value = @enumFromInt(instruction.data);
9829 try writer.print(" {s} {%}\n", .{
9774 try writer.print(" {s} {%}", .{
98309775 @tagName(tag),
98319776 val.fmt(function_index, self),
98329777 });
98339778 },
98349779 .@"ret void",
98359780 .@"unreachable",
9836 => |tag| try writer.print(" {s}\n", .{@tagName(tag)}),
9781 => |tag| try writer.print(" {s}", .{@tagName(tag)}),
98379782 .select,
98389783 .@"select fast",
98399784 => |tag| {
98409785 const extra = function.extraData(Function.Instruction.Select, instruction.data);
9841 try writer.print(" %{} = {s} {%}, {%}, {%}\n", .{
9786 try writer.print(" %{} = {s} {%}, {%}, {%}", .{
98429787 instruction_index.name(&function).fmt(self),
98439788 @tagName(tag),
98449789 extra.cond.fmt(function_index, self),
......@@ -9849,7 +9794,7 @@ pub fn printUnbuffered(
98499794 .shufflevector => |tag| {
98509795 const extra =
98519796 function.extraData(Function.Instruction.ShuffleVector, instruction.data);
9852 try writer.print(" %{} = {s} {%}, {%}, {%}\n", .{
9797 try writer.print(" %{} = {s} {%}, {%}, {%}", .{
98539798 instruction_index.name(&function).fmt(self),
98549799 @tagName(tag),
98559800 extra.lhs.fmt(function_index, self),
......@@ -9861,7 +9806,7 @@ pub fn printUnbuffered(
98619806 .@"store atomic",
98629807 => |tag| {
98639808 const extra = function.extraData(Function.Instruction.Store, instruction.data);
9864 try writer.print(" {s}{ } {%}, {%}{ }{ }{, }\n", .{
9809 try writer.print(" {s}{ } {%}, {%}{ }{ }{, }", .{
98659810 @tagName(tag),
98669811 extra.info.access_kind,
98679812 extra.val.fmt(function_index, self),
......@@ -9889,11 +9834,11 @@ pub fn printUnbuffered(
98899834 case_block.toInst(&function).fmt(function_index, self),
98909835 },
98919836 );
9892 try writer.writeAll(" ]\n");
9837 try writer.writeAll(" ]");
98939838 },
98949839 .va_arg => |tag| {
98959840 const extra = function.extraData(Function.Instruction.VaArg, instruction.data);
9896 try writer.print(" %{} = {s} {%}, {%}\n", .{
9841 try writer.print(" %{} = {s} {%}, {%}", .{
98979842 instruction_index.name(&function).fmt(self),
98989843 @tagName(tag),
98999844 extra.list.fmt(function_index, self),
......@@ -9901,11 +9846,13 @@ pub fn printUnbuffered(
99019846 });
99029847 },
99039848 }
9849 metadata_formatter.need_comma = true;
9850 defer metadata_formatter.need_comma = undefined;
9851 try writer.print("{}\n", .{try metadata_formatter.fmt("!dbg ", dbg)});
99049852 }
99059853 try writer.writeByte('}');
99069854 }
99079855 try writer.writeByte('\n');
9908 need_newline = true;
99099856 }
99109857
99119858 if (attribute_groups.count() > 0) {
......@@ -9915,12 +9862,375 @@ pub fn printUnbuffered(
99159862 \\attributes #{d} = {{{#"} }}
99169863 \\
99179864 , .{ attribute_group_index, attribute_group.fmt(self) });
9918 need_newline = true;
99199865 }
9920}
99219866
9922pub inline fn useLibLlvm(self: *const Builder) bool {
9923 return build_options.have_llvm and self.use_lib_llvm;
9867 if (self.metadata_named.count() > 0) {
9868 if (need_newline) try writer.writeByte('\n') else need_newline = true;
9869 for (self.metadata_named.keys(), self.metadata_named.values()) |name, data| {
9870 const elements: []const Metadata =
9871 @ptrCast(self.metadata_extra.items[data.index..][0..data.len]);
9872 try writer.writeByte('!');
9873 try printEscapedString(name.slice(self), .quote_unless_valid_identifier, writer);
9874 try writer.writeAll(" = !{");
9875 metadata_formatter.need_comma = false;
9876 defer metadata_formatter.need_comma = undefined;
9877 for (elements) |element| try writer.print("{}", .{try metadata_formatter.fmt("", element)});
9878 try writer.writeAll("}\n");
9879 }
9880 }
9881
9882 if (metadata_formatter.map.count() > 0) {
9883 if (need_newline) try writer.writeByte('\n') else need_newline = true;
9884 var metadata_index: usize = 0;
9885 while (metadata_index < metadata_formatter.map.count()) : (metadata_index += 1) {
9886 @setEvalBranchQuota(10_000);
9887 const metadata_item =
9888 self.metadata_items.get(@intFromEnum(metadata_formatter.map.keys()[metadata_index]));
9889 try writer.print("!{} = ", .{metadata_index});
9890 metadata_formatter.need_comma = false;
9891 defer metadata_formatter.need_comma = undefined;
9892 switch (metadata_item.tag) {
9893 .none, .expression, .constant => unreachable,
9894 .file => {
9895 const extra = self.metadataExtraData(Metadata.File, metadata_item.data);
9896 try metadata_formatter.specialized(.@"!", .DIFile, .{
9897 .filename = extra.filename,
9898 .directory = extra.directory,
9899 .checksumkind = null,
9900 .checksum = null,
9901 .source = null,
9902 }, writer);
9903 },
9904 .compile_unit,
9905 .@"compile_unit optimized",
9906 => |kind| {
9907 const extra = self.metadataExtraData(Metadata.CompileUnit, metadata_item.data);
9908 try metadata_formatter.specialized(.@"distinct !", .DICompileUnit, .{
9909 .language = .DW_LANG_C99,
9910 .file = extra.file,
9911 .producer = extra.producer,
9912 .isOptimized = switch (kind) {
9913 .compile_unit => false,
9914 .@"compile_unit optimized" => true,
9915 else => unreachable,
9916 },
9917 .flags = null,
9918 .runtimeVersion = 0,
9919 .splitDebugFilename = null,
9920 .emissionKind = .FullDebug,
9921 .enums = extra.enums,
9922 .retainedTypes = null,
9923 .globals = extra.globals,
9924 .imports = null,
9925 .macros = null,
9926 .dwoId = null,
9927 .splitDebugInlining = false,
9928 .debugInfoForProfiling = null,
9929 .nameTableKind = null,
9930 .rangesBaseAddress = null,
9931 .sysroot = null,
9932 .sdk = null,
9933 }, writer);
9934 },
9935 .subprogram,
9936 .@"subprogram local",
9937 .@"subprogram definition",
9938 .@"subprogram local definition",
9939 .@"subprogram optimized",
9940 .@"subprogram optimized local",
9941 .@"subprogram optimized definition",
9942 .@"subprogram optimized local definition",
9943 => |kind| {
9944 const extra = self.metadataExtraData(Metadata.Subprogram, metadata_item.data);
9945 try metadata_formatter.specialized(.@"distinct !", .DISubprogram, .{
9946 .name = extra.name,
9947 .linkageName = extra.linkage_name,
9948 .scope = extra.file,
9949 .file = extra.file,
9950 .line = extra.line,
9951 .type = extra.ty,
9952 .scopeLine = extra.scope_line,
9953 .containingType = null,
9954 .virtualIndex = null,
9955 .thisAdjustment = null,
9956 .flags = extra.di_flags,
9957 .spFlags = @as(Metadata.Subprogram.DISPFlags, @bitCast(@as(u32, @as(u3, @intCast(
9958 @intFromEnum(kind) - @intFromEnum(Metadata.Tag.subprogram),
9959 ))) << 2)),
9960 .unit = extra.compile_unit,
9961 .templateParams = null,
9962 .declaration = null,
9963 .retainedNodes = null,
9964 .thrownTypes = null,
9965 .annotations = null,
9966 .targetFuncName = null,
9967 }, writer);
9968 },
9969 .lexical_block => {
9970 const extra = self.metadataExtraData(Metadata.LexicalBlock, metadata_item.data);
9971 try metadata_formatter.specialized(.@"distinct !", .DILexicalBlock, .{
9972 .scope = extra.scope,
9973 .file = extra.file,
9974 .line = extra.line,
9975 .column = extra.column,
9976 }, writer);
9977 },
9978 .location => {
9979 const extra = self.metadataExtraData(Metadata.Location, metadata_item.data);
9980 try metadata_formatter.specialized(.@"!", .DILocation, .{
9981 .line = extra.line,
9982 .column = extra.column,
9983 .scope = extra.scope,
9984 .inlinedAt = extra.inlined_at,
9985 .isImplicitCode = false,
9986 }, writer);
9987 },
9988 .basic_bool_type,
9989 .basic_unsigned_type,
9990 .basic_signed_type,
9991 .basic_float_type,
9992 => |kind| {
9993 const extra = self.metadataExtraData(Metadata.BasicType, metadata_item.data);
9994 try metadata_formatter.specialized(.@"!", .DIBasicType, .{
9995 .tag = null,
9996 .name = switch (extra.name) {
9997 .none => null,
9998 else => extra.name,
9999 },
10000 .size = extra.bitSize(),
10001 .@"align" = null,
10002 .encoding = @as(enum {
10003 DW_ATE_boolean,
10004 DW_ATE_unsigned,
10005 DW_ATE_signed,
10006 DW_ATE_float,
10007 }, switch (kind) {
10008 .basic_bool_type => .DW_ATE_boolean,
10009 .basic_unsigned_type => .DW_ATE_unsigned,
10010 .basic_signed_type => .DW_ATE_signed,
10011 .basic_float_type => .DW_ATE_float,
10012 else => unreachable,
10013 }),
10014 .flags = null,
10015 }, writer);
10016 },
10017 .composite_struct_type,
10018 .composite_union_type,
10019 .composite_enumeration_type,
10020 .composite_array_type,
10021 .composite_vector_type,
10022 => |kind| {
10023 const extra = self.metadataExtraData(Metadata.CompositeType, metadata_item.data);
10024 try metadata_formatter.specialized(.@"!", .DICompositeType, .{
10025 .tag = @as(enum {
10026 DW_TAG_structure_type,
10027 DW_TAG_union_type,
10028 DW_TAG_enumeration_type,
10029 DW_TAG_array_type,
10030 }, switch (kind) {
10031 .composite_struct_type => .DW_TAG_structure_type,
10032 .composite_union_type => .DW_TAG_union_type,
10033 .composite_enumeration_type => .DW_TAG_enumeration_type,
10034 .composite_array_type, .composite_vector_type => .DW_TAG_array_type,
10035 else => unreachable,
10036 }),
10037 .name = switch (extra.name) {
10038 .none => null,
10039 else => extra.name,
10040 },
10041 .scope = extra.scope,
10042 .file = null,
10043 .line = null,
10044 .baseType = extra.underlying_type,
10045 .size = extra.bitSize(),
10046 .@"align" = extra.bitAlign(),
10047 .offset = null,
10048 .flags = null,
10049 .elements = extra.fields_tuple,
10050 .runtimeLang = null,
10051 .vtableHolder = null,
10052 .templateParams = null,
10053 .identifier = null,
10054 .discriminator = null,
10055 .dataLocation = null,
10056 .associated = null,
10057 .allocated = null,
10058 .rank = null,
10059 .annotations = null,
10060 }, writer);
10061 },
10062 .derived_pointer_type,
10063 .derived_member_type,
10064 => |kind| {
10065 const extra = self.metadataExtraData(Metadata.DerivedType, metadata_item.data);
10066 try metadata_formatter.specialized(.@"!", .DIDerivedType, .{
10067 .tag = @as(enum {
10068 DW_TAG_pointer_type,
10069 DW_TAG_member,
10070 }, switch (kind) {
10071 .derived_pointer_type => .DW_TAG_pointer_type,
10072 .derived_member_type => .DW_TAG_member,
10073 else => unreachable,
10074 }),
10075 .name = switch (extra.name) {
10076 .none => null,
10077 else => extra.name,
10078 },
10079 .scope = extra.scope,
10080 .file = null,
10081 .line = null,
10082 .baseType = extra.underlying_type,
10083 .size = extra.bitSize(),
10084 .@"align" = extra.bitAlign(),
10085 .offset = switch (extra.bitOffset()) {
10086 0 => null,
10087 else => |bit_offset| bit_offset,
10088 },
10089 .flags = null,
10090 .extraData = null,
10091 .dwarfAddressSpace = null,
10092 .annotations = null,
10093 }, writer);
10094 },
10095 .subroutine_type => {
10096 const extra = self.metadataExtraData(Metadata.SubroutineType, metadata_item.data);
10097 try metadata_formatter.specialized(.@"!", .DISubroutineType, .{
10098 .flags = null,
10099 .cc = null,
10100 .types = extra.types_tuple,
10101 }, writer);
10102 },
10103 .enumerator_unsigned,
10104 .enumerator_signed_positive,
10105 .enumerator_signed_negative,
10106 => |kind| {
10107 const extra = self.metadataExtraData(Metadata.Enumerator, metadata_item.data);
10108
10109 const ExpectedContents = extern struct {
10110 string: [(64 * 8 / std.math.log2(10)) + 2]u8,
10111 limbs: [
10112 std.math.big.int.calcToStringLimbsBufferLen(
10113 64 / @sizeOf(std.math.big.Limb),
10114 10,
10115 )
10116 ]std.math.big.Limb,
10117 };
10118 var stack align(@alignOf(ExpectedContents)) =
10119 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
10120 const allocator = stack.get();
10121
10122 const limbs = self.metadata_limbs.items[extra.limbs_index..][0..extra.limbs_len];
10123 const bigint: std.math.big.int.Const = .{
10124 .limbs = limbs,
10125 .positive = switch (kind) {
10126 .enumerator_unsigned,
10127 .enumerator_signed_positive,
10128 => true,
10129 .enumerator_signed_negative => false,
10130 else => unreachable,
10131 },
10132 };
10133 const str = try bigint.toStringAlloc(allocator, 10, undefined);
10134 defer allocator.free(str);
10135
10136 try metadata_formatter.specialized(.@"!", .DIEnumerator, .{
10137 .name = extra.name,
10138 .value = str,
10139 .isUnsigned = switch (kind) {
10140 .enumerator_unsigned => true,
10141 .enumerator_signed_positive, .enumerator_signed_negative => false,
10142 else => unreachable,
10143 },
10144 }, writer);
10145 },
10146 .subrange => {
10147 const extra = self.metadataExtraData(Metadata.Subrange, metadata_item.data);
10148 try metadata_formatter.specialized(.@"!", .DISubrange, .{
10149 .count = extra.count,
10150 .lowerBound = extra.lower_bound,
10151 .upperBound = null,
10152 .stride = null,
10153 }, writer);
10154 },
10155 .tuple => {
10156 var extra = self.metadataExtraDataTrail(Metadata.Tuple, metadata_item.data);
10157 const elements = extra.trail.next(extra.data.elements_len, Metadata, self);
10158 try writer.writeAll("!{");
10159 for (elements) |element| try writer.print("{[element]%}", .{
10160 .element = try metadata_formatter.fmt("", element),
10161 });
10162 try writer.writeAll("}\n");
10163 },
10164 .module_flag => {
10165 const extra = self.metadataExtraData(Metadata.ModuleFlag, metadata_item.data);
10166 try writer.print("!{{{[behavior]%}{[name]%}{[constant]%}}}\n", .{
10167 .behavior = try metadata_formatter.fmt("", extra.behavior),
10168 .name = try metadata_formatter.fmt("", extra.name),
10169 .constant = try metadata_formatter.fmt("", extra.constant),
10170 });
10171 },
10172 .local_var => {
10173 const extra = self.metadataExtraData(Metadata.LocalVar, metadata_item.data);
10174 try metadata_formatter.specialized(.@"!", .DILocalVariable, .{
10175 .name = extra.name,
10176 .arg = null,
10177 .scope = extra.scope,
10178 .file = extra.file,
10179 .line = extra.line,
10180 .type = extra.ty,
10181 .flags = null,
10182 .@"align" = null,
10183 .annotations = null,
10184 }, writer);
10185 },
10186 .parameter => {
10187 const extra = self.metadataExtraData(Metadata.Parameter, metadata_item.data);
10188 try metadata_formatter.specialized(.@"!", .DILocalVariable, .{
10189 .name = extra.name,
10190 .arg = extra.arg_no,
10191 .scope = extra.scope,
10192 .file = extra.file,
10193 .line = extra.line,
10194 .type = extra.ty,
10195 .flags = null,
10196 .@"align" = null,
10197 .annotations = null,
10198 }, writer);
10199 },
10200 .global_var,
10201 .@"global_var local",
10202 => |kind| {
10203 const extra = self.metadataExtraData(Metadata.GlobalVar, metadata_item.data);
10204 try metadata_formatter.specialized(.@"distinct !", .DIGlobalVariable, .{
10205 .name = extra.name,
10206 .linkageName = extra.linkage_name,
10207 .scope = extra.scope,
10208 .file = extra.file,
10209 .line = extra.line,
10210 .type = extra.ty,
10211 .isLocal = switch (kind) {
10212 .global_var => false,
10213 .@"global_var local" => true,
10214 else => unreachable,
10215 },
10216 .isDefinition = true,
10217 .declaration = null,
10218 .templateParams = null,
10219 .@"align" = null,
10220 .annotations = null,
10221 }, writer);
10222 },
10223 .global_var_expression => {
10224 const extra =
10225 self.metadataExtraData(Metadata.GlobalVarExpression, metadata_item.data);
10226 try metadata_formatter.specialized(.@"!", .DIGlobalVariableExpression, .{
10227 .@"var" = extra.variable,
10228 .expr = extra.expression,
10229 }, writer);
10230 },
10231 }
10232 }
10233 }
992410234}
992510235
992610236const NoExtra = struct {};
......@@ -9954,10 +10264,9 @@ fn printEscapedString(
995410264}
995510265
995610266fn ensureUnusedGlobalCapacity(self: *Builder, name: String) Allocator.Error!void {
9957 if (self.useLibLlvm()) try self.llvm.globals.ensureUnusedCapacity(self.gpa, 1);
995810267 try self.string_map.ensureUnusedCapacity(self.gpa, 1);
995910268 if (name.slice(self)) |id| {
9960 const count: usize = comptime std.fmt.count("{d}" ++ .{0}, .{std.math.maxInt(u32)});
10269 const count: usize = comptime std.fmt.count("{d}", .{std.math.maxInt(u32)});
996110270 try self.string_bytes.ensureUnusedCapacity(self.gpa, id.len + count);
996210271 }
996310272 try self.string_indices.ensureUnusedCapacity(self.gpa, 1);
......@@ -9970,7 +10279,7 @@ fn fnTypeAssumeCapacity(
997010279 ret: Type,
997110280 params: []const Type,
997210281 comptime kind: Type.Function.Kind,
9973) (if (build_options.have_llvm) Allocator.Error else error{})!Type {
10282) Type {
997410283 const tag: Type.Tag = switch (kind) {
997510284 .normal => .function,
997610285 .vararg => .vararg_function,
......@@ -10007,20 +10316,6 @@ fn fnTypeAssumeCapacity(
1000710316 }),
1000810317 });
1000910318 self.type_extra.appendSliceAssumeCapacity(@ptrCast(params));
10010 if (self.useLibLlvm()) {
10011 const llvm_params = try self.gpa.alloc(*llvm.Type, params.len);
10012 defer self.gpa.free(llvm_params);
10013 for (llvm_params, params) |*llvm_param, param| llvm_param.* = param.toLlvm(self);
10014 self.llvm.types.appendAssumeCapacity(llvm.functionType(
10015 ret.toLlvm(self),
10016 llvm_params.ptr,
10017 @intCast(llvm_params.len),
10018 switch (kind) {
10019 .normal => .False,
10020 .vararg => .True,
10021 },
10022 ));
10023 }
1002410319 }
1002510320 return @enumFromInt(gop.index);
1002610321}
......@@ -10028,8 +10323,6 @@ fn fnTypeAssumeCapacity(
1002810323fn intTypeAssumeCapacity(self: *Builder, bits: u24) Type {
1002910324 assert(bits > 0);
1003010325 const result = self.getOrPutTypeNoExtraAssumeCapacity(.{ .tag = .integer, .data = bits });
10031 if (self.useLibLlvm() and result.new)
10032 self.llvm.types.appendAssumeCapacity(self.llvm.context.intType(bits));
1003310326 return result.type;
1003410327}
1003510328
......@@ -10037,8 +10330,6 @@ fn ptrTypeAssumeCapacity(self: *Builder, addr_space: AddrSpace) Type {
1003710330 const result = self.getOrPutTypeNoExtraAssumeCapacity(
1003810331 .{ .tag = .pointer, .data = @intFromEnum(addr_space) },
1003910332 );
10040 if (self.useLibLlvm() and result.new)
10041 self.llvm.types.appendAssumeCapacity(self.llvm.context.pointerType(@intFromEnum(addr_space)));
1004210333 return result.type;
1004310334}
1004410335
......@@ -10076,10 +10367,6 @@ fn vectorTypeAssumeCapacity(
1007610367 .tag = tag,
1007710368 .data = self.addTypeExtraAssumeCapacity(data),
1007810369 });
10079 if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(switch (kind) {
10080 .normal => &llvm.Type.vectorType,
10081 .scalable => &llvm.Type.scalableVectorType,
10082 }(child.toLlvm(self), @intCast(len)));
1008310370 }
1008410371 return @enumFromInt(gop.index);
1008510372}
......@@ -10109,9 +10396,6 @@ fn arrayTypeAssumeCapacity(self: *Builder, len: u64, child: Type) Type {
1010910396 .tag = .small_array,
1011010397 .data = self.addTypeExtraAssumeCapacity(data),
1011110398 });
10112 if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
10113 child.toLlvm(self).arrayType2(len),
10114 );
1011510399 }
1011610400 return @enumFromInt(gop.index);
1011710401 } else {
......@@ -10142,9 +10426,6 @@ fn arrayTypeAssumeCapacity(self: *Builder, len: u64, child: Type) Type {
1014210426 .tag = .array,
1014310427 .data = self.addTypeExtraAssumeCapacity(data),
1014410428 });
10145 if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
10146 child.toLlvm(self).arrayType2(len),
10147 );
1014810429 }
1014910430 return @enumFromInt(gop.index);
1015010431 }
......@@ -10154,7 +10435,7 @@ fn structTypeAssumeCapacity(
1015410435 self: *Builder,
1015510436 comptime kind: Type.Structure.Kind,
1015610437 fields: []const Type,
10157) (if (build_options.have_llvm) Allocator.Error else error{})!Type {
10438) Type {
1015810439 const tag: Type.Tag = switch (kind) {
1015910440 .normal => .structure,
1016010441 .@"packed" => .packed_structure,
......@@ -10186,25 +10467,6 @@ fn structTypeAssumeCapacity(
1018610467 }),
1018710468 });
1018810469 self.type_extra.appendSliceAssumeCapacity(@ptrCast(fields));
10189 if (self.useLibLlvm()) {
10190 const ExpectedContents = [expected_fields_len]*llvm.Type;
10191 var stack align(@alignOf(ExpectedContents)) =
10192 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
10193 const allocator = stack.get();
10194
10195 const llvm_fields = try allocator.alloc(*llvm.Type, fields.len);
10196 defer allocator.free(llvm_fields);
10197 for (llvm_fields, fields) |*llvm_field, field| llvm_field.* = field.toLlvm(self);
10198
10199 self.llvm.types.appendAssumeCapacity(self.llvm.context.structType(
10200 llvm_fields.ptr,
10201 @intCast(llvm_fields.len),
10202 switch (kind) {
10203 .normal => .False,
10204 .@"packed" => .True,
10205 },
10206 ));
10207 }
1020810470 }
1020910471 return @enumFromInt(gop.index);
1021010472}
......@@ -10246,9 +10508,6 @@ fn opaqueTypeAssumeCapacity(self: *Builder, name: String) Type {
1024610508 });
1024710509 const result: Type = @enumFromInt(gop.index);
1024810510 type_gop.value_ptr.* = result;
10249 if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
10250 self.llvm.context.structCreateNamed(id.slice(self) orelse ""),
10251 );
1025210511 return result;
1025310512 }
1025410513
......@@ -10271,7 +10530,6 @@ fn ensureUnusedTypeCapacity(
1027110530 self.gpa,
1027210531 count * (@typeInfo(Extra).Struct.fields.len + trail_len),
1027310532 );
10274 if (self.useLibLlvm()) try self.llvm.types.ensureUnusedCapacity(self.gpa, count);
1027510533}
1027610534
1027710535fn getOrPutTypeNoExtraAssumeCapacity(self: *Builder, item: Type.Item) struct { new: bool, type: Type } {
......@@ -10305,7 +10563,7 @@ fn addTypeExtraAssumeCapacity(self: *Builder, extra: anytype) Type.Item.ExtraInd
1030510563 self.type_extra.appendAssumeCapacity(switch (field.type) {
1030610564 u32 => value,
1030710565 String, Type => @intFromEnum(value),
10308 else => @compileError("bad field type: " ++ @typeName(field.type)),
10566 else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),
1030910567 });
1031010568 }
1031110569 return result;
......@@ -10388,10 +10646,7 @@ fn bigIntConstAssumeCapacity(
1038810646 assert(type_item.tag == .integer);
1038910647 const bits = type_item.data;
1039010648
10391 const ExpectedContents = extern struct {
10392 limbs: [64 / @sizeOf(std.math.big.Limb)]std.math.big.Limb,
10393 llvm_limbs: if (build_options.have_llvm) [64 / @sizeOf(u64)]u64 else void,
10394 };
10649 const ExpectedContents = [64 / @sizeOf(std.math.big.Limb)]std.math.big.Limb;
1039510650 var stack align(@alignOf(ExpectedContents)) =
1039610651 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
1039710652 const allocator = stack.get();
......@@ -10448,44 +10703,6 @@ fn bigIntConstAssumeCapacity(
1044810703 @ptrCast(self.constant_limbs.addManyAsArrayAssumeCapacity(Constant.Integer.limbs));
1044910704 extra.* = .{ .type = ty, .limbs_len = @intCast(canonical_value.limbs.len) };
1045010705 self.constant_limbs.appendSliceAssumeCapacity(canonical_value.limbs);
10451 if (self.useLibLlvm()) {
10452 const llvm_type = ty.toLlvm(self);
10453 if (canonical_value.to(c_longlong)) |small| {
10454 self.llvm.constants.appendAssumeCapacity(llvm_type.constInt(@bitCast(small), .True));
10455 } else |_| if (canonical_value.to(c_ulonglong)) |small| {
10456 self.llvm.constants.appendAssumeCapacity(llvm_type.constInt(small, .False));
10457 } else |_| {
10458 const llvm_limbs = try allocator.alloc(u64, std.math.divCeil(
10459 usize,
10460 if (canonical_value.positive) canonical_value.bitCountAbs() else bits,
10461 @bitSizeOf(u64),
10462 ) catch unreachable);
10463 defer allocator.free(llvm_limbs);
10464 var limb_index: usize = 0;
10465 var borrow: std.math.big.Limb = 0;
10466 for (llvm_limbs) |*result_limb| {
10467 var llvm_limb: u64 = 0;
10468 inline for (0..Constant.Integer.limbs) |shift| {
10469 const limb = if (limb_index < canonical_value.limbs.len)
10470 canonical_value.limbs[limb_index]
10471 else
10472 0;
10473 limb_index += 1;
10474 llvm_limb |= @as(u64, limb) << shift * @bitSizeOf(std.math.big.Limb);
10475 }
10476 if (!canonical_value.positive) {
10477 const overflow = @subWithOverflow(borrow, llvm_limb);
10478 llvm_limb = overflow[0];
10479 borrow -%= overflow[1];
10480 assert(borrow == 0 or borrow == std.math.maxInt(std.math.big.Limb));
10481 }
10482 result_limb.* = llvm_limb;
10483 }
10484 self.llvm.constants.appendAssumeCapacity(
10485 llvm_type.constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), llvm_limbs.ptr),
10486 );
10487 }
10488 }
1048910706 }
1049010707 return @enumFromInt(gop.index);
1049110708}
......@@ -10494,13 +10711,6 @@ fn halfConstAssumeCapacity(self: *Builder, val: f16) Constant {
1049410711 const result = self.getOrPutConstantNoExtraAssumeCapacity(
1049510712 .{ .tag = .half, .data = @as(u16, @bitCast(val)) },
1049610713 );
10497 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
10498 if (std.math.isSignalNan(val))
10499 Type.i16.toLlvm(self).constInt(@as(u16, @bitCast(val)), .False)
10500 .constBitCast(Type.half.toLlvm(self))
10501 else
10502 Type.half.toLlvm(self).constReal(val),
10503 );
1050410714 return result.constant;
1050510715}
1050610716
......@@ -10509,16 +10719,6 @@ fn bfloatConstAssumeCapacity(self: *Builder, val: f32) Constant {
1050910719 const result = self.getOrPutConstantNoExtraAssumeCapacity(
1051010720 .{ .tag = .bfloat, .data = @bitCast(val) },
1051110721 );
10512 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
10513 if (std.math.isSignalNan(val))
10514 Type.i16.toLlvm(self).constInt(@as(u32, @bitCast(val)) >> 16, .False)
10515 .constBitCast(Type.bfloat.toLlvm(self))
10516 else
10517 Type.bfloat.toLlvm(self).constReal(val),
10518 );
10519
10520 if (self.useLibLlvm() and result.new)
10521 self.llvm.constants.appendAssumeCapacity(Type.bfloat.toLlvm(self).constReal(val));
1052210722 return result.constant;
1052310723}
1052410724
......@@ -10526,13 +10726,6 @@ fn floatConstAssumeCapacity(self: *Builder, val: f32) Constant {
1052610726 const result = self.getOrPutConstantNoExtraAssumeCapacity(
1052710727 .{ .tag = .float, .data = @bitCast(val) },
1052810728 );
10529 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
10530 if (std.math.isSignalNan(val))
10531 Type.i32.toLlvm(self).constInt(@as(u32, @bitCast(val)), .False)
10532 .constBitCast(Type.float.toLlvm(self))
10533 else
10534 Type.float.toLlvm(self).constReal(val),
10535 );
1053610729 return result.constant;
1053710730}
1053810731
......@@ -10563,13 +10756,6 @@ fn doubleConstAssumeCapacity(self: *Builder, val: f64) Constant {
1056310756 .hi = @intCast(@as(u64, @bitCast(val)) >> 32),
1056410757 }),
1056510758 });
10566 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
10567 if (std.math.isSignalNan(val))
10568 Type.i64.toLlvm(self).constInt(@as(u64, @bitCast(val)), .False)
10569 .constBitCast(Type.double.toLlvm(self))
10570 else
10571 Type.double.toLlvm(self).constReal(val),
10572 );
1057310759 }
1057410760 return @enumFromInt(gop.index);
1057510761}
......@@ -10604,17 +10790,6 @@ fn fp128ConstAssumeCapacity(self: *Builder, val: f128) Constant {
1060410790 .hi_hi = @intCast(@as(u128, @bitCast(val)) >> 96),
1060510791 }),
1060610792 });
10607 if (self.useLibLlvm()) {
10608 const llvm_limbs = [_]u64{
10609 @truncate(@as(u128, @bitCast(val))),
10610 @intCast(@as(u128, @bitCast(val)) >> 64),
10611 };
10612 self.llvm.constants.appendAssumeCapacity(
10613 Type.i128.toLlvm(self)
10614 .constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), &llvm_limbs)
10615 .constBitCast(Type.fp128.toLlvm(self)),
10616 );
10617 }
1061810793 }
1061910794 return @enumFromInt(gop.index);
1062010795}
......@@ -10648,17 +10823,6 @@ fn x86_fp80ConstAssumeCapacity(self: *Builder, val: f80) Constant {
1064810823 .hi = @intCast(@as(u80, @bitCast(val)) >> 64),
1064910824 }),
1065010825 });
10651 if (self.useLibLlvm()) {
10652 const llvm_limbs = [_]u64{
10653 @truncate(@as(u80, @bitCast(val))),
10654 @intCast(@as(u80, @bitCast(val)) >> 64),
10655 };
10656 self.llvm.constants.appendAssumeCapacity(
10657 Type.i80.toLlvm(self)
10658 .constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), &llvm_limbs)
10659 .constBitCast(Type.x86_fp80.toLlvm(self)),
10660 );
10661 }
1066210826 }
1066310827 return @enumFromInt(gop.index);
1066410828}
......@@ -10693,14 +10857,6 @@ fn ppc_fp128ConstAssumeCapacity(self: *Builder, val: [2]f64) Constant {
1069310857 .hi_hi = @intCast(@as(u64, @bitCast(val[1])) >> 32),
1069410858 }),
1069510859 });
10696 if (self.useLibLlvm()) {
10697 const llvm_limbs: [2]u64 = @bitCast(val);
10698 self.llvm.constants.appendAssumeCapacity(
10699 Type.i128.toLlvm(self)
10700 .constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), &llvm_limbs)
10701 .constBitCast(Type.ppc_fp128.toLlvm(self)),
10702 );
10703 }
1070410860 }
1070510861 return @enumFromInt(gop.index);
1070610862}
......@@ -10710,8 +10866,6 @@ fn nullConstAssumeCapacity(self: *Builder, ty: Type) Constant {
1071010866 const result = self.getOrPutConstantNoExtraAssumeCapacity(
1071110867 .{ .tag = .null, .data = @intFromEnum(ty) },
1071210868 );
10713 if (self.useLibLlvm() and result.new)
10714 self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).constNull());
1071510869 return result.constant;
1071610870}
1071710871
......@@ -10720,16 +10874,10 @@ fn noneConstAssumeCapacity(self: *Builder, ty: Type) Constant {
1072010874 const result = self.getOrPutConstantNoExtraAssumeCapacity(
1072110875 .{ .tag = .none, .data = @intFromEnum(ty) },
1072210876 );
10723 if (self.useLibLlvm() and result.new)
10724 self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).constNull());
1072510877 return result.constant;
1072610878}
1072710879
10728fn structConstAssumeCapacity(
10729 self: *Builder,
10730 ty: Type,
10731 vals: []const Constant,
10732) (if (build_options.have_llvm) Allocator.Error else error{})!Constant {
10880fn structConstAssumeCapacity(self: *Builder, ty: Type, vals: []const Constant) Constant {
1073310881 const type_item = self.type_items.items[@intFromEnum(ty)];
1073410882 var extra = self.typeExtraDataTrail(Type.Structure, switch (type_item.tag) {
1073510883 .structure, .packed_structure => type_item.data,
......@@ -10756,28 +10904,10 @@ fn structConstAssumeCapacity(
1075610904 else => unreachable,
1075710905 };
1075810906 const result = self.getOrPutConstantAggregateAssumeCapacity(tag, ty, vals);
10759 if (self.useLibLlvm() and result.new) {
10760 const ExpectedContents = [expected_fields_len]*llvm.Value;
10761 var stack align(@alignOf(ExpectedContents)) =
10762 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
10763 const allocator = stack.get();
10764
10765 const llvm_vals = try allocator.alloc(*llvm.Value, vals.len);
10766 defer allocator.free(llvm_vals);
10767 for (llvm_vals, vals) |*llvm_val, val| llvm_val.* = val.toLlvm(self);
10768
10769 self.llvm.constants.appendAssumeCapacity(
10770 ty.toLlvm(self).constNamedStruct(llvm_vals.ptr, @intCast(llvm_vals.len)),
10771 );
10772 }
1077310907 return result.constant;
1077410908}
1077510909
10776fn arrayConstAssumeCapacity(
10777 self: *Builder,
10778 ty: Type,
10779 vals: []const Constant,
10780) (if (build_options.have_llvm) Allocator.Error else error{})!Constant {
10910fn arrayConstAssumeCapacity(self: *Builder, ty: Type, vals: []const Constant) Constant {
1078110911 const type_item = self.type_items.items[@intFromEnum(ty)];
1078210912 const type_extra: struct { len: u64, child: Type } = switch (type_item.tag) {
1078310913 inline .small_array, .array => |kind| extra: {
......@@ -10798,20 +10928,6 @@ fn arrayConstAssumeCapacity(
1079810928 } else return self.zeroInitConstAssumeCapacity(ty);
1079910929
1080010930 const result = self.getOrPutConstantAggregateAssumeCapacity(.array, ty, vals);
10801 if (self.useLibLlvm() and result.new) {
10802 const ExpectedContents = [expected_fields_len]*llvm.Value;
10803 var stack align(@alignOf(ExpectedContents)) =
10804 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
10805 const allocator = stack.get();
10806
10807 const llvm_vals = try allocator.alloc(*llvm.Value, vals.len);
10808 defer allocator.free(llvm_vals);
10809 for (llvm_vals, vals) |*llvm_val, val| llvm_val.* = val.toLlvm(self);
10810
10811 self.llvm.constants.appendAssumeCapacity(
10812 type_extra.child.toLlvm(self).constArray2(llvm_vals.ptr, llvm_vals.len),
10813 );
10814 }
1081510931 return result.constant;
1081610932}
1081710933
......@@ -10822,30 +10938,10 @@ fn stringConstAssumeCapacity(self: *Builder, val: String) Constant {
1082210938 const result = self.getOrPutConstantNoExtraAssumeCapacity(
1082310939 .{ .tag = .string, .data = @intFromEnum(val) },
1082410940 );
10825 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
10826 self.llvm.context.constString(slice.ptr, @intCast(slice.len), .True),
10827 );
10828 return result.constant;
10829}
10830
10831fn stringNullConstAssumeCapacity(self: *Builder, val: String) Constant {
10832 const slice = val.slice(self).?;
10833 const ty = self.arrayTypeAssumeCapacity(slice.len + 1, .i8);
10834 if (std.mem.allEqual(u8, slice, 0)) return self.zeroInitConstAssumeCapacity(ty);
10835 const result = self.getOrPutConstantNoExtraAssumeCapacity(
10836 .{ .tag = .string_null, .data = @intFromEnum(val) },
10837 );
10838 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
10839 self.llvm.context.constString(slice.ptr, @intCast(slice.len + 1), .True),
10840 );
1084110941 return result.constant;
1084210942}
1084310943
10844fn vectorConstAssumeCapacity(
10845 self: *Builder,
10846 ty: Type,
10847 vals: []const Constant,
10848) (if (build_options.have_llvm) Allocator.Error else error{})!Constant {
10944fn vectorConstAssumeCapacity(self: *Builder, ty: Type, vals: []const Constant) Constant {
1084910945 assert(ty.isVector(self));
1085010946 assert(ty.vectorLen(self) == vals.len);
1085110947 for (vals) |val| assert(ty.childType(self) == val.typeOf(self));
......@@ -10858,28 +10954,10 @@ fn vectorConstAssumeCapacity(
1085810954 } else return self.zeroInitConstAssumeCapacity(ty);
1085910955
1086010956 const result = self.getOrPutConstantAggregateAssumeCapacity(.vector, ty, vals);
10861 if (self.useLibLlvm() and result.new) {
10862 const ExpectedContents = [expected_fields_len]*llvm.Value;
10863 var stack align(@alignOf(ExpectedContents)) =
10864 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
10865 const allocator = stack.get();
10866
10867 const llvm_vals = try allocator.alloc(*llvm.Value, vals.len);
10868 defer allocator.free(llvm_vals);
10869 for (llvm_vals, vals) |*llvm_val, val| llvm_val.* = val.toLlvm(self);
10870
10871 self.llvm.constants.appendAssumeCapacity(
10872 llvm.constVector(llvm_vals.ptr, @intCast(llvm_vals.len)),
10873 );
10874 }
1087510957 return result.constant;
1087610958}
1087710959
10878fn splatConstAssumeCapacity(
10879 self: *Builder,
10880 ty: Type,
10881 val: Constant,
10882) (if (build_options.have_llvm) Allocator.Error else error{})!Constant {
10960fn splatConstAssumeCapacity(self: *Builder, ty: Type, val: Constant) Constant {
1088310961 assert(ty.scalarType(self) == val.typeOf(self));
1088410962
1088510963 if (!ty.isVector(self)) return val;
......@@ -10909,20 +10987,6 @@ fn splatConstAssumeCapacity(
1090910987 .tag = .splat,
1091010988 .data = self.addConstantExtraAssumeCapacity(data),
1091110989 });
10912 if (self.useLibLlvm()) {
10913 const ExpectedContents = [expected_fields_len]*llvm.Value;
10914 var stack align(@alignOf(ExpectedContents)) =
10915 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
10916 const allocator = stack.get();
10917
10918 const llvm_vals = try allocator.alloc(*llvm.Value, ty.vectorLen(self));
10919 defer allocator.free(llvm_vals);
10920 @memset(llvm_vals, val.toLlvm(self));
10921
10922 self.llvm.constants.appendAssumeCapacity(
10923 llvm.constVector(llvm_vals.ptr, @intCast(llvm_vals.len)),
10924 );
10925 }
1092610990 }
1092710991 return @enumFromInt(gop.index);
1092810992}
......@@ -10964,8 +11028,6 @@ fn zeroInitConstAssumeCapacity(self: *Builder, ty: Type) Constant {
1096411028 const result = self.getOrPutConstantNoExtraAssumeCapacity(
1096511029 .{ .tag = .zeroinitializer, .data = @intFromEnum(ty) },
1096611030 );
10967 if (self.useLibLlvm() and result.new)
10968 self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).constNull());
1096911031 return result.constant;
1097011032}
1097111033
......@@ -10981,8 +11043,6 @@ fn undefConstAssumeCapacity(self: *Builder, ty: Type) Constant {
1098111043 const result = self.getOrPutConstantNoExtraAssumeCapacity(
1098211044 .{ .tag = .undef, .data = @intFromEnum(ty) },
1098311045 );
10984 if (self.useLibLlvm() and result.new)
10985 self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).getUndef());
1098611046 return result.constant;
1098711047}
1098811048
......@@ -10998,8 +11058,6 @@ fn poisonConstAssumeCapacity(self: *Builder, ty: Type) Constant {
1099811058 const result = self.getOrPutConstantNoExtraAssumeCapacity(
1099911059 .{ .tag = .poison, .data = @intFromEnum(ty) },
1100011060 );
11001 if (self.useLibLlvm() and result.new)
11002 self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).getPoison());
1100311061 return result.constant;
1100411062}
1100511063
......@@ -11032,9 +11090,6 @@ fn blockAddrConstAssumeCapacity(
1103211090 .tag = .blockaddress,
1103311091 .data = self.addConstantExtraAssumeCapacity(data),
1103411092 });
11035 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
11036 function.toLlvm(self).blockAddress(block.toValue(self, function).toLlvm(self, function)),
11037 );
1103811093 }
1103911094 return @enumFromInt(gop.index);
1104011095}
......@@ -11043,7 +11098,6 @@ fn dsoLocalEquivalentConstAssumeCapacity(self: *Builder, function: Function.Inde
1104311098 const result = self.getOrPutConstantNoExtraAssumeCapacity(
1104411099 .{ .tag = .dso_local_equivalent, .data = @intFromEnum(function) },
1104511100 );
11046 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(undefined);
1104711101 return result.constant;
1104811102}
1104911103
......@@ -11051,7 +11105,6 @@ fn noCfiConstAssumeCapacity(self: *Builder, function: Function.Index) Constant {
1105111105 const result = self.getOrPutConstantNoExtraAssumeCapacity(
1105211106 .{ .tag = .no_cfi, .data = @intFromEnum(function) },
1105311107 );
11054 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(undefined);
1105511108 return result.constant;
1105611109}
1105711110
......@@ -11141,22 +11194,6 @@ fn castConstAssumeCapacity(self: *Builder, tag: Constant.Tag, val: Constant, ty:
1114111194 .tag = tag,
1114211195 .data = self.addConstantExtraAssumeCapacity(data.cast),
1114311196 });
11144 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(switch (tag) {
11145 .trunc => &llvm.Value.constTrunc,
11146 .zext => &llvm.Value.constZExt,
11147 .sext => &llvm.Value.constSExt,
11148 .fptrunc => &llvm.Value.constFPTrunc,
11149 .fpext => &llvm.Value.constFPExt,
11150 .fptoui => &llvm.Value.constFPToUI,
11151 .fptosi => &llvm.Value.constFPToSI,
11152 .uitofp => &llvm.Value.constUIToFP,
11153 .sitofp => &llvm.Value.constSIToFP,
11154 .ptrtoint => &llvm.Value.constPtrToInt,
11155 .inttoptr => &llvm.Value.constIntToPtr,
11156 .bitcast => &llvm.Value.constBitCast,
11157 .addrspacecast => &llvm.Value.constAddrSpaceCast,
11158 else => unreachable,
11159 }(val.toLlvm(self), ty.toLlvm(self)));
1116011197 }
1116111198 return @enumFromInt(gop.index);
1116211199}
......@@ -11168,7 +11205,7 @@ fn gepConstAssumeCapacity(
1116811205 base: Constant,
1116911206 inrange: ?u16,
1117011207 indices: []const Constant,
11171) (if (build_options.have_llvm) Allocator.Error else error{})!Constant {
11208) Constant {
1117211209 const tag: Constant.Tag = switch (kind) {
1117311210 .normal => .getelementptr,
1117411211 .inbounds => .@"getelementptr inbounds",
......@@ -11249,21 +11286,6 @@ fn gepConstAssumeCapacity(
1124911286 }),
1125011287 });
1125111288 self.constant_extra.appendSliceAssumeCapacity(@ptrCast(indices));
11252 if (self.useLibLlvm()) {
11253 const ExpectedContents = [expected_gep_indices_len]*llvm.Value;
11254 var stack align(@alignOf(ExpectedContents)) =
11255 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
11256 const allocator = stack.get();
11257
11258 const llvm_indices = try allocator.alloc(*llvm.Value, indices.len);
11259 defer allocator.free(llvm_indices);
11260 for (llvm_indices, indices) |*llvm_index, index| llvm_index.* = index.toLlvm(self);
11261
11262 self.llvm.constants.appendAssumeCapacity(switch (kind) {
11263 .normal => &llvm.Type.constGEP,
11264 .inbounds => &llvm.Type.constInBoundsGEP,
11265 }(ty.toLlvm(self), base.toLlvm(self), llvm_indices.ptr, @intCast(llvm_indices.len)));
11266 }
1126711289 }
1126811290 return @enumFromInt(gop.index);
1126911291}
......@@ -11298,9 +11320,6 @@ fn icmpConstAssumeCapacity(
1129811320 .tag = .icmp,
1129911321 .data = self.addConstantExtraAssumeCapacity(data),
1130011322 });
11301 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
11302 llvm.constICmp(cond.toLlvm(), lhs.toLlvm(self), rhs.toLlvm(self)),
11303 );
1130411323 }
1130511324 return @enumFromInt(gop.index);
1130611325}
......@@ -11335,9 +11354,6 @@ fn fcmpConstAssumeCapacity(
1133511354 .tag = .fcmp,
1133611355 .data = self.addConstantExtraAssumeCapacity(data),
1133711356 });
11338 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
11339 llvm.constFCmp(cond.toLlvm(), lhs.toLlvm(self), rhs.toLlvm(self)),
11340 );
1134111357 }
1134211358 return @enumFromInt(gop.index);
1134311359}
......@@ -11371,9 +11387,6 @@ fn extractElementConstAssumeCapacity(
1137111387 .tag = .extractelement,
1137211388 .data = self.addConstantExtraAssumeCapacity(data),
1137311389 });
11374 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
11375 val.toLlvm(self).constExtractElement(index.toLlvm(self)),
11376 );
1137711390 }
1137811391 return @enumFromInt(gop.index);
1137911392}
......@@ -11408,9 +11421,6 @@ fn insertElementConstAssumeCapacity(
1140811421 .tag = .insertelement,
1140911422 .data = self.addConstantExtraAssumeCapacity(data),
1141011423 });
11411 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
11412 val.toLlvm(self).constInsertElement(elem.toLlvm(self), index.toLlvm(self)),
11413 );
1141411424 }
1141511425 return @enumFromInt(gop.index);
1141611426}
......@@ -11449,9 +11459,6 @@ fn shuffleVectorConstAssumeCapacity(
1144911459 .tag = .shufflevector,
1145011460 .data = self.addConstantExtraAssumeCapacity(data),
1145111461 });
11452 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
11453 lhs.toLlvm(self).constShuffleVector(rhs.toLlvm(self), mask.toLlvm(self)),
11454 );
1145511462 }
1145611463 return @enumFromInt(gop.index);
1145711464}
......@@ -11506,18 +11513,6 @@ fn binConstAssumeCapacity(
1150611513 .tag = tag,
1150711514 .data = self.addConstantExtraAssumeCapacity(data.extra),
1150811515 });
11509 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(switch (tag) {
11510 .add => &llvm.Value.constAdd,
11511 .sub => &llvm.Value.constSub,
11512 .mul => &llvm.Value.constMul,
11513 .shl => &llvm.Value.constShl,
11514 .lshr => &llvm.Value.constLShr,
11515 .ashr => &llvm.Value.constAShr,
11516 .@"and" => &llvm.Value.constAnd,
11517 .@"or" => &llvm.Value.constOr,
11518 .xor => &llvm.Value.constXor,
11519 else => unreachable,
11520 }(lhs.toLlvm(self), rhs.toLlvm(self)));
1152111516 }
1152211517 return @enumFromInt(gop.index);
1152311518}
......@@ -11560,21 +11555,6 @@ fn asmConstAssumeCapacity(
1156011555 .tag = data.tag,
1156111556 .data = self.addConstantExtraAssumeCapacity(data.extra),
1156211557 });
11563 if (self.useLibLlvm()) {
11564 const assembly_slice = assembly.slice(self).?;
11565 const constraints_slice = constraints.slice(self).?;
11566 self.llvm.constants.appendAssumeCapacity(llvm.getInlineAsm(
11567 ty.toLlvm(self),
11568 assembly_slice.ptr,
11569 assembly_slice.len,
11570 constraints_slice.ptr,
11571 constraints_slice.len,
11572 llvm.Bool.fromBool(info.sideeffect),
11573 llvm.Bool.fromBool(info.alignstack),
11574 if (info.inteldialect) .Intel else .ATT,
11575 llvm.Bool.fromBool(info.unwind),
11576 ));
11577 }
1157811558 }
1157911559 return @enumFromInt(gop.index);
1158011560}
......@@ -11591,7 +11571,6 @@ fn ensureUnusedConstantCapacity(
1159111571 self.gpa,
1159211572 count * (@typeInfo(Extra).Struct.fields.len + trail_len),
1159311573 );
11594 if (self.useLibLlvm()) try self.llvm.constants.ensureUnusedCapacity(self.gpa, count);
1159511574}
1159611575
1159711576fn getOrPutConstantNoExtraAssumeCapacity(
......@@ -11722,15 +11701,3260 @@ fn constantExtraData(self: *const Builder, comptime T: type, index: Constant.Ite
1172211701 return self.constantExtraDataTrail(T, index).data;
1172311702}
1172411703
11725const assert = std.debug.assert;
11726const build_options = @import("build_options");
11727const builtin = @import("builtin");
11728const llvm = if (build_options.have_llvm)
11729 @import("bindings.zig")
11730else
11731 @compileError("LLVM unavailable");
11732const log = std.log.scoped(.llvm);
11733const std = @import("std");
11704fn ensureUnusedMetadataCapacity(
11705 self: *Builder,
11706 count: usize,
11707 comptime Extra: type,
11708 trail_len: usize,
11709) Allocator.Error!void {
11710 try self.metadata_map.ensureUnusedCapacity(self.gpa, count);
11711 try self.metadata_items.ensureUnusedCapacity(self.gpa, count);
11712 try self.metadata_extra.ensureUnusedCapacity(
11713 self.gpa,
11714 count * (@typeInfo(Extra).Struct.fields.len + trail_len),
11715 );
11716}
1173411717
11735const Allocator = std.mem.Allocator;
11736const Builder = @This();
11718fn addMetadataExtraAssumeCapacity(self: *Builder, extra: anytype) Metadata.Item.ExtraIndex {
11719 const result: Metadata.Item.ExtraIndex = @intCast(self.metadata_extra.items.len);
11720 inline for (@typeInfo(@TypeOf(extra)).Struct.fields) |field| {
11721 const value = @field(extra, field.name);
11722 self.metadata_extra.appendAssumeCapacity(switch (field.type) {
11723 u32 => value,
11724 MetadataString, Metadata, Variable.Index, Value => @intFromEnum(value),
11725 Metadata.DIFlags => @bitCast(value),
11726 else => @compileError("bad field type: " ++ @typeName(field.type)),
11727 });
11728 }
11729 return result;
11730}
11731
11732const MetadataExtraDataTrail = struct {
11733 index: Metadata.Item.ExtraIndex,
11734
11735 fn nextMut(self: *MetadataExtraDataTrail, len: u32, comptime Item: type, builder: *Builder) []Item {
11736 const items: []Item = @ptrCast(builder.metadata_extra.items[self.index..][0..len]);
11737 self.index += @intCast(len);
11738 return items;
11739 }
11740
11741 fn next(
11742 self: *MetadataExtraDataTrail,
11743 len: u32,
11744 comptime Item: type,
11745 builder: *const Builder,
11746 ) []const Item {
11747 const items: []const Item = @ptrCast(builder.metadata_extra.items[self.index..][0..len]);
11748 self.index += @intCast(len);
11749 return items;
11750 }
11751};
11752
11753fn metadataExtraDataTrail(
11754 self: *const Builder,
11755 comptime T: type,
11756 index: Metadata.Item.ExtraIndex,
11757) struct { data: T, trail: MetadataExtraDataTrail } {
11758 var result: T = undefined;
11759 const fields = @typeInfo(T).Struct.fields;
11760 inline for (fields, self.metadata_extra.items[index..][0..fields.len]) |field, value|
11761 @field(result, field.name) = switch (field.type) {
11762 u32 => value,
11763 MetadataString, Metadata, Variable.Index, Value => @enumFromInt(value),
11764 Metadata.DIFlags => @bitCast(value),
11765 else => @compileError("bad field type: " ++ @typeName(field.type)),
11766 };
11767 return .{
11768 .data = result,
11769 .trail = .{ .index = index + @as(Metadata.Item.ExtraIndex, @intCast(fields.len)) },
11770 };
11771}
11772
11773fn metadataExtraData(self: *const Builder, comptime T: type, index: Metadata.Item.ExtraIndex) T {
11774 return self.metadataExtraDataTrail(T, index).data;
11775}
11776
11777pub fn metadataString(self: *Builder, bytes: []const u8) Allocator.Error!MetadataString {
11778 try self.metadata_string_bytes.ensureUnusedCapacity(self.gpa, bytes.len);
11779 try self.metadata_string_indices.ensureUnusedCapacity(self.gpa, 1);
11780 try self.metadata_string_map.ensureUnusedCapacity(self.gpa, 1);
11781
11782 const gop = self.metadata_string_map.getOrPutAssumeCapacityAdapted(
11783 bytes,
11784 MetadataString.Adapter{ .builder = self },
11785 );
11786 if (!gop.found_existing) {
11787 self.metadata_string_bytes.appendSliceAssumeCapacity(bytes);
11788 self.metadata_string_indices.appendAssumeCapacity(@intCast(self.metadata_string_bytes.items.len));
11789 }
11790 return @enumFromInt(gop.index);
11791}
11792
11793pub fn metadataStringFromString(self: *Builder, str: String) Allocator.Error!MetadataString {
11794 if (str == .none or str == .empty) return MetadataString.none;
11795 return try self.metadataString(str.slice(self).?);
11796}
11797
11798pub fn metadataStringFmt(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) Allocator.Error!MetadataString {
11799 try self.metadata_string_map.ensureUnusedCapacity(self.gpa, 1);
11800 try self.metadata_string_bytes.ensureUnusedCapacity(self.gpa, @intCast(std.fmt.count(fmt_str, fmt_args)));
11801 try self.metadata_string_indices.ensureUnusedCapacity(self.gpa, 1);
11802 return self.metadataStringFmtAssumeCapacity(fmt_str, fmt_args);
11803}
11804
11805pub fn metadataStringFmtAssumeCapacity(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) MetadataString {
11806 self.metadata_string_bytes.writer(undefined).print(fmt_str, fmt_args) catch unreachable;
11807 return self.trailingMetadataStringAssumeCapacity();
11808}
11809
11810pub fn trailingMetadataString(self: *Builder) Allocator.Error!MetadataString {
11811 try self.metadata_string_indices.ensureUnusedCapacity(self.gpa, 1);
11812 try self.metadata_string_map.ensureUnusedCapacity(self.gpa, 1);
11813 return self.trailingMetadataStringAssumeCapacity();
11814}
11815
11816pub fn trailingMetadataStringAssumeCapacity(self: *Builder) MetadataString {
11817 const start = self.metadata_string_indices.getLast();
11818 const bytes: []const u8 = self.metadata_string_bytes.items[start..];
11819 const gop = self.metadata_string_map.getOrPutAssumeCapacityAdapted(bytes, String.Adapter{ .builder = self });
11820 if (gop.found_existing) {
11821 self.metadata_string_bytes.shrinkRetainingCapacity(start);
11822 } else {
11823 self.metadata_string_indices.appendAssumeCapacity(@intCast(self.metadata_string_bytes.items.len));
11824 }
11825 return @enumFromInt(gop.index);
11826}
11827
11828pub fn debugNamed(self: *Builder, name: MetadataString, operands: []const Metadata) Allocator.Error!void {
11829 try self.metadata_extra.ensureUnusedCapacity(self.gpa, operands.len);
11830 try self.metadata_named.ensureUnusedCapacity(self.gpa, 1);
11831 self.debugNamedAssumeCapacity(name, operands);
11832}
11833
11834fn debugNone(self: *Builder) Allocator.Error!Metadata {
11835 try self.ensureUnusedMetadataCapacity(1, NoExtra, 0);
11836 return self.debugNoneAssumeCapacity();
11837}
11838
11839pub fn debugFile(
11840 self: *Builder,
11841 filename: MetadataString,
11842 directory: MetadataString,
11843) Allocator.Error!Metadata {
11844 try self.ensureUnusedMetadataCapacity(1, Metadata.File, 0);
11845 return self.debugFileAssumeCapacity(filename, directory);
11846}
11847
11848pub fn debugCompileUnit(
11849 self: *Builder,
11850 file: Metadata,
11851 producer: MetadataString,
11852 enums: Metadata,
11853 globals: Metadata,
11854 options: Metadata.CompileUnit.Options,
11855) Allocator.Error!Metadata {
11856 try self.ensureUnusedMetadataCapacity(1, Metadata.CompileUnit, 0);
11857 return self.debugCompileUnitAssumeCapacity(file, producer, enums, globals, options);
11858}
11859
11860pub fn debugSubprogram(
11861 self: *Builder,
11862 file: Metadata,
11863 name: MetadataString,
11864 linkage_name: MetadataString,
11865 line: u32,
11866 scope_line: u32,
11867 ty: Metadata,
11868 options: Metadata.Subprogram.Options,
11869 compile_unit: Metadata,
11870) Allocator.Error!Metadata {
11871 try self.ensureUnusedMetadataCapacity(1, Metadata.Subprogram, 0);
11872 return self.debugSubprogramAssumeCapacity(
11873 file,
11874 name,
11875 linkage_name,
11876 line,
11877 scope_line,
11878 ty,
11879 options,
11880 compile_unit,
11881 );
11882}
11883
11884pub fn debugLexicalBlock(self: *Builder, scope: Metadata, file: Metadata, line: u32, column: u32) Allocator.Error!Metadata {
11885 try self.ensureUnusedMetadataCapacity(1, Metadata.LexicalBlock, 0);
11886 return self.debugLexicalBlockAssumeCapacity(scope, file, line, column);
11887}
11888
11889pub fn debugLocation(self: *Builder, line: u32, column: u32, scope: Metadata, inlined_at: Metadata) Allocator.Error!Metadata {
11890 try self.ensureUnusedMetadataCapacity(1, Metadata.Location, 0);
11891 return self.debugLocationAssumeCapacity(line, column, scope, inlined_at);
11892}
11893
11894pub fn debugBoolType(self: *Builder, name: MetadataString, size_in_bits: u64) Allocator.Error!Metadata {
11895 try self.ensureUnusedMetadataCapacity(1, Metadata.BasicType, 0);
11896 return self.debugBoolTypeAssumeCapacity(name, size_in_bits);
11897}
11898
11899pub fn debugUnsignedType(self: *Builder, name: MetadataString, size_in_bits: u64) Allocator.Error!Metadata {
11900 try self.ensureUnusedMetadataCapacity(1, Metadata.BasicType, 0);
11901 return self.debugUnsignedTypeAssumeCapacity(name, size_in_bits);
11902}
11903
11904pub fn debugSignedType(self: *Builder, name: MetadataString, size_in_bits: u64) Allocator.Error!Metadata {
11905 try self.ensureUnusedMetadataCapacity(1, Metadata.BasicType, 0);
11906 return self.debugSignedTypeAssumeCapacity(name, size_in_bits);
11907}
11908
11909pub fn debugFloatType(self: *Builder, name: MetadataString, size_in_bits: u64) Allocator.Error!Metadata {
11910 try self.ensureUnusedMetadataCapacity(1, Metadata.BasicType, 0);
11911 return self.debugFloatTypeAssumeCapacity(name, size_in_bits);
11912}
11913
11914pub fn debugForwardReference(self: *Builder) Allocator.Error!Metadata {
11915 try self.metadata_forward_references.ensureUnusedCapacity(self.gpa, 1);
11916 return self.debugForwardReferenceAssumeCapacity();
11917}
11918
11919pub fn debugStructType(
11920 self: *Builder,
11921 name: MetadataString,
11922 file: Metadata,
11923 scope: Metadata,
11924 line: u32,
11925 underlying_type: Metadata,
11926 size_in_bits: u64,
11927 align_in_bits: u64,
11928 fields_tuple: Metadata,
11929) Allocator.Error!Metadata {
11930 try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0);
11931 return self.debugStructTypeAssumeCapacity(
11932 name,
11933 file,
11934 scope,
11935 line,
11936 underlying_type,
11937 size_in_bits,
11938 align_in_bits,
11939 fields_tuple,
11940 );
11941}
11942
11943pub fn debugUnionType(
11944 self: *Builder,
11945 name: MetadataString,
11946 file: Metadata,
11947 scope: Metadata,
11948 line: u32,
11949 underlying_type: Metadata,
11950 size_in_bits: u64,
11951 align_in_bits: u64,
11952 fields_tuple: Metadata,
11953) Allocator.Error!Metadata {
11954 try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0);
11955 return self.debugUnionTypeAssumeCapacity(
11956 name,
11957 file,
11958 scope,
11959 line,
11960 underlying_type,
11961 size_in_bits,
11962 align_in_bits,
11963 fields_tuple,
11964 );
11965}
11966
11967pub fn debugEnumerationType(
11968 self: *Builder,
11969 name: MetadataString,
11970 file: Metadata,
11971 scope: Metadata,
11972 line: u32,
11973 underlying_type: Metadata,
11974 size_in_bits: u64,
11975 align_in_bits: u64,
11976 fields_tuple: Metadata,
11977) Allocator.Error!Metadata {
11978 try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0);
11979 return self.debugEnumerationTypeAssumeCapacity(
11980 name,
11981 file,
11982 scope,
11983 line,
11984 underlying_type,
11985 size_in_bits,
11986 align_in_bits,
11987 fields_tuple,
11988 );
11989}
11990
11991pub fn debugArrayType(
11992 self: *Builder,
11993 name: MetadataString,
11994 file: Metadata,
11995 scope: Metadata,
11996 line: u32,
11997 underlying_type: Metadata,
11998 size_in_bits: u64,
11999 align_in_bits: u64,
12000 fields_tuple: Metadata,
12001) Allocator.Error!Metadata {
12002 try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0);
12003 return self.debugArrayTypeAssumeCapacity(
12004 name,
12005 file,
12006 scope,
12007 line,
12008 underlying_type,
12009 size_in_bits,
12010 align_in_bits,
12011 fields_tuple,
12012 );
12013}
12014
12015pub fn debugVectorType(
12016 self: *Builder,
12017 name: MetadataString,
12018 file: Metadata,
12019 scope: Metadata,
12020 line: u32,
12021 underlying_type: Metadata,
12022 size_in_bits: u64,
12023 align_in_bits: u64,
12024 fields_tuple: Metadata,
12025) Allocator.Error!Metadata {
12026 try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0);
12027 return self.debugVectorTypeAssumeCapacity(
12028 name,
12029 file,
12030 scope,
12031 line,
12032 underlying_type,
12033 size_in_bits,
12034 align_in_bits,
12035 fields_tuple,
12036 );
12037}
12038
12039pub fn debugPointerType(
12040 self: *Builder,
12041 name: MetadataString,
12042 file: Metadata,
12043 scope: Metadata,
12044 line: u32,
12045 underlying_type: Metadata,
12046 size_in_bits: u64,
12047 align_in_bits: u64,
12048 offset_in_bits: u64,
12049) Allocator.Error!Metadata {
12050 try self.ensureUnusedMetadataCapacity(1, Metadata.DerivedType, 0);
12051 return self.debugPointerTypeAssumeCapacity(
12052 name,
12053 file,
12054 scope,
12055 line,
12056 underlying_type,
12057 size_in_bits,
12058 align_in_bits,
12059 offset_in_bits,
12060 );
12061}
12062
12063pub fn debugMemberType(
12064 self: *Builder,
12065 name: MetadataString,
12066 file: Metadata,
12067 scope: Metadata,
12068 line: u32,
12069 underlying_type: Metadata,
12070 size_in_bits: u64,
12071 align_in_bits: u64,
12072 offset_in_bits: u64,
12073) Allocator.Error!Metadata {
12074 try self.ensureUnusedMetadataCapacity(1, Metadata.DerivedType, 0);
12075 return self.debugMemberTypeAssumeCapacity(
12076 name,
12077 file,
12078 scope,
12079 line,
12080 underlying_type,
12081 size_in_bits,
12082 align_in_bits,
12083 offset_in_bits,
12084 );
12085}
12086
12087pub fn debugSubroutineType(
12088 self: *Builder,
12089 types_tuple: Metadata,
12090) Allocator.Error!Metadata {
12091 try self.ensureUnusedMetadataCapacity(1, Metadata.SubroutineType, 0);
12092 return self.debugSubroutineTypeAssumeCapacity(types_tuple);
12093}
12094
12095pub fn debugEnumerator(
12096 self: *Builder,
12097 name: MetadataString,
12098 unsigned: bool,
12099 bit_width: u32,
12100 value: std.math.big.int.Const,
12101) Allocator.Error!Metadata {
12102 assert(!(unsigned and !value.positive));
12103 try self.ensureUnusedMetadataCapacity(1, Metadata.Enumerator, 0);
12104 try self.metadata_limbs.ensureUnusedCapacity(self.gpa, value.limbs.len);
12105 return self.debugEnumeratorAssumeCapacity(name, unsigned, bit_width, value);
12106}
12107
12108pub fn debugSubrange(
12109 self: *Builder,
12110 lower_bound: Metadata,
12111 count: Metadata,
12112) Allocator.Error!Metadata {
12113 try self.ensureUnusedMetadataCapacity(1, Metadata.Subrange, 0);
12114 return self.debugSubrangeAssumeCapacity(lower_bound, count);
12115}
12116
12117pub fn debugExpression(
12118 self: *Builder,
12119 elements: []const u32,
12120) Allocator.Error!Metadata {
12121 try self.ensureUnusedMetadataCapacity(1, Metadata.Expression, elements.len * @sizeOf(u32));
12122 return self.debugExpressionAssumeCapacity(elements);
12123}
12124
12125pub fn debugTuple(
12126 self: *Builder,
12127 elements: []const Metadata,
12128) Allocator.Error!Metadata {
12129 try self.ensureUnusedMetadataCapacity(1, Metadata.Tuple, elements.len * @sizeOf(Metadata));
12130 return self.debugTupleAssumeCapacity(elements);
12131}
12132
12133pub fn debugModuleFlag(
12134 self: *Builder,
12135 behavior: Metadata,
12136 name: MetadataString,
12137 constant: Metadata,
12138) Allocator.Error!Metadata {
12139 try self.ensureUnusedMetadataCapacity(1, Metadata.ModuleFlag, 0);
12140 return self.debugModuleFlagAssumeCapacity(behavior, name, constant);
12141}
12142
12143pub fn debugLocalVar(
12144 self: *Builder,
12145 name: MetadataString,
12146 file: Metadata,
12147 scope: Metadata,
12148 line: u32,
12149 ty: Metadata,
12150) Allocator.Error!Metadata {
12151 try self.ensureUnusedMetadataCapacity(1, Metadata.LocalVar, 0);
12152 return self.debugLocalVarAssumeCapacity(name, file, scope, line, ty);
12153}
12154
12155pub fn debugParameter(
12156 self: *Builder,
12157 name: MetadataString,
12158 file: Metadata,
12159 scope: Metadata,
12160 line: u32,
12161 ty: Metadata,
12162 arg_no: u32,
12163) Allocator.Error!Metadata {
12164 try self.ensureUnusedMetadataCapacity(1, Metadata.Parameter, 0);
12165 return self.debugParameterAssumeCapacity(name, file, scope, line, ty, arg_no);
12166}
12167
12168pub fn debugGlobalVar(
12169 self: *Builder,
12170 name: MetadataString,
12171 linkage_name: MetadataString,
12172 file: Metadata,
12173 scope: Metadata,
12174 line: u32,
12175 ty: Metadata,
12176 variable: Variable.Index,
12177 options: Metadata.GlobalVar.Options,
12178) Allocator.Error!Metadata {
12179 try self.ensureUnusedMetadataCapacity(1, Metadata.GlobalVar, 0);
12180 return self.debugGlobalVarAssumeCapacity(
12181 name,
12182 linkage_name,
12183 file,
12184 scope,
12185 line,
12186 ty,
12187 variable,
12188 options,
12189 );
12190}
12191
12192pub fn debugGlobalVarExpression(
12193 self: *Builder,
12194 variable: Metadata,
12195 expression: Metadata,
12196) Allocator.Error!Metadata {
12197 try self.ensureUnusedMetadataCapacity(1, Metadata.GlobalVarExpression, 0);
12198 return self.debugGlobalVarExpressionAssumeCapacity(variable, expression);
12199}
12200
12201pub fn debugConstant(self: *Builder, value: Constant) Allocator.Error!Metadata {
12202 try self.ensureUnusedMetadataCapacity(1, NoExtra, 0);
12203 return self.debugConstantAssumeCapacity(value);
12204}
12205
12206pub fn debugForwardReferenceSetType(self: *Builder, fwd_ref: Metadata, ty: Metadata) void {
12207 assert(
12208 @intFromEnum(fwd_ref) >= Metadata.first_forward_reference and
12209 @intFromEnum(fwd_ref) <= Metadata.first_local_metadata,
12210 );
12211 const index = @intFromEnum(fwd_ref) - Metadata.first_forward_reference;
12212 self.metadata_forward_references.items[index] = ty;
12213}
12214
12215fn metadataSimpleAssumeCapacity(self: *Builder, tag: Metadata.Tag, value: anytype) Metadata {
12216 const Key = struct {
12217 tag: Metadata.Tag,
12218 value: @TypeOf(value),
12219 };
12220 const Adapter = struct {
12221 builder: *const Builder,
12222 pub fn hash(_: @This(), key: Key) u32 {
12223 var hasher = std.hash.Wyhash.init(std.hash.uint32(@intFromEnum(key.tag)));
12224 inline for (std.meta.fields(@TypeOf(value))) |field| {
12225 hasher.update(std.mem.asBytes(&@field(key.value, field.name)));
12226 }
12227 return @truncate(hasher.final());
12228 }
12229
12230 pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool {
12231 if (lhs_key.tag != ctx.builder.metadata_items.items(.tag)[rhs_index]) return false;
12232 const rhs_data = ctx.builder.metadata_items.items(.data)[rhs_index];
12233 const rhs_extra = ctx.builder.metadataExtraData(@TypeOf(value), rhs_data);
12234 return std.meta.eql(lhs_key.value, rhs_extra);
12235 }
12236 };
12237
12238 const gop = self.metadata_map.getOrPutAssumeCapacityAdapted(
12239 Key{ .tag = tag, .value = value },
12240 Adapter{ .builder = self },
12241 );
12242
12243 if (!gop.found_existing) {
12244 gop.key_ptr.* = {};
12245 gop.value_ptr.* = {};
12246 self.metadata_items.appendAssumeCapacity(.{
12247 .tag = tag,
12248 .data = self.addMetadataExtraAssumeCapacity(value),
12249 });
12250 }
12251 return @enumFromInt(gop.index);
12252}
12253
12254fn metadataDistinctAssumeCapacity(self: *Builder, tag: Metadata.Tag, value: anytype) Metadata {
12255 const Key = struct { tag: Metadata.Tag, index: Metadata };
12256 const Adapter = struct {
12257 pub fn hash(_: @This(), key: Key) u32 {
12258 return @truncate(std.hash.Wyhash.hash(
12259 std.hash.uint32(@intFromEnum(key.tag)),
12260 std.mem.asBytes(&key.index),
12261 ));
12262 }
12263
12264 pub fn eql(_: @This(), lhs_key: Key, _: void, rhs_index: usize) bool {
12265 return @intFromEnum(lhs_key.index) == rhs_index;
12266 }
12267 };
12268
12269 const gop = self.metadata_map.getOrPutAssumeCapacityAdapted(
12270 Key{ .tag = tag, .index = @enumFromInt(self.metadata_map.count()) },
12271 Adapter{},
12272 );
12273
12274 if (!gop.found_existing) {
12275 gop.key_ptr.* = {};
12276 gop.value_ptr.* = {};
12277 self.metadata_items.appendAssumeCapacity(.{
12278 .tag = tag,
12279 .data = self.addMetadataExtraAssumeCapacity(value),
12280 });
12281 }
12282 return @enumFromInt(gop.index);
12283}
12284
12285fn debugNamedAssumeCapacity(self: *Builder, name: MetadataString, operands: []const Metadata) void {
12286 assert(!self.strip);
12287 assert(name != .none);
12288 const extra_index: u32 = @intCast(self.metadata_extra.items.len);
12289 self.metadata_extra.appendSliceAssumeCapacity(@ptrCast(operands));
12290
12291 const gop = self.metadata_named.getOrPutAssumeCapacity(name);
12292 gop.value_ptr.* = .{
12293 .index = extra_index,
12294 .len = @intCast(operands.len),
12295 };
12296}
12297
12298pub fn debugNoneAssumeCapacity(self: *Builder) Metadata {
12299 assert(!self.strip);
12300 return self.metadataSimpleAssumeCapacity(.none, .{});
12301}
12302
12303fn debugFileAssumeCapacity(
12304 self: *Builder,
12305 filename: MetadataString,
12306 directory: MetadataString,
12307) Metadata {
12308 assert(!self.strip);
12309 return self.metadataSimpleAssumeCapacity(.file, Metadata.File{
12310 .filename = filename,
12311 .directory = directory,
12312 });
12313}
12314
12315pub fn debugCompileUnitAssumeCapacity(
12316 self: *Builder,
12317 file: Metadata,
12318 producer: MetadataString,
12319 enums: Metadata,
12320 globals: Metadata,
12321 options: Metadata.CompileUnit.Options,
12322) Metadata {
12323 assert(!self.strip);
12324 return self.metadataDistinctAssumeCapacity(
12325 if (options.optimized) .@"compile_unit optimized" else .compile_unit,
12326 Metadata.CompileUnit{
12327 .file = file,
12328 .producer = producer,
12329 .enums = enums,
12330 .globals = globals,
12331 },
12332 );
12333}
12334
12335fn debugSubprogramAssumeCapacity(
12336 self: *Builder,
12337 file: Metadata,
12338 name: MetadataString,
12339 linkage_name: MetadataString,
12340 line: u32,
12341 scope_line: u32,
12342 ty: Metadata,
12343 options: Metadata.Subprogram.Options,
12344 compile_unit: Metadata,
12345) Metadata {
12346 assert(!self.strip);
12347 const tag: Metadata.Tag = @enumFromInt(@intFromEnum(Metadata.Tag.subprogram) +
12348 @as(u3, @truncate(@as(u32, @bitCast(options.sp_flags)) >> 2)));
12349 return self.metadataDistinctAssumeCapacity(tag, Metadata.Subprogram{
12350 .file = file,
12351 .name = name,
12352 .linkage_name = linkage_name,
12353 .line = line,
12354 .scope_line = scope_line,
12355 .ty = ty,
12356 .di_flags = options.di_flags,
12357 .compile_unit = compile_unit,
12358 });
12359}
12360
12361fn debugLexicalBlockAssumeCapacity(self: *Builder, scope: Metadata, file: Metadata, line: u32, column: u32) Metadata {
12362 assert(!self.strip);
12363 return self.metadataSimpleAssumeCapacity(.lexical_block, Metadata.LexicalBlock{
12364 .scope = scope,
12365 .file = file,
12366 .line = line,
12367 .column = column,
12368 });
12369}
12370
12371fn debugLocationAssumeCapacity(self: *Builder, line: u32, column: u32, scope: Metadata, inlined_at: Metadata) Metadata {
12372 assert(!self.strip);
12373 return self.metadataSimpleAssumeCapacity(.location, Metadata.Location{
12374 .line = line,
12375 .column = column,
12376 .scope = scope,
12377 .inlined_at = inlined_at,
12378 });
12379}
12380
12381fn debugBoolTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bits: u64) Metadata {
12382 assert(!self.strip);
12383 return self.metadataSimpleAssumeCapacity(.basic_bool_type, Metadata.BasicType{
12384 .name = name,
12385 .size_in_bits_lo = @truncate(size_in_bits),
12386 .size_in_bits_hi = @truncate(size_in_bits >> 32),
12387 });
12388}
12389
12390fn debugUnsignedTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bits: u64) Metadata {
12391 assert(!self.strip);
12392 return self.metadataSimpleAssumeCapacity(.basic_unsigned_type, Metadata.BasicType{
12393 .name = name,
12394 .size_in_bits_lo = @truncate(size_in_bits),
12395 .size_in_bits_hi = @truncate(size_in_bits >> 32),
12396 });
12397}
12398
12399fn debugSignedTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bits: u64) Metadata {
12400 assert(!self.strip);
12401 return self.metadataSimpleAssumeCapacity(.basic_signed_type, Metadata.BasicType{
12402 .name = name,
12403 .size_in_bits_lo = @truncate(size_in_bits),
12404 .size_in_bits_hi = @truncate(size_in_bits >> 32),
12405 });
12406}
12407
12408fn debugFloatTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bits: u64) Metadata {
12409 assert(!self.strip);
12410 return self.metadataSimpleAssumeCapacity(.basic_float_type, Metadata.BasicType{
12411 .name = name,
12412 .size_in_bits_lo = @truncate(size_in_bits),
12413 .size_in_bits_hi = @truncate(size_in_bits >> 32),
12414 });
12415}
12416
12417fn debugForwardReferenceAssumeCapacity(self: *Builder) Metadata {
12418 assert(!self.strip);
12419 const index = Metadata.first_forward_reference + self.metadata_forward_references.items.len;
12420 self.metadata_forward_references.appendAssumeCapacity(.none);
12421 return @enumFromInt(index);
12422}
12423
12424fn debugStructTypeAssumeCapacity(
12425 self: *Builder,
12426 name: MetadataString,
12427 file: Metadata,
12428 scope: Metadata,
12429 line: u32,
12430 underlying_type: Metadata,
12431 size_in_bits: u64,
12432 align_in_bits: u64,
12433 fields_tuple: Metadata,
12434) Metadata {
12435 assert(!self.strip);
12436 return self.debugCompositeTypeAssumeCapacity(
12437 .composite_struct_type,
12438 name,
12439 file,
12440 scope,
12441 line,
12442 underlying_type,
12443 size_in_bits,
12444 align_in_bits,
12445 fields_tuple,
12446 );
12447}
12448
12449fn debugUnionTypeAssumeCapacity(
12450 self: *Builder,
12451 name: MetadataString,
12452 file: Metadata,
12453 scope: Metadata,
12454 line: u32,
12455 underlying_type: Metadata,
12456 size_in_bits: u64,
12457 align_in_bits: u64,
12458 fields_tuple: Metadata,
12459) Metadata {
12460 assert(!self.strip);
12461 return self.debugCompositeTypeAssumeCapacity(
12462 .composite_union_type,
12463 name,
12464 file,
12465 scope,
12466 line,
12467 underlying_type,
12468 size_in_bits,
12469 align_in_bits,
12470 fields_tuple,
12471 );
12472}
12473
12474fn debugEnumerationTypeAssumeCapacity(
12475 self: *Builder,
12476 name: MetadataString,
12477 file: Metadata,
12478 scope: Metadata,
12479 line: u32,
12480 underlying_type: Metadata,
12481 size_in_bits: u64,
12482 align_in_bits: u64,
12483 fields_tuple: Metadata,
12484) Metadata {
12485 assert(!self.strip);
12486 return self.debugCompositeTypeAssumeCapacity(
12487 .composite_enumeration_type,
12488 name,
12489 file,
12490 scope,
12491 line,
12492 underlying_type,
12493 size_in_bits,
12494 align_in_bits,
12495 fields_tuple,
12496 );
12497}
12498
12499fn debugArrayTypeAssumeCapacity(
12500 self: *Builder,
12501 name: MetadataString,
12502 file: Metadata,
12503 scope: Metadata,
12504 line: u32,
12505 underlying_type: Metadata,
12506 size_in_bits: u64,
12507 align_in_bits: u64,
12508 fields_tuple: Metadata,
12509) Metadata {
12510 assert(!self.strip);
12511 return self.debugCompositeTypeAssumeCapacity(
12512 .composite_array_type,
12513 name,
12514 file,
12515 scope,
12516 line,
12517 underlying_type,
12518 size_in_bits,
12519 align_in_bits,
12520 fields_tuple,
12521 );
12522}
12523
12524fn debugVectorTypeAssumeCapacity(
12525 self: *Builder,
12526 name: MetadataString,
12527 file: Metadata,
12528 scope: Metadata,
12529 line: u32,
12530 underlying_type: Metadata,
12531 size_in_bits: u64,
12532 align_in_bits: u64,
12533 fields_tuple: Metadata,
12534) Metadata {
12535 assert(!self.strip);
12536 return self.debugCompositeTypeAssumeCapacity(
12537 .composite_vector_type,
12538 name,
12539 file,
12540 scope,
12541 line,
12542 underlying_type,
12543 size_in_bits,
12544 align_in_bits,
12545 fields_tuple,
12546 );
12547}
12548
12549fn debugCompositeTypeAssumeCapacity(
12550 self: *Builder,
12551 tag: Metadata.Tag,
12552 name: MetadataString,
12553 file: Metadata,
12554 scope: Metadata,
12555 line: u32,
12556 underlying_type: Metadata,
12557 size_in_bits: u64,
12558 align_in_bits: u64,
12559 fields_tuple: Metadata,
12560) Metadata {
12561 assert(!self.strip);
12562 return self.metadataSimpleAssumeCapacity(tag, Metadata.CompositeType{
12563 .name = name,
12564 .file = file,
12565 .scope = scope,
12566 .line = line,
12567 .underlying_type = underlying_type,
12568 .size_in_bits_lo = @truncate(size_in_bits),
12569 .size_in_bits_hi = @truncate(size_in_bits >> 32),
12570 .align_in_bits_lo = @truncate(align_in_bits),
12571 .align_in_bits_hi = @truncate(align_in_bits >> 32),
12572 .fields_tuple = fields_tuple,
12573 });
12574}
12575
12576fn debugPointerTypeAssumeCapacity(
12577 self: *Builder,
12578 name: MetadataString,
12579 file: Metadata,
12580 scope: Metadata,
12581 line: u32,
12582 underlying_type: Metadata,
12583 size_in_bits: u64,
12584 align_in_bits: u64,
12585 offset_in_bits: u64,
12586) Metadata {
12587 assert(!self.strip);
12588 return self.metadataSimpleAssumeCapacity(.derived_pointer_type, Metadata.DerivedType{
12589 .name = name,
12590 .file = file,
12591 .scope = scope,
12592 .line = line,
12593 .underlying_type = underlying_type,
12594 .size_in_bits_lo = @truncate(size_in_bits),
12595 .size_in_bits_hi = @truncate(size_in_bits >> 32),
12596 .align_in_bits_lo = @truncate(align_in_bits),
12597 .align_in_bits_hi = @truncate(align_in_bits >> 32),
12598 .offset_in_bits_lo = @truncate(offset_in_bits),
12599 .offset_in_bits_hi = @truncate(offset_in_bits >> 32),
12600 });
12601}
12602
12603fn debugMemberTypeAssumeCapacity(
12604 self: *Builder,
12605 name: MetadataString,
12606 file: Metadata,
12607 scope: Metadata,
12608 line: u32,
12609 underlying_type: Metadata,
12610 size_in_bits: u64,
12611 align_in_bits: u64,
12612 offset_in_bits: u64,
12613) Metadata {
12614 assert(!self.strip);
12615 return self.metadataSimpleAssumeCapacity(.derived_member_type, Metadata.DerivedType{
12616 .name = name,
12617 .file = file,
12618 .scope = scope,
12619 .line = line,
12620 .underlying_type = underlying_type,
12621 .size_in_bits_lo = @truncate(size_in_bits),
12622 .size_in_bits_hi = @truncate(size_in_bits >> 32),
12623 .align_in_bits_lo = @truncate(align_in_bits),
12624 .align_in_bits_hi = @truncate(align_in_bits >> 32),
12625 .offset_in_bits_lo = @truncate(offset_in_bits),
12626 .offset_in_bits_hi = @truncate(offset_in_bits >> 32),
12627 });
12628}
12629
12630fn debugSubroutineTypeAssumeCapacity(
12631 self: *Builder,
12632 types_tuple: Metadata,
12633) Metadata {
12634 assert(!self.strip);
12635 return self.metadataSimpleAssumeCapacity(.subroutine_type, Metadata.SubroutineType{
12636 .types_tuple = types_tuple,
12637 });
12638}
12639
12640fn debugEnumeratorAssumeCapacity(
12641 self: *Builder,
12642 name: MetadataString,
12643 unsigned: bool,
12644 bit_width: u32,
12645 value: std.math.big.int.Const,
12646) Metadata {
12647 assert(!self.strip);
12648 const Key = struct {
12649 tag: Metadata.Tag,
12650 name: MetadataString,
12651 bit_width: u32,
12652 value: std.math.big.int.Const,
12653 };
12654 const Adapter = struct {
12655 builder: *const Builder,
12656 pub fn hash(_: @This(), key: Key) u32 {
12657 var hasher = std.hash.Wyhash.init(std.hash.uint32(@intFromEnum(key.tag)));
12658 hasher.update(std.mem.asBytes(&key.name));
12659 hasher.update(std.mem.asBytes(&key.bit_width));
12660 hasher.update(std.mem.sliceAsBytes(key.value.limbs));
12661 return @truncate(hasher.final());
12662 }
12663
12664 pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool {
12665 if (lhs_key.tag != ctx.builder.metadata_items.items(.tag)[rhs_index]) return false;
12666 const rhs_data = ctx.builder.metadata_items.items(.data)[rhs_index];
12667 const rhs_extra = ctx.builder.metadataExtraData(Metadata.Enumerator, rhs_data);
12668 const limbs = ctx.builder.metadata_limbs
12669 .items[rhs_extra.limbs_index..][0..rhs_extra.limbs_len];
12670 const rhs_value = std.math.big.int.Const{
12671 .limbs = limbs,
12672 .positive = lhs_key.value.positive,
12673 };
12674 return lhs_key.name == rhs_extra.name and
12675 lhs_key.bit_width == rhs_extra.bit_width and
12676 lhs_key.value.eql(rhs_value);
12677 }
12678 };
12679
12680 const tag: Metadata.Tag = if (unsigned)
12681 .enumerator_unsigned
12682 else if (value.positive)
12683 .enumerator_signed_positive
12684 else
12685 .enumerator_signed_negative;
12686
12687 assert(!(tag == .enumerator_unsigned and !value.positive));
12688
12689 const gop = self.metadata_map.getOrPutAssumeCapacityAdapted(
12690 Key{
12691 .tag = tag,
12692 .name = name,
12693 .bit_width = bit_width,
12694 .value = value,
12695 },
12696 Adapter{ .builder = self },
12697 );
12698
12699 if (!gop.found_existing) {
12700 gop.key_ptr.* = {};
12701 gop.value_ptr.* = {};
12702 self.metadata_items.appendAssumeCapacity(.{
12703 .tag = tag,
12704 .data = self.addMetadataExtraAssumeCapacity(Metadata.Enumerator{
12705 .name = name,
12706 .bit_width = bit_width,
12707 .limbs_index = @intCast(self.metadata_limbs.items.len),
12708 .limbs_len = @intCast(value.limbs.len),
12709 }),
12710 });
12711 self.metadata_limbs.appendSliceAssumeCapacity(value.limbs);
12712 }
12713 return @enumFromInt(gop.index);
12714}
12715
12716fn debugSubrangeAssumeCapacity(
12717 self: *Builder,
12718 lower_bound: Metadata,
12719 count: Metadata,
12720) Metadata {
12721 assert(!self.strip);
12722 return self.metadataSimpleAssumeCapacity(.subrange, Metadata.Subrange{
12723 .lower_bound = lower_bound,
12724 .count = count,
12725 });
12726}
12727
12728fn debugExpressionAssumeCapacity(
12729 self: *Builder,
12730 elements: []const u32,
12731) Metadata {
12732 assert(!self.strip);
12733 const Key = struct {
12734 elements: []const u32,
12735 };
12736 const Adapter = struct {
12737 builder: *const Builder,
12738 pub fn hash(_: @This(), key: Key) u32 {
12739 var hasher = comptime std.hash.Wyhash.init(std.hash.uint32(@intFromEnum(Metadata.Tag.expression)));
12740 hasher.update(std.mem.sliceAsBytes(key.elements));
12741 return @truncate(hasher.final());
12742 }
12743
12744 pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool {
12745 if (Metadata.Tag.expression != ctx.builder.metadata_items.items(.tag)[rhs_index]) return false;
12746 const rhs_data = ctx.builder.metadata_items.items(.data)[rhs_index];
12747 var rhs_extra = ctx.builder.metadataExtraDataTrail(Metadata.Expression, rhs_data);
12748 return std.mem.eql(
12749 u32,
12750 lhs_key.elements,
12751 rhs_extra.trail.next(rhs_extra.data.elements_len, u32, ctx.builder),
12752 );
12753 }
12754 };
12755
12756 const gop = self.metadata_map.getOrPutAssumeCapacityAdapted(
12757 Key{ .elements = elements },
12758 Adapter{ .builder = self },
12759 );
12760
12761 if (!gop.found_existing) {
12762 gop.key_ptr.* = {};
12763 gop.value_ptr.* = {};
12764 self.metadata_items.appendAssumeCapacity(.{
12765 .tag = .expression,
12766 .data = self.addMetadataExtraAssumeCapacity(Metadata.Expression{
12767 .elements_len = @intCast(elements.len),
12768 }),
12769 });
12770 self.metadata_extra.appendSliceAssumeCapacity(@ptrCast(elements));
12771 }
12772 return @enumFromInt(gop.index);
12773}
12774
12775fn debugTupleAssumeCapacity(
12776 self: *Builder,
12777 elements: []const Metadata,
12778) Metadata {
12779 assert(!self.strip);
12780 const Key = struct {
12781 elements: []const Metadata,
12782 };
12783 const Adapter = struct {
12784 builder: *const Builder,
12785 pub fn hash(_: @This(), key: Key) u32 {
12786 var hasher = comptime std.hash.Wyhash.init(std.hash.uint32(@intFromEnum(Metadata.Tag.tuple)));
12787 hasher.update(std.mem.sliceAsBytes(key.elements));
12788 return @truncate(hasher.final());
12789 }
12790
12791 pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool {
12792 if (Metadata.Tag.tuple != ctx.builder.metadata_items.items(.tag)[rhs_index]) return false;
12793 const rhs_data = ctx.builder.metadata_items.items(.data)[rhs_index];
12794 var rhs_extra = ctx.builder.metadataExtraDataTrail(Metadata.Tuple, rhs_data);
12795 return std.mem.eql(
12796 Metadata,
12797 lhs_key.elements,
12798 rhs_extra.trail.next(rhs_extra.data.elements_len, Metadata, ctx.builder),
12799 );
12800 }
12801 };
12802
12803 const gop = self.metadata_map.getOrPutAssumeCapacityAdapted(
12804 Key{ .elements = elements },
12805 Adapter{ .builder = self },
12806 );
12807
12808 if (!gop.found_existing) {
12809 gop.key_ptr.* = {};
12810 gop.value_ptr.* = {};
12811 self.metadata_items.appendAssumeCapacity(.{
12812 .tag = .tuple,
12813 .data = self.addMetadataExtraAssumeCapacity(Metadata.Tuple{
12814 .elements_len = @intCast(elements.len),
12815 }),
12816 });
12817 self.metadata_extra.appendSliceAssumeCapacity(@ptrCast(elements));
12818 }
12819 return @enumFromInt(gop.index);
12820}
12821
12822fn debugModuleFlagAssumeCapacity(
12823 self: *Builder,
12824 behavior: Metadata,
12825 name: MetadataString,
12826 constant: Metadata,
12827) Metadata {
12828 assert(!self.strip);
12829 return self.metadataSimpleAssumeCapacity(.module_flag, Metadata.ModuleFlag{
12830 .behavior = behavior,
12831 .name = name,
12832 .constant = constant,
12833 });
12834}
12835
12836fn debugLocalVarAssumeCapacity(
12837 self: *Builder,
12838 name: MetadataString,
12839 file: Metadata,
12840 scope: Metadata,
12841 line: u32,
12842 ty: Metadata,
12843) Metadata {
12844 assert(!self.strip);
12845 return self.metadataSimpleAssumeCapacity(.local_var, Metadata.LocalVar{
12846 .name = name,
12847 .file = file,
12848 .scope = scope,
12849 .line = line,
12850 .ty = ty,
12851 });
12852}
12853
12854fn debugParameterAssumeCapacity(
12855 self: *Builder,
12856 name: MetadataString,
12857 file: Metadata,
12858 scope: Metadata,
12859 line: u32,
12860 ty: Metadata,
12861 arg_no: u32,
12862) Metadata {
12863 assert(!self.strip);
12864 return self.metadataSimpleAssumeCapacity(.parameter, Metadata.Parameter{
12865 .name = name,
12866 .file = file,
12867 .scope = scope,
12868 .line = line,
12869 .ty = ty,
12870 .arg_no = arg_no,
12871 });
12872}
12873
12874fn debugGlobalVarAssumeCapacity(
12875 self: *Builder,
12876 name: MetadataString,
12877 linkage_name: MetadataString,
12878 file: Metadata,
12879 scope: Metadata,
12880 line: u32,
12881 ty: Metadata,
12882 variable: Variable.Index,
12883 options: Metadata.GlobalVar.Options,
12884) Metadata {
12885 assert(!self.strip);
12886 return self.metadataDistinctAssumeCapacity(
12887 if (options.local) .@"global_var local" else .global_var,
12888 Metadata.GlobalVar{
12889 .name = name,
12890 .linkage_name = linkage_name,
12891 .file = file,
12892 .scope = scope,
12893 .line = line,
12894 .ty = ty,
12895 .variable = variable,
12896 },
12897 );
12898}
12899
12900fn debugGlobalVarExpressionAssumeCapacity(
12901 self: *Builder,
12902 variable: Metadata,
12903 expression: Metadata,
12904) Metadata {
12905 assert(!self.strip);
12906 return self.metadataSimpleAssumeCapacity(.global_var_expression, Metadata.GlobalVarExpression{
12907 .variable = variable,
12908 .expression = expression,
12909 });
12910}
12911
12912fn debugConstantAssumeCapacity(self: *Builder, constant: Constant) Metadata {
12913 assert(!self.strip);
12914 const Adapter = struct {
12915 builder: *const Builder,
12916 pub fn hash(_: @This(), key: Constant) u32 {
12917 var hasher = comptime std.hash.Wyhash.init(std.hash.uint32(@intFromEnum(Metadata.Tag.constant)));
12918 hasher.update(std.mem.asBytes(&key));
12919 return @truncate(hasher.final());
12920 }
12921
12922 pub fn eql(ctx: @This(), lhs_key: Constant, _: void, rhs_index: usize) bool {
12923 if (Metadata.Tag.constant != ctx.builder.metadata_items.items(.tag)[rhs_index]) return false;
12924 const rhs_data: Constant = @enumFromInt(ctx.builder.metadata_items.items(.data)[rhs_index]);
12925 return rhs_data == lhs_key;
12926 }
12927 };
12928
12929 const gop = self.metadata_map.getOrPutAssumeCapacityAdapted(
12930 constant,
12931 Adapter{ .builder = self },
12932 );
12933
12934 if (!gop.found_existing) {
12935 gop.key_ptr.* = {};
12936 gop.value_ptr.* = {};
12937 self.metadata_items.appendAssumeCapacity(.{
12938 .tag = .constant,
12939 .data = @intFromEnum(constant),
12940 });
12941 }
12942 return @enumFromInt(gop.index);
12943}
12944
12945pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]const u32 {
12946 const BitcodeWriter = bitcode_writer.BitcodeWriter(&.{ Type, FunctionAttributes });
12947 var bitcode = BitcodeWriter.init(allocator, .{
12948 std.math.log2_int_ceil(usize, self.type_items.items.len),
12949 std.math.log2_int_ceil(usize, 1 + self.function_attributes_set.count()),
12950 });
12951 errdefer bitcode.deinit();
12952
12953 // Write LLVM IR magic
12954 try bitcode.writeBits(ir.MAGIC, 32);
12955
12956 var record: std.ArrayListUnmanaged(u64) = .{};
12957 defer record.deinit(self.gpa);
12958
12959 // IDENTIFICATION_BLOCK
12960 {
12961 const Identification = ir.Identification;
12962 var identification_block = try bitcode.enterTopBlock(Identification);
12963
12964 const producer = try std.fmt.allocPrint(self.gpa, "zig {d}.{d}.{d}", .{
12965 build_options.semver.major,
12966 build_options.semver.minor,
12967 build_options.semver.patch,
12968 });
12969 defer self.gpa.free(producer);
12970
12971 try identification_block.writeAbbrev(Identification.Version{ .string = producer });
12972 try identification_block.writeAbbrev(Identification.Epoch{ .epoch = 0 });
12973
12974 try identification_block.end();
12975 }
12976
12977 // MODULE_BLOCK
12978 {
12979 const Module = ir.Module;
12980 var module_block = try bitcode.enterTopBlock(Module);
12981
12982 try module_block.writeAbbrev(Module.Version{});
12983
12984 if (self.target_triple.slice(self)) |triple| {
12985 try module_block.writeAbbrev(Module.String{
12986 .code = 2,
12987 .string = triple,
12988 });
12989 }
12990
12991 if (self.data_layout.slice(self)) |data_layout| {
12992 try module_block.writeAbbrev(Module.String{
12993 .code = 3,
12994 .string = data_layout,
12995 });
12996 }
12997
12998 if (self.source_filename.slice(self)) |source_filename| {
12999 try module_block.writeAbbrev(Module.String{
13000 .code = 16,
13001 .string = source_filename,
13002 });
13003 }
13004
13005 if (self.module_asm.items.len != 0) {
13006 try module_block.writeAbbrev(Module.String{
13007 .code = 4,
13008 .string = self.module_asm.items,
13009 });
13010 }
13011
13012 // TYPE_BLOCK
13013 {
13014 var type_block = try module_block.enterSubBlock(ir.Type);
13015
13016 try type_block.writeAbbrev(ir.Type.NumEntry{ .num = @intCast(self.type_items.items.len) });
13017
13018 for (self.type_items.items, 0..) |item, i| {
13019 const ty: Type = @enumFromInt(i);
13020
13021 switch (item.tag) {
13022 .simple => try type_block.writeAbbrev(ir.Type.Simple{ .code = @truncate(item.data) }),
13023 .integer => try type_block.writeAbbrev(ir.Type.Integer{ .width = item.data }),
13024 .structure,
13025 .packed_structure,
13026 => |kind| {
13027 const is_packed = switch (kind) {
13028 .structure => false,
13029 .packed_structure => true,
13030 else => unreachable,
13031 };
13032 var extra = self.typeExtraDataTrail(Type.Structure, item.data);
13033 try type_block.writeAbbrev(ir.Type.StructAnon{
13034 .is_packed = is_packed,
13035 .types = extra.trail.next(extra.data.fields_len, Type, self),
13036 });
13037 },
13038 .named_structure => {
13039 const extra = self.typeExtraData(Type.NamedStructure, item.data);
13040 try type_block.writeAbbrev(ir.Type.StructName{
13041 .string = extra.id.slice(self).?,
13042 });
13043
13044 switch (extra.body) {
13045 .none => try type_block.writeAbbrev(ir.Type.Opaque{}),
13046 else => {
13047 const real_struct = self.type_items.items[@intFromEnum(extra.body)];
13048 const is_packed: bool = switch (real_struct.tag) {
13049 .structure => false,
13050 .packed_structure => true,
13051 else => unreachable,
13052 };
13053
13054 var real_extra = self.typeExtraDataTrail(Type.Structure, real_struct.data);
13055 try type_block.writeAbbrev(ir.Type.StructNamed{
13056 .is_packed = is_packed,
13057 .types = real_extra.trail.next(real_extra.data.fields_len, Type, self),
13058 });
13059 },
13060 }
13061 },
13062 .array,
13063 .small_array,
13064 => try type_block.writeAbbrev(ir.Type.Array{
13065 .len = ty.aggregateLen(self),
13066 .child = ty.childType(self),
13067 }),
13068 .vector,
13069 .scalable_vector,
13070 => try type_block.writeAbbrev(ir.Type.Vector{
13071 .len = ty.aggregateLen(self),
13072 .child = ty.childType(self),
13073 }),
13074 .pointer => try type_block.writeAbbrev(ir.Type.Pointer{
13075 .addr_space = ty.pointerAddrSpace(self),
13076 }),
13077 .target => {
13078 var extra = self.typeExtraDataTrail(Type.Target, item.data);
13079 try type_block.writeAbbrev(ir.Type.StructName{
13080 .string = extra.data.name.slice(self).?,
13081 });
13082
13083 const types = extra.trail.next(extra.data.types_len, Type, self);
13084 const ints = extra.trail.next(extra.data.ints_len, u32, self);
13085
13086 try type_block.writeAbbrev(ir.Type.Target{
13087 .num_types = extra.data.types_len,
13088 .types = types,
13089 .ints = ints,
13090 });
13091 },
13092 .function, .vararg_function => |kind| {
13093 const is_vararg = switch (kind) {
13094 .function => false,
13095 .vararg_function => true,
13096 else => unreachable,
13097 };
13098 var extra = self.typeExtraDataTrail(Type.Function, item.data);
13099 try type_block.writeAbbrev(ir.Type.Function{
13100 .is_vararg = is_vararg,
13101 .return_type = extra.data.ret,
13102 .param_types = extra.trail.next(extra.data.params_len, Type, self),
13103 });
13104 },
13105 }
13106 }
13107
13108 try type_block.end();
13109 }
13110
13111 var attributes_set: std.AutoArrayHashMapUnmanaged(struct {
13112 attributes: Attributes,
13113 index: u32,
13114 }, void) = .{};
13115 defer attributes_set.deinit(self.gpa);
13116
13117 // PARAMATTR_GROUP_BLOCK
13118 {
13119 const ParamattrGroup = ir.ParamattrGroup;
13120
13121 var paramattr_group_block = try module_block.enterSubBlock(ParamattrGroup);
13122
13123 for (self.function_attributes_set.keys()) |func_attributes| {
13124 for (func_attributes.slice(self), 0..) |attributes, i| {
13125 const attributes_slice = attributes.slice(self);
13126 if (attributes_slice.len == 0) continue;
13127
13128 const attr_gop = try attributes_set.getOrPut(self.gpa, .{
13129 .attributes = attributes,
13130 .index = @intCast(i),
13131 });
13132
13133 if (attr_gop.found_existing) continue;
13134
13135 record.clearRetainingCapacity();
13136 try record.ensureUnusedCapacity(self.gpa, 2);
13137
13138 record.appendAssumeCapacity(attr_gop.index);
13139 record.appendAssumeCapacity(switch (i) {
13140 0 => 0xffffffff,
13141 else => i - 1,
13142 });
13143
13144 for (attributes_slice) |attr_index| {
13145 const kind = attr_index.getKind(self);
13146 switch (attr_index.toAttribute(self)) {
13147 .zeroext,
13148 .signext,
13149 .inreg,
13150 .@"noalias",
13151 .nocapture,
13152 .nofree,
13153 .nest,
13154 .returned,
13155 .nonnull,
13156 .swiftself,
13157 .swiftasync,
13158 .swifterror,
13159 .immarg,
13160 .noundef,
13161 .allocalign,
13162 .allocptr,
13163 .readnone,
13164 .readonly,
13165 .writeonly,
13166 .alwaysinline,
13167 .builtin,
13168 .cold,
13169 .convergent,
13170 .disable_sanitizer_information,
13171 .fn_ret_thunk_extern,
13172 .hot,
13173 .inlinehint,
13174 .jumptable,
13175 .minsize,
13176 .naked,
13177 .nobuiltin,
13178 .nocallback,
13179 .noduplicate,
13180 .noimplicitfloat,
13181 .@"noinline",
13182 .nomerge,
13183 .nonlazybind,
13184 .noprofile,
13185 .skipprofile,
13186 .noredzone,
13187 .noreturn,
13188 .norecurse,
13189 .willreturn,
13190 .nosync,
13191 .nounwind,
13192 .nosanitize_bounds,
13193 .nosanitize_coverage,
13194 .null_pointer_is_valid,
13195 .optforfuzzing,
13196 .optnone,
13197 .optsize,
13198 .returns_twice,
13199 .safestack,
13200 .sanitize_address,
13201 .sanitize_memory,
13202 .sanitize_thread,
13203 .sanitize_hwaddress,
13204 .sanitize_memtag,
13205 .speculative_load_hardening,
13206 .speculatable,
13207 .ssp,
13208 .sspstrong,
13209 .sspreq,
13210 .strictfp,
13211 .nocf_check,
13212 .shadowcallstack,
13213 .mustprogress,
13214 .no_sanitize_address,
13215 .no_sanitize_hwaddress,
13216 .sanitize_address_dyninit,
13217 => {
13218 try record.ensureUnusedCapacity(self.gpa, 2);
13219 record.appendAssumeCapacity(0);
13220 record.appendAssumeCapacity(@intFromEnum(kind));
13221 },
13222 .byval,
13223 .byref,
13224 .preallocated,
13225 .inalloca,
13226 .sret,
13227 .elementtype,
13228 => |ty| {
13229 try record.ensureUnusedCapacity(self.gpa, 3);
13230 record.appendAssumeCapacity(6);
13231 record.appendAssumeCapacity(@intFromEnum(kind));
13232 record.appendAssumeCapacity(@intFromEnum(ty));
13233 },
13234 .@"align",
13235 .alignstack,
13236 => |alignment| {
13237 try record.ensureUnusedCapacity(self.gpa, 3);
13238 record.appendAssumeCapacity(1);
13239 record.appendAssumeCapacity(@intFromEnum(kind));
13240 record.appendAssumeCapacity(alignment.toByteUnits() orelse 0);
13241 },
13242 .dereferenceable,
13243 .dereferenceable_or_null,
13244 => |size| {
13245 try record.ensureUnusedCapacity(self.gpa, 3);
13246 record.appendAssumeCapacity(1);
13247 record.appendAssumeCapacity(@intFromEnum(kind));
13248 record.appendAssumeCapacity(size);
13249 },
13250 .nofpclass => |fpclass| {
13251 try record.ensureUnusedCapacity(self.gpa, 3);
13252 record.appendAssumeCapacity(1);
13253 record.appendAssumeCapacity(@intFromEnum(kind));
13254 record.appendAssumeCapacity(@as(u32, @bitCast(fpclass)));
13255 },
13256 .allockind => |allockind| {
13257 try record.ensureUnusedCapacity(self.gpa, 3);
13258 record.appendAssumeCapacity(1);
13259 record.appendAssumeCapacity(@intFromEnum(kind));
13260 record.appendAssumeCapacity(@as(u32, @bitCast(allockind)));
13261 },
13262
13263 .allocsize => |allocsize| {
13264 try record.ensureUnusedCapacity(self.gpa, 3);
13265 record.appendAssumeCapacity(1);
13266 record.appendAssumeCapacity(@intFromEnum(kind));
13267 record.appendAssumeCapacity(@bitCast(allocsize.toLlvm()));
13268 },
13269 .memory => |memory| {
13270 try record.ensureUnusedCapacity(self.gpa, 3);
13271 record.appendAssumeCapacity(1);
13272 record.appendAssumeCapacity(@intFromEnum(kind));
13273 record.appendAssumeCapacity(@as(u32, @bitCast(memory)));
13274 },
13275 .uwtable => |uwtable| if (uwtable != .none) {
13276 try record.ensureUnusedCapacity(self.gpa, 3);
13277 record.appendAssumeCapacity(1);
13278 record.appendAssumeCapacity(@intFromEnum(kind));
13279 record.appendAssumeCapacity(@intFromEnum(uwtable));
13280 },
13281 .vscale_range => |vscale_range| {
13282 try record.ensureUnusedCapacity(self.gpa, 3);
13283 record.appendAssumeCapacity(1);
13284 record.appendAssumeCapacity(@intFromEnum(kind));
13285 record.appendAssumeCapacity(@bitCast(vscale_range.toLlvm()));
13286 },
13287 .string => |string_attr| {
13288 const string_attr_kind_slice = string_attr.kind.slice(self).?;
13289 const string_attr_value_slice = if (string_attr.value != .none)
13290 string_attr.value.slice(self).?
13291 else
13292 null;
13293
13294 try record.ensureUnusedCapacity(
13295 self.gpa,
13296 2 + string_attr_kind_slice.len + if (string_attr_value_slice) |slice| slice.len + 1 else 0,
13297 );
13298 record.appendAssumeCapacity(if (string_attr.value == .none) 3 else 4);
13299 for (string_attr.kind.slice(self).?) |c| {
13300 record.appendAssumeCapacity(c);
13301 }
13302 record.appendAssumeCapacity(0);
13303 if (string_attr_value_slice) |slice| {
13304 for (slice) |c| {
13305 record.appendAssumeCapacity(c);
13306 }
13307 record.appendAssumeCapacity(0);
13308 }
13309 },
13310 .none => unreachable,
13311 }
13312 }
13313
13314 try paramattr_group_block.writeUnabbrev(3, record.items);
13315 }
13316 }
13317
13318 try paramattr_group_block.end();
13319 }
13320
13321 // PARAMATTR_BLOCK
13322 {
13323 const Paramattr = ir.Paramattr;
13324 var paramattr_block = try module_block.enterSubBlock(Paramattr);
13325
13326 for (self.function_attributes_set.keys()) |func_attributes| {
13327 const func_attributes_slice = func_attributes.slice(self);
13328 record.clearRetainingCapacity();
13329 try record.ensureUnusedCapacity(self.gpa, func_attributes_slice.len);
13330 for (func_attributes_slice, 0..) |attributes, i| {
13331 const attributes_slice = attributes.slice(self);
13332 if (attributes_slice.len == 0) continue;
13333
13334 const group_index = attributes_set.getIndex(.{
13335 .attributes = attributes,
13336 .index = @intCast(i),
13337 }).?;
13338 record.appendAssumeCapacity(@intCast(group_index));
13339 }
13340
13341 try paramattr_block.writeAbbrev(Paramattr.Entry{ .group_indices = record.items });
13342 }
13343
13344 try paramattr_block.end();
13345 }
13346
13347 var globals: std.AutoArrayHashMapUnmanaged(Global.Index, void) = .{};
13348 defer globals.deinit(self.gpa);
13349 try globals.ensureUnusedCapacity(
13350 self.gpa,
13351 self.variables.items.len +
13352 self.functions.items.len +
13353 self.aliases.items.len,
13354 );
13355
13356 for (self.variables.items) |variable| {
13357 if (variable.global.getReplacement(self) != .none) continue;
13358
13359 globals.putAssumeCapacity(variable.global, {});
13360 }
13361
13362 for (self.functions.items) |function| {
13363 if (function.global.getReplacement(self) != .none) continue;
13364
13365 globals.putAssumeCapacity(function.global, {});
13366 }
13367
13368 for (self.aliases.items) |alias| {
13369 if (alias.global.getReplacement(self) != .none) continue;
13370
13371 globals.putAssumeCapacity(alias.global, {});
13372 }
13373
13374 const ConstantAdapter = struct {
13375 const ConstantAdapter = @This();
13376 builder: *const Builder,
13377 globals: *const std.AutoArrayHashMapUnmanaged(Global.Index, void),
13378
13379 pub fn get(adapter: @This(), param: anytype, comptime field_name: []const u8) @TypeOf(param) {
13380 _ = field_name;
13381 return switch (@TypeOf(param)) {
13382 Constant => @enumFromInt(adapter.getConstantIndex(param)),
13383 else => param,
13384 };
13385 }
13386
13387 pub fn getConstantIndex(adapter: ConstantAdapter, constant: Constant) u32 {
13388 return switch (constant.unwrap()) {
13389 .constant => |c| c + adapter.numGlobals(),
13390 .global => |global| @intCast(adapter.globals.getIndex(global.unwrap(adapter.builder)).?),
13391 };
13392 }
13393
13394 pub fn numConstants(adapter: ConstantAdapter) u32 {
13395 return @intCast(adapter.globals.count() + adapter.builder.constant_items.len);
13396 }
13397
13398 pub fn numGlobals(adapter: ConstantAdapter) u32 {
13399 return @intCast(adapter.globals.count());
13400 }
13401 };
13402
13403 const constant_adapter = ConstantAdapter{
13404 .builder = self,
13405 .globals = &globals,
13406 };
13407
13408 // Globals
13409 {
13410 var section_map: std.AutoArrayHashMapUnmanaged(String, void) = .{};
13411 defer section_map.deinit(self.gpa);
13412 try section_map.ensureUnusedCapacity(self.gpa, globals.count());
13413
13414 for (self.variables.items) |variable| {
13415 if (variable.global.getReplacement(self) != .none) continue;
13416
13417 const section = blk: {
13418 if (variable.section == .none) break :blk 0;
13419 const gop = section_map.getOrPutAssumeCapacity(variable.section);
13420 if (!gop.found_existing) {
13421 try module_block.writeAbbrev(Module.String{
13422 .code = 5,
13423 .string = variable.section.slice(self).?,
13424 });
13425 }
13426 break :blk gop.index + 1;
13427 };
13428
13429 const initid = if (variable.init == .no_init)
13430 0
13431 else
13432 (constant_adapter.getConstantIndex(variable.init) + 1);
13433
13434 const strtab = variable.global.strtab(self);
13435
13436 const global = variable.global.ptrConst(self);
13437 try module_block.writeAbbrev(Module.Variable{
13438 .strtab_offset = strtab.offset,
13439 .strtab_size = strtab.size,
13440 .type_index = global.type,
13441 .is_const = .{
13442 .is_const = switch (variable.mutability) {
13443 .global => false,
13444 .constant => true,
13445 },
13446 .addr_space = global.addr_space,
13447 },
13448 .initid = initid,
13449 .linkage = global.linkage,
13450 .alignment = variable.alignment.toLlvm(),
13451 .section = section,
13452 .visibility = global.visibility,
13453 .thread_local = variable.thread_local,
13454 .unnamed_addr = global.unnamed_addr,
13455 .externally_initialized = global.externally_initialized,
13456 .dllstorageclass = global.dll_storage_class,
13457 .preemption = global.preemption,
13458 });
13459 }
13460
13461 for (self.functions.items) |func| {
13462 if (func.global.getReplacement(self) != .none) continue;
13463
13464 const section = blk: {
13465 if (func.section == .none) break :blk 0;
13466 const gop = section_map.getOrPutAssumeCapacity(func.section);
13467 if (!gop.found_existing) {
13468 try module_block.writeAbbrev(Module.String{
13469 .code = 5,
13470 .string = func.section.slice(self).?,
13471 });
13472 }
13473 break :blk gop.index + 1;
13474 };
13475
13476 const paramattr_index = if (self.function_attributes_set.getIndex(func.attributes)) |index|
13477 index + 1
13478 else
13479 0;
13480
13481 const strtab = func.global.strtab(self);
13482
13483 const global = func.global.ptrConst(self);
13484 try module_block.writeAbbrev(Module.Function{
13485 .strtab_offset = strtab.offset,
13486 .strtab_size = strtab.size,
13487 .type_index = global.type,
13488 .call_conv = func.call_conv,
13489 .is_proto = func.instructions.len == 0,
13490 .linkage = global.linkage,
13491 .paramattr = paramattr_index,
13492 .alignment = func.alignment.toLlvm(),
13493 .section = section,
13494 .visibility = global.visibility,
13495 .unnamed_addr = global.unnamed_addr,
13496 .dllstorageclass = global.dll_storage_class,
13497 .preemption = global.preemption,
13498 .addr_space = global.addr_space,
13499 });
13500 }
13501
13502 for (self.aliases.items) |alias| {
13503 if (alias.global.getReplacement(self) != .none) continue;
13504
13505 const strtab = alias.global.strtab(self);
13506
13507 const global = alias.global.ptrConst(self);
13508 try module_block.writeAbbrev(Module.Alias{
13509 .strtab_offset = strtab.offset,
13510 .strtab_size = strtab.size,
13511 .type_index = global.type,
13512 .addr_space = global.addr_space,
13513 .aliasee = constant_adapter.getConstantIndex(alias.aliasee),
13514 .linkage = global.linkage,
13515 .visibility = global.visibility,
13516 .thread_local = alias.thread_local,
13517 .unnamed_addr = global.unnamed_addr,
13518 .dllstorageclass = global.dll_storage_class,
13519 .preemption = global.preemption,
13520 });
13521 }
13522 }
13523
13524 // CONSTANTS_BLOCK
13525 {
13526 const Constants = ir.Constants;
13527 var constants_block = try module_block.enterSubBlock(Constants);
13528
13529 var current_type: Type = .none;
13530 const tags = self.constant_items.items(.tag);
13531 const datas = self.constant_items.items(.data);
13532 for (0..self.constant_items.len) |index| {
13533 record.clearRetainingCapacity();
13534 const constant: Constant = @enumFromInt(index);
13535 const constant_type = constant.typeOf(self);
13536 if (constant_type != current_type) {
13537 try constants_block.writeAbbrev(Constants.SetType{ .type_id = constant_type });
13538 current_type = constant_type;
13539 }
13540 const data = datas[index];
13541 switch (tags[index]) {
13542 .null,
13543 .zeroinitializer,
13544 .none,
13545 => try constants_block.writeAbbrev(Constants.Null{}),
13546 .undef => try constants_block.writeAbbrev(Constants.Undef{}),
13547 .poison => try constants_block.writeAbbrev(Constants.Poison{}),
13548 .positive_integer,
13549 .negative_integer,
13550 => |tag| {
13551 const extra: *align(@alignOf(std.math.big.Limb)) Constant.Integer =
13552 @ptrCast(self.constant_limbs.items[data..][0..Constant.Integer.limbs]);
13553 const limbs = self.constant_limbs
13554 .items[data + Constant.Integer.limbs ..][0..extra.limbs_len];
13555 const bigint: std.math.big.int.Const = .{
13556 .limbs = limbs,
13557 .positive = tag == .positive_integer,
13558 };
13559
13560 const bit_count = extra.type.scalarBits(self);
13561 if (bit_count <= 64) {
13562 const val = bigint.to(i64) catch unreachable;
13563 const emit_val = if (tag == .positive_integer)
13564 @shlWithOverflow(val, 1)[0]
13565 else
13566 (@shlWithOverflow(@addWithOverflow(~val, 1)[0], 1)[0] | 1);
13567 try constants_block.writeAbbrev(Constants.Integer{ .value = @bitCast(emit_val) });
13568 } else {
13569 const word_count = std.mem.alignForward(u24, bit_count, 64) / 64;
13570 try record.ensureUnusedCapacity(self.gpa, word_count);
13571 const buffer: [*]u8 = @ptrCast(record.items.ptr);
13572 bigint.writeTwosComplement(buffer[0..(word_count * 8)], .little);
13573
13574 const signed_buffer: [*]i64 = @ptrCast(record.items.ptr);
13575 for (signed_buffer[0..word_count], 0..) |val, i| {
13576 signed_buffer[i] = if (val >= 0)
13577 @shlWithOverflow(val, 1)[0]
13578 else
13579 (@shlWithOverflow(@addWithOverflow(~val, 1)[0], 1)[0] | 1);
13580 }
13581
13582 try constants_block.writeUnabbrev(5, record.items.ptr[0..word_count]);
13583 }
13584 },
13585 .half,
13586 .bfloat,
13587 => try constants_block.writeAbbrev(Constants.Half{ .value = @truncate(data) }),
13588 .float => try constants_block.writeAbbrev(Constants.Float{ .value = data }),
13589 .double => {
13590 const extra = self.constantExtraData(Constant.Double, data);
13591 try constants_block.writeAbbrev(Constants.Double{
13592 .value = (@as(u64, extra.hi) << 32) | extra.lo,
13593 });
13594 },
13595 .x86_fp80 => {
13596 const extra = self.constantExtraData(Constant.Fp80, data);
13597 try constants_block.writeAbbrev(Constants.Fp80{
13598 .hi = @as(u64, extra.hi) << 48 | @as(u64, extra.lo_hi) << 16 |
13599 extra.lo_lo >> 16,
13600 .lo = @truncate(extra.lo_lo),
13601 });
13602 },
13603 .fp128,
13604 .ppc_fp128,
13605 => {
13606 const extra = self.constantExtraData(Constant.Fp128, data);
13607 try constants_block.writeAbbrev(Constants.Fp128{
13608 .lo = @as(u64, extra.lo_hi) << 32 | @as(u64, extra.lo_lo),
13609 .hi = @as(u64, extra.hi_hi) << 32 | @as(u64, extra.hi_lo),
13610 });
13611 },
13612 .array,
13613 .vector,
13614 .structure,
13615 .packed_structure,
13616 => {
13617 var extra = self.constantExtraDataTrail(Constant.Aggregate, data);
13618 const len: u32 = @intCast(extra.data.type.aggregateLen(self));
13619 const values = extra.trail.next(len, Constant, self);
13620
13621 try constants_block.writeAbbrevAdapted(
13622 Constants.Aggregate{ .values = values },
13623 constant_adapter,
13624 );
13625 },
13626 .splat => {
13627 const ConstantsWriter = @TypeOf(constants_block);
13628 const extra = self.constantExtraData(Constant.Splat, data);
13629 const vector_len = extra.type.vectorLen(self);
13630 const c = constant_adapter.getConstantIndex(extra.value);
13631
13632 try bitcode.writeBits(
13633 ConstantsWriter.abbrevId(Constants.Aggregate),
13634 ConstantsWriter.abbrev_len,
13635 );
13636 try bitcode.writeVBR(vector_len, 6);
13637 for (0..vector_len) |_| {
13638 try bitcode.writeBits(c, Constants.Aggregate.ops[1].array_fixed);
13639 }
13640 },
13641 .string => {
13642 const str: String = @enumFromInt(data);
13643 if (str == .none) {
13644 try constants_block.writeAbbrev(Constants.Null{});
13645 } else {
13646 const slice = str.slice(self).?;
13647 if (slice.len > 0 and slice[slice.len - 1] == 0)
13648 try constants_block.writeAbbrev(Constants.CString{ .string = slice[0 .. slice.len - 1] })
13649 else
13650 try constants_block.writeAbbrev(Constants.String{ .string = slice });
13651 }
13652 },
13653 .bitcast,
13654 .inttoptr,
13655 .ptrtoint,
13656 .fptosi,
13657 .fptoui,
13658 .sitofp,
13659 .uitofp,
13660 .addrspacecast,
13661 .fptrunc,
13662 .trunc,
13663 .fpext,
13664 .sext,
13665 .zext,
13666 => |tag| {
13667 const extra = self.constantExtraData(Constant.Cast, data);
13668 try constants_block.writeAbbrevAdapted(Constants.Cast{
13669 .type_index = extra.type,
13670 .val = extra.val,
13671 .opcode = tag.toCastOpcode(),
13672 }, constant_adapter);
13673 },
13674 .add,
13675 .@"add nsw",
13676 .@"add nuw",
13677 .sub,
13678 .@"sub nsw",
13679 .@"sub nuw",
13680 .mul,
13681 .@"mul nsw",
13682 .@"mul nuw",
13683 .shl,
13684 .lshr,
13685 .ashr,
13686 .@"and",
13687 .@"or",
13688 .xor,
13689 => |tag| {
13690 const extra = self.constantExtraData(Constant.Binary, data);
13691 try constants_block.writeAbbrevAdapted(Constants.Binary{
13692 .opcode = tag.toBinaryOpcode(),
13693 .lhs = extra.lhs,
13694 .rhs = extra.rhs,
13695 }, constant_adapter);
13696 },
13697 .icmp,
13698 .fcmp,
13699 => {
13700 const extra = self.constantExtraData(Constant.Compare, data);
13701 try constants_block.writeAbbrevAdapted(Constants.Cmp{
13702 .ty = extra.lhs.typeOf(self),
13703 .lhs = extra.lhs,
13704 .rhs = extra.rhs,
13705 .pred = extra.cond,
13706 }, constant_adapter);
13707 },
13708 .extractelement => {
13709 const extra = self.constantExtraData(Constant.ExtractElement, data);
13710 try constants_block.writeAbbrevAdapted(Constants.ExtractElement{
13711 .val_type = extra.val.typeOf(self),
13712 .val = extra.val,
13713 .index_type = extra.index.typeOf(self),
13714 .index = extra.index,
13715 }, constant_adapter);
13716 },
13717 .insertelement => {
13718 const extra = self.constantExtraData(Constant.InsertElement, data);
13719 try constants_block.writeAbbrevAdapted(Constants.InsertElement{
13720 .val = extra.val,
13721 .elem = extra.elem,
13722 .index_type = extra.index.typeOf(self),
13723 .index = extra.index,
13724 }, constant_adapter);
13725 },
13726 .shufflevector => {
13727 const extra = self.constantExtraData(Constant.ShuffleVector, data);
13728 const ty = constant.typeOf(self);
13729 const lhs_type = extra.lhs.typeOf(self);
13730 // Check if instruction is widening, truncating or not
13731 if (ty == lhs_type) {
13732 try constants_block.writeAbbrevAdapted(Constants.ShuffleVector{
13733 .lhs = extra.lhs,
13734 .rhs = extra.rhs,
13735 .mask = extra.mask,
13736 }, constant_adapter);
13737 } else {
13738 try constants_block.writeAbbrevAdapted(Constants.ShuffleVectorEx{
13739 .ty = ty,
13740 .lhs = extra.lhs,
13741 .rhs = extra.rhs,
13742 .mask = extra.mask,
13743 }, constant_adapter);
13744 }
13745 },
13746 .getelementptr,
13747 .@"getelementptr inbounds",
13748 => |tag| {
13749 var extra = self.constantExtraDataTrail(Constant.GetElementPtr, data);
13750 const indices = extra.trail.next(extra.data.info.indices_len, Constant, self);
13751 try record.ensureUnusedCapacity(self.gpa, 1 + 2 + 2 * indices.len);
13752
13753 record.appendAssumeCapacity(@intFromEnum(extra.data.type));
13754
13755 record.appendAssumeCapacity(@intFromEnum(extra.data.base.typeOf(self)));
13756 record.appendAssumeCapacity(constant_adapter.getConstantIndex(extra.data.base));
13757
13758 for (indices) |i| {
13759 record.appendAssumeCapacity(@intFromEnum(i.typeOf(self)));
13760 record.appendAssumeCapacity(constant_adapter.getConstantIndex(i));
13761 }
13762
13763 try constants_block.writeUnabbrev(switch (tag) {
13764 .getelementptr => 12,
13765 .@"getelementptr inbounds" => 20,
13766 else => unreachable,
13767 }, record.items);
13768 },
13769 .@"asm",
13770 .@"asm sideeffect",
13771 .@"asm alignstack",
13772 .@"asm sideeffect alignstack",
13773 .@"asm inteldialect",
13774 .@"asm sideeffect inteldialect",
13775 .@"asm alignstack inteldialect",
13776 .@"asm sideeffect alignstack inteldialect",
13777 .@"asm unwind",
13778 .@"asm sideeffect unwind",
13779 .@"asm alignstack unwind",
13780 .@"asm sideeffect alignstack unwind",
13781 .@"asm inteldialect unwind",
13782 .@"asm sideeffect inteldialect unwind",
13783 .@"asm alignstack inteldialect unwind",
13784 .@"asm sideeffect alignstack inteldialect unwind",
13785 => |tag| {
13786 const extra = self.constantExtraData(Constant.Assembly, data);
13787
13788 const assembly_slice = extra.assembly.slice(self).?;
13789 const constraints_slice = extra.constraints.slice(self).?;
13790
13791 try record.ensureUnusedCapacity(self.gpa, 4 + assembly_slice.len + constraints_slice.len);
13792
13793 record.appendAssumeCapacity(@intFromEnum(extra.type));
13794 record.appendAssumeCapacity(switch (tag) {
13795 .@"asm" => 0,
13796 .@"asm sideeffect" => 0b0001,
13797 .@"asm sideeffect alignstack" => 0b0011,
13798 .@"asm sideeffect inteldialect" => 0b0101,
13799 .@"asm sideeffect alignstack inteldialect" => 0b0111,
13800 .@"asm sideeffect unwind" => 0b1001,
13801 .@"asm sideeffect alignstack unwind" => 0b1011,
13802 .@"asm sideeffect inteldialect unwind" => 0b1101,
13803 .@"asm sideeffect alignstack inteldialect unwind" => 0b1111,
13804 .@"asm alignstack" => 0b0010,
13805 .@"asm inteldialect" => 0b0100,
13806 .@"asm alignstack inteldialect" => 0b0110,
13807 .@"asm unwind" => 0b1000,
13808 .@"asm alignstack unwind" => 0b1010,
13809 .@"asm inteldialect unwind" => 0b1100,
13810 .@"asm alignstack inteldialect unwind" => 0b1110,
13811 else => unreachable,
13812 });
13813
13814 record.appendAssumeCapacity(assembly_slice.len);
13815 for (assembly_slice) |c| record.appendAssumeCapacity(c);
13816
13817 record.appendAssumeCapacity(constraints_slice.len);
13818 for (constraints_slice) |c| record.appendAssumeCapacity(c);
13819
13820 try constants_block.writeUnabbrev(30, record.items);
13821 },
13822 .blockaddress => {
13823 const extra = self.constantExtraData(Constant.BlockAddress, data);
13824 try constants_block.writeAbbrev(Constants.BlockAddress{
13825 .type_id = extra.function.typeOf(self),
13826 .function = constant_adapter.getConstantIndex(extra.function.toConst(self)),
13827 .block = @intFromEnum(extra.block),
13828 });
13829 },
13830 .dso_local_equivalent,
13831 .no_cfi,
13832 => |tag| {
13833 const function: Function.Index = @enumFromInt(data);
13834 try constants_block.writeAbbrev(Constants.DsoLocalEquivalentOrNoCfi{
13835 .code = switch (tag) {
13836 .dso_local_equivalent => 27,
13837 .no_cfi => 29,
13838 else => unreachable,
13839 },
13840 .type_id = function.typeOf(self),
13841 .function = constant_adapter.getConstantIndex(function.toConst(self)),
13842 });
13843 },
13844 }
13845 }
13846
13847 try constants_block.end();
13848 }
13849
13850 // METADATA_KIND_BLOCK
13851 if (!self.strip) {
13852 const MetadataKindBlock = ir.MetadataKindBlock;
13853 var metadata_kind_block = try module_block.enterSubBlock(MetadataKindBlock);
13854
13855 inline for (@typeInfo(ir.MetadataKind).Enum.fields) |field| {
13856 try metadata_kind_block.writeAbbrev(MetadataKindBlock.Kind{
13857 .id = field.value,
13858 .name = field.name,
13859 });
13860 }
13861
13862 try metadata_kind_block.end();
13863 }
13864
13865 const MetadataAdapter = struct {
13866 builder: *const Builder,
13867 constant_adapter: ConstantAdapter,
13868
13869 pub fn init(
13870 builder: *const Builder,
13871 const_adapter: ConstantAdapter,
13872 ) @This() {
13873 return .{
13874 .builder = builder,
13875 .constant_adapter = const_adapter,
13876 };
13877 }
13878
13879 pub fn get(adapter: @This(), value: anytype, comptime field_name: []const u8) @TypeOf(value) {
13880 _ = field_name;
13881 const Ty = @TypeOf(value);
13882 return switch (Ty) {
13883 Metadata => @enumFromInt(adapter.getMetadataIndex(value)),
13884 MetadataString => @enumFromInt(adapter.getMetadataStringIndex(value)),
13885 Constant => @enumFromInt(adapter.constant_adapter.getConstantIndex(value)),
13886 else => value,
13887 };
13888 }
13889
13890 pub fn getMetadataIndex(adapter: @This(), metadata: Metadata) u32 {
13891 if (metadata == .none) return 0;
13892 return @intCast(adapter.builder.metadata_string_map.count() +
13893 @intFromEnum(metadata.unwrap(adapter.builder)) - 1);
13894 }
13895
13896 pub fn getMetadataStringIndex(_: @This(), metadata_string: MetadataString) u32 {
13897 return @intFromEnum(metadata_string);
13898 }
13899 };
13900
13901 const metadata_adapter = MetadataAdapter.init(self, constant_adapter);
13902
13903 // METADATA_BLOCK
13904 if (!self.strip) {
13905 const MetadataBlock = ir.MetadataBlock;
13906 var metadata_block = try module_block.enterSubBlock(MetadataBlock);
13907
13908 const MetadataBlockWriter = @TypeOf(metadata_block);
13909
13910 // Emit all MetadataStrings
13911 {
13912 const strings_offset, const strings_size = blk: {
13913 var strings_offset: u32 = 0;
13914 var strings_size: u32 = 0;
13915 for (1..self.metadata_string_map.count()) |metadata_string_index| {
13916 const metadata_string: MetadataString = @enumFromInt(metadata_string_index);
13917 const slice = metadata_string.slice(self);
13918 strings_offset += bitcode.bitsVBR(@as(u32, @intCast(slice.len)), 6);
13919 strings_size += @intCast(slice.len * 8);
13920 }
13921 break :blk .{
13922 std.mem.alignForward(u32, strings_offset, 32) / 8,
13923 std.mem.alignForward(u32, strings_size, 32) / 8,
13924 };
13925 };
13926
13927 try bitcode.writeBits(
13928 comptime MetadataBlockWriter.abbrevId(MetadataBlock.Strings),
13929 MetadataBlockWriter.abbrev_len,
13930 );
13931
13932 try bitcode.writeVBR(@as(u32, @intCast(self.metadata_string_map.count() - 1)), 6);
13933 try bitcode.writeVBR(strings_offset, 6);
13934
13935 try bitcode.writeVBR(strings_size + strings_offset, 6);
13936
13937 try bitcode.alignTo32();
13938
13939 for (1..self.metadata_string_map.count()) |metadata_string_index| {
13940 const metadata_string: MetadataString = @enumFromInt(metadata_string_index);
13941 const slice = metadata_string.slice(self);
13942 try bitcode.writeVBR(@as(u32, @intCast(slice.len)), 6);
13943 }
13944
13945 try bitcode.alignTo32();
13946
13947 for (1..self.metadata_string_map.count()) |metadata_string_index| {
13948 const metadata_string: MetadataString = @enumFromInt(metadata_string_index);
13949 const slice = metadata_string.slice(self);
13950 for (slice) |c| {
13951 try bitcode.writeBits(c, 8);
13952 }
13953 }
13954
13955 try bitcode.alignTo32();
13956 }
13957
13958 for (
13959 self.metadata_items.items(.tag)[1..],
13960 self.metadata_items.items(.data)[1..],
13961 ) |tag, data| {
13962 switch (tag) {
13963 .none => unreachable,
13964 .file => {
13965 const extra = self.metadataExtraData(Metadata.File, data);
13966
13967 try metadata_block.writeAbbrevAdapted(MetadataBlock.File{
13968 .filename = extra.filename,
13969 .directory = extra.directory,
13970 }, metadata_adapter);
13971 },
13972 .compile_unit,
13973 .@"compile_unit optimized",
13974 => |kind| {
13975 const extra = self.metadataExtraData(Metadata.CompileUnit, data);
13976 try metadata_block.writeAbbrevAdapted(MetadataBlock.CompileUnit{
13977 .file = extra.file,
13978 .producer = extra.producer,
13979 .is_optimized = switch (kind) {
13980 .compile_unit => false,
13981 .@"compile_unit optimized" => true,
13982 else => unreachable,
13983 },
13984 .enums = extra.enums,
13985 .globals = extra.globals,
13986 }, metadata_adapter);
13987 },
13988 .subprogram,
13989 .@"subprogram local",
13990 .@"subprogram definition",
13991 .@"subprogram local definition",
13992 .@"subprogram optimized",
13993 .@"subprogram optimized local",
13994 .@"subprogram optimized definition",
13995 .@"subprogram optimized local definition",
13996 => |kind| {
13997 const extra = self.metadataExtraData(Metadata.Subprogram, data);
13998
13999 try metadata_block.writeAbbrevAdapted(MetadataBlock.Subprogram{
14000 .scope = extra.file,
14001 .name = extra.name,
14002 .linkage_name = extra.linkage_name,
14003 .file = extra.file,
14004 .line = extra.line,
14005 .ty = extra.ty,
14006 .scope_line = extra.scope_line,
14007 .sp_flags = @bitCast(@as(u32, @as(u3, @intCast(
14008 @intFromEnum(kind) - @intFromEnum(Metadata.Tag.subprogram),
14009 ))) << 2),
14010 .flags = extra.di_flags,
14011 .compile_unit = extra.compile_unit,
14012 }, metadata_adapter);
14013 },
14014 .lexical_block => {
14015 const extra = self.metadataExtraData(Metadata.LexicalBlock, data);
14016 try metadata_block.writeAbbrevAdapted(MetadataBlock.LexicalBlock{
14017 .scope = extra.scope,
14018 .file = extra.file,
14019 .line = extra.line,
14020 .column = extra.column,
14021 }, metadata_adapter);
14022 },
14023 .location => {
14024 const extra = self.metadataExtraData(Metadata.Location, data);
14025 assert(extra.scope != .none);
14026 try metadata_block.writeAbbrev(MetadataBlock.Location{
14027 .line = extra.line,
14028 .column = extra.column,
14029 .scope = metadata_adapter.getMetadataIndex(extra.scope) - 1,
14030 .inlined_at = @enumFromInt(metadata_adapter.getMetadataIndex(extra.inlined_at)),
14031 });
14032 },
14033 .basic_bool_type,
14034 .basic_unsigned_type,
14035 .basic_signed_type,
14036 .basic_float_type,
14037 => |kind| {
14038 const extra = self.metadataExtraData(Metadata.BasicType, data);
14039 try metadata_block.writeAbbrevAdapted(MetadataBlock.BasicType{
14040 .name = extra.name,
14041 .size_in_bits = extra.bitSize(),
14042 .encoding = switch (kind) {
14043 .basic_bool_type => DW.ATE.boolean,
14044 .basic_unsigned_type => DW.ATE.unsigned,
14045 .basic_signed_type => DW.ATE.signed,
14046 .basic_float_type => DW.ATE.float,
14047 else => unreachable,
14048 },
14049 }, metadata_adapter);
14050 },
14051 .composite_struct_type,
14052 .composite_union_type,
14053 .composite_enumeration_type,
14054 .composite_array_type,
14055 .composite_vector_type,
14056 => |kind| {
14057 const extra = self.metadataExtraData(Metadata.CompositeType, data);
14058
14059 try metadata_block.writeAbbrevAdapted(MetadataBlock.CompositeType{
14060 .tag = switch (kind) {
14061 .composite_struct_type => DW.TAG.structure_type,
14062 .composite_union_type => DW.TAG.union_type,
14063 .composite_enumeration_type => DW.TAG.enumeration_type,
14064 .composite_array_type, .composite_vector_type => DW.TAG.array_type,
14065 else => unreachable,
14066 },
14067 .name = extra.name,
14068 .file = extra.file,
14069 .line = extra.line,
14070 .scope = extra.scope,
14071 .underlying_type = extra.underlying_type,
14072 .size_in_bits = extra.bitSize(),
14073 .align_in_bits = extra.bitAlign(),
14074 .flags = if (kind == .composite_vector_type) .{ .Vector = true } else .{},
14075 .elements = extra.fields_tuple,
14076 }, metadata_adapter);
14077 },
14078 .derived_pointer_type,
14079 .derived_member_type,
14080 => |kind| {
14081 const extra = self.metadataExtraData(Metadata.DerivedType, data);
14082 try metadata_block.writeAbbrevAdapted(MetadataBlock.DerivedType{
14083 .tag = switch (kind) {
14084 .derived_pointer_type => DW.TAG.pointer_type,
14085 .derived_member_type => DW.TAG.member,
14086 else => unreachable,
14087 },
14088 .name = extra.name,
14089 .file = extra.file,
14090 .line = extra.line,
14091 .scope = extra.scope,
14092 .underlying_type = extra.underlying_type,
14093 .size_in_bits = extra.bitSize(),
14094 .align_in_bits = extra.bitAlign(),
14095 .offset_in_bits = extra.bitOffset(),
14096 }, metadata_adapter);
14097 },
14098 .subroutine_type => {
14099 const extra = self.metadataExtraData(Metadata.SubroutineType, data);
14100
14101 try metadata_block.writeAbbrevAdapted(MetadataBlock.SubroutineType{
14102 .types = extra.types_tuple,
14103 }, metadata_adapter);
14104 },
14105 .enumerator_unsigned,
14106 .enumerator_signed_positive,
14107 .enumerator_signed_negative,
14108 => |kind| {
14109 const positive = switch (kind) {
14110 .enumerator_unsigned,
14111 .enumerator_signed_positive,
14112 => true,
14113 .enumerator_signed_negative => false,
14114 else => unreachable,
14115 };
14116
14117 const unsigned = switch (kind) {
14118 .enumerator_unsigned => true,
14119 .enumerator_signed_positive,
14120 .enumerator_signed_negative,
14121 => false,
14122 else => unreachable,
14123 };
14124
14125 const extra = self.metadataExtraData(Metadata.Enumerator, data);
14126
14127 const limbs = self.metadata_limbs.items[extra.limbs_index..][0..extra.limbs_len];
14128
14129 const bigint: std.math.big.int.Const = .{
14130 .limbs = limbs,
14131 .positive = positive,
14132 };
14133
14134 if (extra.bit_width <= 64) {
14135 const val = bigint.to(i64) catch unreachable;
14136 const emit_val = if (positive)
14137 @shlWithOverflow(val, 1)[0]
14138 else
14139 (@shlWithOverflow(@addWithOverflow(~val, 1)[0], 1)[0] | 1);
14140 try metadata_block.writeAbbrevAdapted(MetadataBlock.Enumerator{
14141 .flags = .{
14142 .unsigned = unsigned,
14143 .bigint = false,
14144 },
14145 .bit_width = extra.bit_width,
14146 .name = extra.name,
14147 .value = @bitCast(emit_val),
14148 }, metadata_adapter);
14149 } else {
14150 const word_count = std.mem.alignForward(u32, extra.bit_width, 64) / 64;
14151 try record.ensureUnusedCapacity(self.gpa, 3 + word_count);
14152
14153 const flags: MetadataBlock.Enumerator.Flags = .{
14154 .unsigned = unsigned,
14155 .bigint = true,
14156 };
14157
14158 const FlagsInt = @typeInfo(MetadataBlock.Enumerator.Flags).Struct.backing_integer.?;
14159
14160 const flags_int: FlagsInt = @bitCast(flags);
14161
14162 record.appendAssumeCapacity(@intCast(flags_int));
14163 record.appendAssumeCapacity(@intCast(extra.bit_width));
14164 record.appendAssumeCapacity(metadata_adapter.getMetadataStringIndex(extra.name));
14165
14166 const buffer: [*]u8 = @ptrCast(record.items.ptr);
14167 bigint.writeTwosComplement(buffer[0..(word_count * 8)], .little);
14168
14169 const signed_buffer: [*]i64 = @ptrCast(record.items.ptr);
14170 for (signed_buffer[0..word_count], 0..) |val, i| {
14171 signed_buffer[i] = if (val >= 0)
14172 @shlWithOverflow(val, 1)[0]
14173 else
14174 (@shlWithOverflow(@addWithOverflow(~val, 1)[0], 1)[0] | 1);
14175 }
14176
14177 try metadata_block.writeUnabbrev(
14178 MetadataBlock.Enumerator.id,
14179 record.items.ptr[0..(3 + word_count)],
14180 );
14181 }
14182 },
14183 .subrange => {
14184 const extra = self.metadataExtraData(Metadata.Subrange, data);
14185
14186 try metadata_block.writeAbbrevAdapted(MetadataBlock.Subrange{
14187 .count = extra.count,
14188 .lower_bound = extra.lower_bound,
14189 }, metadata_adapter);
14190 },
14191 .expression => {
14192 var extra = self.metadataExtraDataTrail(Metadata.Expression, data);
14193
14194 const elements = extra.trail.next(extra.data.elements_len, u32, self);
14195
14196 try metadata_block.writeAbbrevAdapted(MetadataBlock.Expression{
14197 .elements = elements,
14198 }, metadata_adapter);
14199 },
14200 .tuple => {
14201 var extra = self.metadataExtraDataTrail(Metadata.Tuple, data);
14202
14203 const elements = extra.trail.next(extra.data.elements_len, Metadata, self);
14204
14205 try metadata_block.writeAbbrevAdapted(MetadataBlock.Node{
14206 .elements = elements,
14207 }, metadata_adapter);
14208 },
14209 .module_flag => {
14210 const extra = self.metadataExtraData(Metadata.ModuleFlag, data);
14211 try metadata_block.writeAbbrev(MetadataBlock.Node{
14212 .elements = &.{
14213 @enumFromInt(metadata_adapter.getMetadataIndex(extra.behavior)),
14214 @enumFromInt(metadata_adapter.getMetadataStringIndex(extra.name)),
14215 @enumFromInt(metadata_adapter.getMetadataIndex(extra.constant)),
14216 },
14217 });
14218 },
14219 .local_var => {
14220 const extra = self.metadataExtraData(Metadata.LocalVar, data);
14221 try metadata_block.writeAbbrevAdapted(MetadataBlock.LocalVar{
14222 .scope = extra.scope,
14223 .name = extra.name,
14224 .file = extra.file,
14225 .line = extra.line,
14226 .ty = extra.ty,
14227 }, metadata_adapter);
14228 },
14229 .parameter => {
14230 const extra = self.metadataExtraData(Metadata.Parameter, data);
14231 try metadata_block.writeAbbrevAdapted(MetadataBlock.Parameter{
14232 .scope = extra.scope,
14233 .name = extra.name,
14234 .file = extra.file,
14235 .line = extra.line,
14236 .ty = extra.ty,
14237 .arg = extra.arg_no,
14238 }, metadata_adapter);
14239 },
14240 .global_var,
14241 .@"global_var local",
14242 => |kind| {
14243 const extra = self.metadataExtraData(Metadata.GlobalVar, data);
14244 try metadata_block.writeAbbrevAdapted(MetadataBlock.GlobalVar{
14245 .scope = extra.scope,
14246 .name = extra.name,
14247 .linkage_name = extra.linkage_name,
14248 .file = extra.file,
14249 .line = extra.line,
14250 .ty = extra.ty,
14251 .local = kind == .@"global_var local",
14252 }, metadata_adapter);
14253 },
14254 .global_var_expression => {
14255 const extra = self.metadataExtraData(Metadata.GlobalVarExpression, data);
14256 try metadata_block.writeAbbrevAdapted(MetadataBlock.GlobalVarExpression{
14257 .variable = extra.variable,
14258 .expression = extra.expression,
14259 }, metadata_adapter);
14260 },
14261 .constant => {
14262 const constant: Constant = @enumFromInt(data);
14263 try metadata_block.writeAbbrevAdapted(MetadataBlock.Constant{
14264 .ty = constant.typeOf(self),
14265 .constant = constant,
14266 }, metadata_adapter);
14267 },
14268 }
14269 record.clearRetainingCapacity();
14270 }
14271
14272 // Write named metadata
14273 for (self.metadata_named.keys(), self.metadata_named.values()) |name, operands| {
14274 const slice = name.slice(self);
14275 try metadata_block.writeAbbrev(MetadataBlock.Name{
14276 .name = slice,
14277 });
14278
14279 const elements = self.metadata_extra.items[operands.index..][0..operands.len];
14280 for (elements) |*e| {
14281 e.* = metadata_adapter.getMetadataIndex(@enumFromInt(e.*)) - 1;
14282 }
14283
14284 try metadata_block.writeAbbrev(MetadataBlock.NamedNode{
14285 .elements = @ptrCast(elements),
14286 });
14287 }
14288
14289 // Write global attached metadata
14290 {
14291 for (globals.keys()) |global| {
14292 const global_ptr = global.ptrConst(self);
14293 if (global_ptr.dbg == .none) continue;
14294
14295 switch (global_ptr.kind) {
14296 .function => |f| if (f.ptrConst(self).instructions.len != 0) continue,
14297 else => {},
14298 }
14299
14300 try metadata_block.writeAbbrev(MetadataBlock.GlobalDeclAttachment{
14301 .value = @enumFromInt(constant_adapter.getConstantIndex(global.toConst())),
14302 .kind = ir.MetadataKind.dbg,
14303 .metadata = @enumFromInt(metadata_adapter.getMetadataIndex(global_ptr.dbg) - 1),
14304 });
14305 }
14306 }
14307
14308 try metadata_block.end();
14309 }
14310
14311 // FUNCTION_BLOCKS
14312 {
14313 const FunctionAdapter = struct {
14314 constant_adapter: ConstantAdapter,
14315 metadata_adapter: MetadataAdapter,
14316 func: *const Function,
14317 instruction_index: u32 = 0,
14318
14319 pub fn init(
14320 const_adapter: ConstantAdapter,
14321 meta_adapter: MetadataAdapter,
14322 func: *const Function,
14323 ) @This() {
14324 return .{
14325 .constant_adapter = const_adapter,
14326 .metadata_adapter = meta_adapter,
14327 .func = func,
14328 .instruction_index = 0,
14329 };
14330 }
14331
14332 pub fn get(adapter: @This(), value: anytype, comptime field_name: []const u8) @TypeOf(value) {
14333 _ = field_name;
14334 const Ty = @TypeOf(value);
14335 return switch (Ty) {
14336 Value => @enumFromInt(adapter.getOffsetValueIndex(value)),
14337 Constant => @enumFromInt(adapter.getOffsetConstantIndex(value)),
14338 FunctionAttributes => @enumFromInt(switch (value) {
14339 .none => 0,
14340 else => 1 + adapter.constant_adapter.builder.function_attributes_set.getIndex(value).?,
14341 }),
14342 else => value,
14343 };
14344 }
14345
14346 pub fn getValueIndex(adapter: @This(), value: Value) u32 {
14347 return @intCast(switch (value.unwrap()) {
14348 .instruction => |instruction| instruction.valueIndex(adapter.func) + adapter.firstInstr(),
14349 .constant => |constant| adapter.constant_adapter.getConstantIndex(constant),
14350 .metadata => |metadata| if (!adapter.metadata_adapter.builder.strip) blk: {
14351 const real_metadata = metadata.unwrap(adapter.metadata_adapter.builder);
14352 if (@intFromEnum(real_metadata) < Metadata.first_local_metadata)
14353 break :blk adapter.metadata_adapter.getMetadataIndex(real_metadata) - 1;
14354
14355 return @intCast(@intFromEnum(metadata) -
14356 Metadata.first_local_metadata +
14357 adapter.metadata_adapter.builder.metadata_string_map.count() - 1 +
14358 adapter.metadata_adapter.builder.metadata_map.count() - 1);
14359 } else unreachable,
14360 });
14361 }
14362
14363 pub fn getOffsetValueIndex(adapter: @This(), value: Value) u32 {
14364 return @subWithOverflow(adapter.offset(), adapter.getValueIndex(value))[0];
14365 }
14366
14367 pub fn getOffsetValueSignedIndex(adapter: @This(), value: Value) i32 {
14368 const signed_offset: i32 = @intCast(adapter.offset());
14369 const signed_value: i32 = @intCast(adapter.getValueIndex(value));
14370 return signed_offset - signed_value;
14371 }
14372
14373 pub fn getOffsetConstantIndex(adapter: @This(), constant: Constant) u32 {
14374 return adapter.offset() - adapter.constant_adapter.getConstantIndex(constant);
14375 }
14376
14377 pub fn offset(adapter: @This()) u32 {
14378 return @as(
14379 Function.Instruction.Index,
14380 @enumFromInt(adapter.instruction_index),
14381 ).valueIndex(adapter.func) + adapter.firstInstr();
14382 }
14383
14384 fn firstInstr(adapter: @This()) u32 {
14385 return adapter.constant_adapter.numConstants();
14386 }
14387
14388 pub fn next(adapter: *@This()) void {
14389 adapter.instruction_index += 1;
14390 }
14391 };
14392
14393 for (self.functions.items, 0..) |func, func_index| {
14394 const FunctionBlock = ir.FunctionBlock;
14395 if (func.global.getReplacement(self) != .none) continue;
14396
14397 if (func.instructions.len == 0) continue;
14398
14399 var function_block = try module_block.enterSubBlock(FunctionBlock);
14400
14401 try function_block.writeAbbrev(FunctionBlock.DeclareBlocks{ .num_blocks = func.blocks.len });
14402
14403 var adapter = FunctionAdapter.init(constant_adapter, metadata_adapter, &func);
14404
14405 // Emit function level metadata block
14406 if (!self.strip and func.debug_values.len != 0) {
14407 const MetadataBlock = ir.FunctionMetadataBlock;
14408 var metadata_block = try function_block.enterSubBlock(MetadataBlock);
14409
14410 for (func.debug_values) |value| {
14411 try metadata_block.writeAbbrev(MetadataBlock.Value{
14412 .ty = value.typeOf(@enumFromInt(func_index), self),
14413 .value = @enumFromInt(adapter.getValueIndex(value.toValue())),
14414 });
14415 }
14416
14417 try metadata_block.end();
14418 }
14419
14420 const tags = func.instructions.items(.tag);
14421 const datas = func.instructions.items(.data);
14422
14423 var has_location = false;
14424
14425 var block_incoming_len: u32 = undefined;
14426 for (0..func.instructions.len) |instr_index| {
14427 const tag = tags[instr_index];
14428
14429 record.clearRetainingCapacity();
14430
14431 switch (tag) {
14432 .block => block_incoming_len = datas[instr_index],
14433 .arg => {},
14434 .@"unreachable" => try function_block.writeAbbrev(FunctionBlock.Unreachable{}),
14435 .call,
14436 .@"musttail call",
14437 .@"notail call",
14438 .@"tail call",
14439 => |kind| {
14440 var extra = func.extraDataTrail(Function.Instruction.Call, datas[instr_index]);
14441
14442 const call_conv = extra.data.info.call_conv;
14443 const args = extra.trail.next(extra.data.args_len, Value, &func);
14444 try function_block.writeAbbrevAdapted(FunctionBlock.Call{
14445 .attributes = extra.data.attributes,
14446 .call_type = switch (kind) {
14447 .call => .{ .call_conv = call_conv },
14448 .@"tail call" => .{ .tail = true, .call_conv = call_conv },
14449 .@"musttail call" => .{ .must_tail = true, .call_conv = call_conv },
14450 .@"notail call" => .{ .no_tail = true, .call_conv = call_conv },
14451 else => unreachable,
14452 },
14453 .type_id = extra.data.ty,
14454 .callee = extra.data.callee,
14455 .args = args,
14456 }, adapter);
14457 },
14458 .@"call fast",
14459 .@"musttail call fast",
14460 .@"notail call fast",
14461 .@"tail call fast",
14462 => |kind| {
14463 var extra = func.extraDataTrail(Function.Instruction.Call, datas[instr_index]);
14464
14465 const call_conv = extra.data.info.call_conv;
14466 const args = extra.trail.next(extra.data.args_len, Value, &func);
14467 try function_block.writeAbbrevAdapted(FunctionBlock.CallFast{
14468 .attributes = extra.data.attributes,
14469 .call_type = switch (kind) {
14470 .call => .{ .call_conv = call_conv },
14471 .@"tail call" => .{ .tail = true, .call_conv = call_conv },
14472 .@"musttail call" => .{ .must_tail = true, .call_conv = call_conv },
14473 .@"notail call" => .{ .no_tail = true, .call_conv = call_conv },
14474 else => unreachable,
14475 },
14476 .fast_math = .{},
14477 .type_id = extra.data.ty,
14478 .callee = extra.data.callee,
14479 .args = args,
14480 }, adapter);
14481 },
14482 .add,
14483 .@"add nsw",
14484 .@"add nuw",
14485 .@"add nuw nsw",
14486 .@"and",
14487 .fadd,
14488 .fdiv,
14489 .fmul,
14490 .mul,
14491 .@"mul nsw",
14492 .@"mul nuw",
14493 .@"mul nuw nsw",
14494 .frem,
14495 .fsub,
14496 .sdiv,
14497 .@"sdiv exact",
14498 .sub,
14499 .@"sub nsw",
14500 .@"sub nuw",
14501 .@"sub nuw nsw",
14502 .udiv,
14503 .@"udiv exact",
14504 .xor,
14505 .shl,
14506 .@"shl nsw",
14507 .@"shl nuw",
14508 .@"shl nuw nsw",
14509 .lshr,
14510 .@"lshr exact",
14511 .@"or",
14512 .urem,
14513 .srem,
14514 .ashr,
14515 .@"ashr exact",
14516 => |kind| {
14517 const extra = func.extraData(Function.Instruction.Binary, datas[instr_index]);
14518 try function_block.writeAbbrev(FunctionBlock.Binary{
14519 .opcode = kind.toBinaryOpcode(),
14520 .lhs = adapter.getOffsetValueIndex(extra.lhs),
14521 .rhs = adapter.getOffsetValueIndex(extra.rhs),
14522 });
14523 },
14524 .@"fadd fast",
14525 .@"fdiv fast",
14526 .@"fmul fast",
14527 .@"frem fast",
14528 .@"fsub fast",
14529 => |kind| {
14530 const extra = func.extraData(Function.Instruction.Binary, datas[instr_index]);
14531 try function_block.writeAbbrev(FunctionBlock.BinaryFast{
14532 .opcode = kind.toBinaryOpcode(),
14533 .lhs = adapter.getOffsetValueIndex(extra.lhs),
14534 .rhs = adapter.getOffsetValueIndex(extra.rhs),
14535 .fast_math = .{},
14536 });
14537 },
14538 .alloca,
14539 .@"alloca inalloca",
14540 => |kind| {
14541 const extra = func.extraData(Function.Instruction.Alloca, datas[instr_index]);
14542 const alignment = extra.info.alignment.toLlvm();
14543 try function_block.writeAbbrev(FunctionBlock.Alloca{
14544 .inst_type = extra.type,
14545 .len_type = extra.len.typeOf(@enumFromInt(func_index), self),
14546 .len_value = adapter.getValueIndex(extra.len),
14547 .flags = .{
14548 .align_lower = @truncate(alignment),
14549 .inalloca = kind == .@"alloca inalloca",
14550 .explicit_type = true,
14551 .swift_error = false,
14552 .align_upper = @truncate(alignment << 5),
14553 },
14554 });
14555 },
14556 .bitcast,
14557 .inttoptr,
14558 .ptrtoint,
14559 .fptosi,
14560 .fptoui,
14561 .sitofp,
14562 .uitofp,
14563 .addrspacecast,
14564 .fptrunc,
14565 .trunc,
14566 .fpext,
14567 .sext,
14568 .zext,
14569 => |kind| {
14570 const extra = func.extraData(Function.Instruction.Cast, datas[instr_index]);
14571 try function_block.writeAbbrev(FunctionBlock.Cast{
14572 .val = adapter.getOffsetValueIndex(extra.val),
14573 .type_index = extra.type,
14574 .opcode = kind.toCastOpcode(),
14575 });
14576 },
14577 .@"fcmp false",
14578 .@"fcmp oeq",
14579 .@"fcmp oge",
14580 .@"fcmp ogt",
14581 .@"fcmp ole",
14582 .@"fcmp olt",
14583 .@"fcmp one",
14584 .@"fcmp ord",
14585 .@"fcmp true",
14586 .@"fcmp ueq",
14587 .@"fcmp uge",
14588 .@"fcmp ugt",
14589 .@"fcmp ule",
14590 .@"fcmp ult",
14591 .@"fcmp une",
14592 .@"fcmp uno",
14593 .@"icmp eq",
14594 .@"icmp ne",
14595 .@"icmp sge",
14596 .@"icmp sgt",
14597 .@"icmp sle",
14598 .@"icmp slt",
14599 .@"icmp uge",
14600 .@"icmp ugt",
14601 .@"icmp ule",
14602 .@"icmp ult",
14603 => |kind| {
14604 const extra = func.extraData(Function.Instruction.Binary, datas[instr_index]);
14605 try function_block.writeAbbrev(FunctionBlock.Cmp{
14606 .lhs = adapter.getOffsetValueIndex(extra.lhs),
14607 .rhs = adapter.getOffsetValueIndex(extra.rhs),
14608 .pred = kind.toCmpPredicate(),
14609 });
14610 },
14611 .@"fcmp fast false",
14612 .@"fcmp fast oeq",
14613 .@"fcmp fast oge",
14614 .@"fcmp fast ogt",
14615 .@"fcmp fast ole",
14616 .@"fcmp fast olt",
14617 .@"fcmp fast one",
14618 .@"fcmp fast ord",
14619 .@"fcmp fast true",
14620 .@"fcmp fast ueq",
14621 .@"fcmp fast uge",
14622 .@"fcmp fast ugt",
14623 .@"fcmp fast ule",
14624 .@"fcmp fast ult",
14625 .@"fcmp fast une",
14626 .@"fcmp fast uno",
14627 => |kind| {
14628 const extra = func.extraData(Function.Instruction.Binary, datas[instr_index]);
14629 try function_block.writeAbbrev(FunctionBlock.CmpFast{
14630 .lhs = adapter.getOffsetValueIndex(extra.lhs),
14631 .rhs = adapter.getOffsetValueIndex(extra.rhs),
14632 .pred = kind.toCmpPredicate(),
14633 .fast_math = .{},
14634 });
14635 },
14636 .fneg => try function_block.writeAbbrev(FunctionBlock.FNeg{
14637 .val = adapter.getOffsetValueIndex(@enumFromInt(datas[instr_index])),
14638 }),
14639 .@"fneg fast" => try function_block.writeAbbrev(FunctionBlock.FNegFast{
14640 .val = adapter.getOffsetValueIndex(@enumFromInt(datas[instr_index])),
14641 .fast_math = .{},
14642 }),
14643 .extractvalue => {
14644 var extra = func.extraDataTrail(Function.Instruction.ExtractValue, datas[instr_index]);
14645 const indices = extra.trail.next(extra.data.indices_len, u32, &func);
14646 try function_block.writeAbbrev(FunctionBlock.ExtractValue{
14647 .val = adapter.getOffsetValueIndex(extra.data.val),
14648 .indices = indices,
14649 });
14650 },
14651 .insertvalue => {
14652 var extra = func.extraDataTrail(Function.Instruction.InsertValue, datas[instr_index]);
14653 const indices = extra.trail.next(extra.data.indices_len, u32, &func);
14654 try function_block.writeAbbrev(FunctionBlock.InsertValue{
14655 .val = adapter.getOffsetValueIndex(extra.data.val),
14656 .elem = adapter.getOffsetValueIndex(extra.data.elem),
14657 .indices = indices,
14658 });
14659 },
14660 .extractelement => {
14661 const extra = func.extraData(Function.Instruction.ExtractElement, datas[instr_index]);
14662 try function_block.writeAbbrev(FunctionBlock.ExtractElement{
14663 .val = adapter.getOffsetValueIndex(extra.val),
14664 .index = adapter.getOffsetValueIndex(extra.index),
14665 });
14666 },
14667 .insertelement => {
14668 const extra = func.extraData(Function.Instruction.InsertElement, datas[instr_index]);
14669 try function_block.writeAbbrev(FunctionBlock.InsertElement{
14670 .val = adapter.getOffsetValueIndex(extra.val),
14671 .elem = adapter.getOffsetValueIndex(extra.elem),
14672 .index = adapter.getOffsetValueIndex(extra.index),
14673 });
14674 },
14675 .select => {
14676 const extra = func.extraData(Function.Instruction.Select, datas[instr_index]);
14677 try function_block.writeAbbrev(FunctionBlock.Select{
14678 .lhs = adapter.getOffsetValueIndex(extra.lhs),
14679 .rhs = adapter.getOffsetValueIndex(extra.rhs),
14680 .cond = adapter.getOffsetValueIndex(extra.cond),
14681 });
14682 },
14683 .@"select fast" => {
14684 const extra = func.extraData(Function.Instruction.Select, datas[instr_index]);
14685 try function_block.writeAbbrev(FunctionBlock.SelectFast{
14686 .lhs = adapter.getOffsetValueIndex(extra.lhs),
14687 .rhs = adapter.getOffsetValueIndex(extra.rhs),
14688 .cond = adapter.getOffsetValueIndex(extra.cond),
14689 .fast_math = .{},
14690 });
14691 },
14692 .shufflevector => {
14693 const extra = func.extraData(Function.Instruction.ShuffleVector, datas[instr_index]);
14694 try function_block.writeAbbrev(FunctionBlock.ShuffleVector{
14695 .lhs = adapter.getOffsetValueIndex(extra.lhs),
14696 .rhs = adapter.getOffsetValueIndex(extra.rhs),
14697 .mask = adapter.getOffsetValueIndex(extra.mask),
14698 });
14699 },
14700 .getelementptr,
14701 .@"getelementptr inbounds",
14702 => |kind| {
14703 var extra = func.extraDataTrail(Function.Instruction.GetElementPtr, datas[instr_index]);
14704 const indices = extra.trail.next(extra.data.indices_len, Value, &func);
14705 try function_block.writeAbbrevAdapted(
14706 FunctionBlock.GetElementPtr{
14707 .is_inbounds = kind == .@"getelementptr inbounds",
14708 .type_index = extra.data.type,
14709 .base = extra.data.base,
14710 .indices = indices,
14711 },
14712 adapter,
14713 );
14714 },
14715 .load => {
14716 const extra = func.extraData(Function.Instruction.Load, datas[instr_index]);
14717 try function_block.writeAbbrev(FunctionBlock.Load{
14718 .ptr = adapter.getOffsetValueIndex(extra.ptr),
14719 .ty = extra.type,
14720 .alignment = extra.info.alignment.toLlvm(),
14721 .is_volatile = extra.info.access_kind == .@"volatile",
14722 });
14723 },
14724 .@"load atomic" => {
14725 const extra = func.extraData(Function.Instruction.Load, datas[instr_index]);
14726 try function_block.writeAbbrev(FunctionBlock.LoadAtomic{
14727 .ptr = adapter.getOffsetValueIndex(extra.ptr),
14728 .ty = extra.type,
14729 .alignment = extra.info.alignment.toLlvm(),
14730 .is_volatile = extra.info.access_kind == .@"volatile",
14731 .success_ordering = extra.info.success_ordering,
14732 .sync_scope = extra.info.sync_scope,
14733 });
14734 },
14735 .store => {
14736 const extra = func.extraData(Function.Instruction.Store, datas[instr_index]);
14737 try function_block.writeAbbrev(FunctionBlock.Store{
14738 .ptr = adapter.getOffsetValueIndex(extra.ptr),
14739 .val = adapter.getOffsetValueIndex(extra.val),
14740 .alignment = extra.info.alignment.toLlvm(),
14741 .is_volatile = extra.info.access_kind == .@"volatile",
14742 });
14743 },
14744 .@"store atomic" => {
14745 const extra = func.extraData(Function.Instruction.Store, datas[instr_index]);
14746 try function_block.writeAbbrev(FunctionBlock.StoreAtomic{
14747 .ptr = adapter.getOffsetValueIndex(extra.ptr),
14748 .val = adapter.getOffsetValueIndex(extra.val),
14749 .alignment = extra.info.alignment.toLlvm(),
14750 .is_volatile = extra.info.access_kind == .@"volatile",
14751 .success_ordering = extra.info.success_ordering,
14752 .sync_scope = extra.info.sync_scope,
14753 });
14754 },
14755 .br => {
14756 try function_block.writeAbbrev(FunctionBlock.BrUnconditional{
14757 .block = datas[instr_index],
14758 });
14759 },
14760 .br_cond => {
14761 const extra = func.extraData(Function.Instruction.BrCond, datas[instr_index]);
14762 try function_block.writeAbbrev(FunctionBlock.BrConditional{
14763 .then_block = @intFromEnum(extra.then),
14764 .else_block = @intFromEnum(extra.@"else"),
14765 .condition = adapter.getOffsetValueIndex(extra.cond),
14766 });
14767 },
14768 .@"switch" => {
14769 var extra = func.extraDataTrail(Function.Instruction.Switch, datas[instr_index]);
14770
14771 try record.ensureUnusedCapacity(self.gpa, 3 + extra.data.cases_len * 2);
14772
14773 // Conditional type
14774 record.appendAssumeCapacity(@intFromEnum(extra.data.val.typeOf(@enumFromInt(func_index), self)));
14775
14776 // Conditional
14777 record.appendAssumeCapacity(adapter.getOffsetValueIndex(extra.data.val));
14778
14779 // Default block
14780 record.appendAssumeCapacity(@intFromEnum(extra.data.default));
14781
14782 const vals = extra.trail.next(extra.data.cases_len, Constant, &func);
14783 const blocks = extra.trail.next(extra.data.cases_len, Function.Block.Index, &func);
14784 for (vals, blocks) |val, block| {
14785 record.appendAssumeCapacity(adapter.constant_adapter.getConstantIndex(val));
14786 record.appendAssumeCapacity(@intFromEnum(block));
14787 }
14788
14789 try function_block.writeUnabbrev(12, record.items);
14790 },
14791 .va_arg => {
14792 const extra = func.extraData(Function.Instruction.VaArg, datas[instr_index]);
14793 try function_block.writeAbbrev(FunctionBlock.VaArg{
14794 .list_type = extra.list.typeOf(@enumFromInt(func_index), self),
14795 .list = adapter.getOffsetValueIndex(extra.list),
14796 .type = extra.type,
14797 });
14798 },
14799 .phi,
14800 .@"phi fast",
14801 => |kind| {
14802 var extra = func.extraDataTrail(Function.Instruction.Phi, datas[instr_index]);
14803 const vals = extra.trail.next(block_incoming_len, Value, &func);
14804 const blocks = extra.trail.next(block_incoming_len, Function.Block.Index, &func);
14805
14806 try record.ensureUnusedCapacity(
14807 self.gpa,
14808 1 + block_incoming_len * 2 + @intFromBool(kind == .@"phi fast"),
14809 );
14810
14811 record.appendAssumeCapacity(@intFromEnum(extra.data.type));
14812
14813 for (vals, blocks) |val, block| {
14814 const offset_value = adapter.getOffsetValueSignedIndex(val);
14815 const abs_value: u32 = @intCast(@abs(offset_value));
14816 const signed_vbr = if (offset_value > 0) abs_value << 1 else ((abs_value << 1) | 1);
14817 record.appendAssumeCapacity(signed_vbr);
14818 record.appendAssumeCapacity(@intFromEnum(block));
14819 }
14820
14821 if (kind == .@"phi fast") record.appendAssumeCapacity(@as(u8, @bitCast(FastMath{})));
14822
14823 try function_block.writeUnabbrev(16, record.items);
14824 },
14825 .ret => try function_block.writeAbbrev(FunctionBlock.Ret{
14826 .val = adapter.getOffsetValueIndex(@enumFromInt(datas[instr_index])),
14827 }),
14828 .@"ret void" => try function_block.writeAbbrev(FunctionBlock.RetVoid{}),
14829 .atomicrmw => {
14830 const extra = func.extraData(Function.Instruction.AtomicRmw, datas[instr_index]);
14831 try function_block.writeAbbrev(FunctionBlock.AtomicRmw{
14832 .ptr = adapter.getOffsetValueIndex(extra.ptr),
14833 .val = adapter.getOffsetValueIndex(extra.val),
14834 .operation = extra.info.atomic_rmw_operation,
14835 .is_volatile = extra.info.access_kind == .@"volatile",
14836 .success_ordering = extra.info.success_ordering,
14837 .sync_scope = extra.info.sync_scope,
14838 .alignment = extra.info.alignment.toLlvm(),
14839 });
14840 },
14841 .cmpxchg,
14842 .@"cmpxchg weak",
14843 => |kind| {
14844 const extra = func.extraData(Function.Instruction.CmpXchg, datas[instr_index]);
14845
14846 try function_block.writeAbbrev(FunctionBlock.CmpXchg{
14847 .ptr = adapter.getOffsetValueIndex(extra.ptr),
14848 .cmp = adapter.getOffsetValueIndex(extra.cmp),
14849 .new = adapter.getOffsetValueIndex(extra.new),
14850 .is_volatile = extra.info.access_kind == .@"volatile",
14851 .success_ordering = extra.info.success_ordering,
14852 .sync_scope = extra.info.sync_scope,
14853 .failure_ordering = extra.info.failure_ordering,
14854 .is_weak = kind == .@"cmpxchg weak",
14855 .alignment = extra.info.alignment.toLlvm(),
14856 });
14857 },
14858 .fence => {
14859 const info: MemoryAccessInfo = @bitCast(datas[instr_index]);
14860 try function_block.writeAbbrev(FunctionBlock.Fence{
14861 .ordering = info.success_ordering,
14862 .sync_scope = info.sync_scope,
14863 });
14864 },
14865 }
14866
14867 if (!self.strip) {
14868 if (func.debug_locations.get(@enumFromInt(instr_index))) |debug_location| {
14869 if (debug_location != .none) {
14870 const location = self.metadata_items.get(@intFromEnum(debug_location));
14871 assert(location.tag == .location);
14872 const extra = self.metadataExtraData(Metadata.Location, location.data);
14873 try function_block.writeAbbrev(FunctionBlock.DebugLoc{
14874 .line = extra.line,
14875 .column = extra.column,
14876 .scope = @enumFromInt(metadata_adapter.getMetadataIndex(extra.scope)),
14877 .inlined_at = @enumFromInt(metadata_adapter.getMetadataIndex(extra.inlined_at)),
14878 .is_implicit = false,
14879 });
14880 has_location = true;
14881 } else {
14882 has_location = false;
14883 }
14884 } else if (has_location) {
14885 try function_block.writeAbbrev(FunctionBlock.DebugLocAgain{});
14886 }
14887 }
14888
14889 adapter.next();
14890 }
14891
14892 // VALUE_SYMTAB
14893 if (!self.strip) {
14894 const ValueSymbolTable = ir.FunctionValueSymbolTable;
14895
14896 var value_symtab_block = try function_block.enterSubBlock(ValueSymbolTable);
14897
14898 for (func.blocks, 0..) |block, block_index| {
14899 const name = block.instruction.name(&func);
14900
14901 if (name == .none or name == .empty) continue;
14902
14903 try value_symtab_block.writeAbbrev(ValueSymbolTable.BlockEntry{
14904 .value_id = @intCast(block_index),
14905 .string = name.slice(self).?,
14906 });
14907 }
14908
14909 // TODO: Emit non block entries if the builder ever starts assigning names to non blocks
14910
14911 try value_symtab_block.end();
14912 }
14913
14914 // METADATA_ATTACHMENT_BLOCK
14915 if (!self.strip) blk: {
14916 const dbg = func.global.ptrConst(self).dbg;
14917
14918 if (dbg == .none) break :blk;
14919
14920 const MetadataAttachmentBlock = ir.MetadataAttachmentBlock;
14921 var metadata_attach_block = try function_block.enterSubBlock(MetadataAttachmentBlock);
14922
14923 try metadata_attach_block.writeAbbrev(MetadataAttachmentBlock.AttachmentSingle{
14924 .kind = ir.MetadataKind.dbg,
14925 .metadata = @enumFromInt(metadata_adapter.getMetadataIndex(dbg) - 1),
14926 });
14927
14928 try metadata_attach_block.end();
14929 }
14930
14931 try function_block.end();
14932 }
14933 }
14934
14935 try module_block.end();
14936 }
14937
14938 // STRTAB_BLOCK
14939 {
14940 const Strtab = ir.Strtab;
14941 var strtab_block = try bitcode.enterTopBlock(Strtab);
14942
14943 try strtab_block.writeAbbrev(Strtab.Blob{ .blob = self.string_bytes.items });
14944
14945 try strtab_block.end();
14946 }
14947
14948 return bitcode.toSlice();
14949}
14950
14951const Allocator = std.mem.Allocator;
14952const assert = std.debug.assert;
14953const bitcode_writer = @import("bitcode_writer.zig");
14954const build_options = @import("build_options");
14955const Builder = @This();
14956const builtin = @import("builtin");
14957const DW = std.dwarf;
14958const ir = @import("ir.zig");
14959const log = std.log.scoped(.llvm);
14960const std = @import("std");
src/codegen/llvm/bindings.zig+10-1455
......@@ -15,7 +15,14 @@ pub const Bool = enum(c_int) {
1515 return b != .False;
1616 }
1717};
18pub const AttributeIndex = c_uint;
18
19pub const MemoryBuffer = opaque {
20 pub const createMemoryBufferWithMemoryRange = LLVMCreateMemoryBufferWithMemoryRange;
21 pub const dispose = LLVMDisposeMemoryBuffer;
22
23 extern fn LLVMCreateMemoryBufferWithMemoryRange(InputData: [*]const u8, InputDataLength: usize, BufferName: ?[*:0]const u8, RequiresNullTerminator: Bool) *MemoryBuffer;
24 extern fn LLVMDisposeMemoryBuffer(MemBuf: *MemoryBuffer) void;
25};
1926
2027/// Make sure to use the *InContext functions instead of the global ones.
2128pub const Context = opaque {
......@@ -25,382 +32,17 @@ pub const Context = opaque {
2532 pub const dispose = LLVMContextDispose;
2633 extern fn LLVMContextDispose(C: *Context) void;
2734
28 pub const createEnumAttribute = LLVMCreateEnumAttribute;
29 extern fn LLVMCreateEnumAttribute(C: *Context, KindID: c_uint, Val: u64) *Attribute;
30
31 pub const createTypeAttribute = LLVMCreateTypeAttribute;
32 extern fn LLVMCreateTypeAttribute(C: *Context, KindID: c_uint, Type: *Type) *Attribute;
33
34 pub const createStringAttribute = LLVMCreateStringAttribute;
35 extern fn LLVMCreateStringAttribute(C: *Context, Key: [*]const u8, Key_Len: c_uint, Value: [*]const u8, Value_Len: c_uint) *Attribute;
36
37 pub const pointerType = LLVMPointerTypeInContext;
38 extern fn LLVMPointerTypeInContext(C: *Context, AddressSpace: c_uint) *Type;
39
40 pub const intType = LLVMIntTypeInContext;
41 extern fn LLVMIntTypeInContext(C: *Context, NumBits: c_uint) *Type;
42
43 pub const halfType = LLVMHalfTypeInContext;
44 extern fn LLVMHalfTypeInContext(C: *Context) *Type;
45
46 pub const bfloatType = LLVMBFloatTypeInContext;
47 extern fn LLVMBFloatTypeInContext(C: *Context) *Type;
48
49 pub const floatType = LLVMFloatTypeInContext;
50 extern fn LLVMFloatTypeInContext(C: *Context) *Type;
51
52 pub const doubleType = LLVMDoubleTypeInContext;
53 extern fn LLVMDoubleTypeInContext(C: *Context) *Type;
54
55 pub const fp128Type = LLVMFP128TypeInContext;
56 extern fn LLVMFP128TypeInContext(C: *Context) *Type;
57
58 pub const x86_fp80Type = LLVMX86FP80TypeInContext;
59 extern fn LLVMX86FP80TypeInContext(C: *Context) *Type;
60
61 pub const ppc_fp128Type = LLVMPPCFP128TypeInContext;
62 extern fn LLVMPPCFP128TypeInContext(C: *Context) *Type;
63
64 pub const x86_amxType = LLVMX86AMXTypeInContext;
65 extern fn LLVMX86AMXTypeInContext(C: *Context) *Type;
66
67 pub const x86_mmxType = LLVMX86MMXTypeInContext;
68 extern fn LLVMX86MMXTypeInContext(C: *Context) *Type;
69
70 pub const voidType = LLVMVoidTypeInContext;
71 extern fn LLVMVoidTypeInContext(C: *Context) *Type;
72
73 pub const labelType = LLVMLabelTypeInContext;
74 extern fn LLVMLabelTypeInContext(C: *Context) *Type;
75
76 pub const tokenType = LLVMTokenTypeInContext;
77 extern fn LLVMTokenTypeInContext(C: *Context) *Type;
78
79 pub const metadataType = LLVMMetadataTypeInContext;
80 extern fn LLVMMetadataTypeInContext(C: *Context) *Type;
81
82 pub const structType = LLVMStructTypeInContext;
83 extern fn LLVMStructTypeInContext(
84 C: *Context,
85 ElementTypes: [*]const *Type,
86 ElementCount: c_uint,
87 Packed: Bool,
88 ) *Type;
89
90 pub const structCreateNamed = LLVMStructCreateNamed;
91 extern fn LLVMStructCreateNamed(C: *Context, Name: [*:0]const u8) *Type;
92
93 pub const constString = LLVMConstStringInContext;
94 extern fn LLVMConstStringInContext(C: *Context, Str: [*]const u8, Length: c_uint, DontNullTerminate: Bool) *Value;
95
96 pub const appendBasicBlock = LLVMAppendBasicBlockInContext;
97 extern fn LLVMAppendBasicBlockInContext(C: *Context, Fn: *Value, Name: [*:0]const u8) *BasicBlock;
98
99 pub const createBuilder = LLVMCreateBuilderInContext;
100 extern fn LLVMCreateBuilderInContext(C: *Context) *Builder;
35 pub const parseBitcodeInContext2 = LLVMParseBitcodeInContext2;
36 extern fn LLVMParseBitcodeInContext2(C: *Context, MemBuf: *MemoryBuffer, OutModule: **Module) Bool;
10137
10238 pub const setOptBisectLimit = ZigLLVMSetOptBisectLimit;
10339 extern fn ZigLLVMSetOptBisectLimit(C: *Context, limit: c_int) void;
10440};
10541
106pub const Value = opaque {
107 pub const addAttributeAtIndex = LLVMAddAttributeAtIndex;
108 extern fn LLVMAddAttributeAtIndex(F: *Value, Idx: AttributeIndex, A: *Attribute) void;
109
110 pub const removeEnumAttributeAtIndex = LLVMRemoveEnumAttributeAtIndex;
111 extern fn LLVMRemoveEnumAttributeAtIndex(F: *Value, Idx: AttributeIndex, KindID: c_uint) void;
112
113 pub const removeStringAttributeAtIndex = LLVMRemoveStringAttributeAtIndex;
114 extern fn LLVMRemoveStringAttributeAtIndex(F: *Value, Idx: AttributeIndex, K: [*]const u8, KLen: c_uint) void;
115
116 pub const getFirstBasicBlock = LLVMGetFirstBasicBlock;
117 extern fn LLVMGetFirstBasicBlock(Fn: *Value) ?*BasicBlock;
118
119 pub const addIncoming = LLVMAddIncoming;
120 extern fn LLVMAddIncoming(
121 PhiNode: *Value,
122 IncomingValues: [*]const *Value,
123 IncomingBlocks: [*]const *BasicBlock,
124 Count: c_uint,
125 ) void;
126
127 pub const setGlobalConstant = LLVMSetGlobalConstant;
128 extern fn LLVMSetGlobalConstant(GlobalVar: *Value, IsConstant: Bool) void;
129
130 pub const setLinkage = LLVMSetLinkage;
131 extern fn LLVMSetLinkage(Global: *Value, Linkage: Linkage) void;
132
133 pub const setVisibility = LLVMSetVisibility;
134 extern fn LLVMSetVisibility(Global: *Value, Linkage: Visibility) void;
135
136 pub const setUnnamedAddr = LLVMSetUnnamedAddr;
137 extern fn LLVMSetUnnamedAddr(Global: *Value, HasUnnamedAddr: Bool) void;
138
139 pub const setThreadLocalMode = LLVMSetThreadLocalMode;
140 extern fn LLVMSetThreadLocalMode(Global: *Value, Mode: ThreadLocalMode) void;
141
142 pub const setSection = LLVMSetSection;
143 extern fn LLVMSetSection(Global: *Value, Section: [*:0]const u8) void;
144
145 pub const removeGlobalValue = ZigLLVMRemoveGlobalValue;
146 extern fn ZigLLVMRemoveGlobalValue(GlobalVal: *Value) void;
147
148 pub const eraseGlobalValue = ZigLLVMEraseGlobalValue;
149 extern fn ZigLLVMEraseGlobalValue(GlobalVal: *Value) void;
150
151 pub const deleteGlobalValue = ZigLLVMDeleteGlobalValue;
152 extern fn ZigLLVMDeleteGlobalValue(GlobalVal: *Value) void;
153
154 pub const setAliasee = LLVMAliasSetAliasee;
155 extern fn LLVMAliasSetAliasee(Alias: *Value, Aliasee: *Value) void;
156
157 pub const constAdd = LLVMConstAdd;
158 extern fn LLVMConstAdd(LHSConstant: *Value, RHSConstant: *Value) *Value;
159
160 pub const constNSWAdd = LLVMConstNSWAdd;
161 extern fn LLVMConstNSWAdd(LHSConstant: *Value, RHSConstant: *Value) *Value;
162
163 pub const constNUWAdd = LLVMConstNUWAdd;
164 extern fn LLVMConstNUWAdd(LHSConstant: *Value, RHSConstant: *Value) *Value;
165
166 pub const constSub = LLVMConstSub;
167 extern fn LLVMConstSub(LHSConstant: *Value, RHSConstant: *Value) *Value;
168
169 pub const constNSWSub = LLVMConstNSWSub;
170 extern fn LLVMConstNSWSub(LHSConstant: *Value, RHSConstant: *Value) *Value;
171
172 pub const constNUWSub = LLVMConstNUWSub;
173 extern fn LLVMConstNUWSub(LHSConstant: *Value, RHSConstant: *Value) *Value;
174
175 pub const constMul = LLVMConstMul;
176 extern fn LLVMConstMul(LHSConstant: *Value, RHSConstant: *Value) *Value;
177
178 pub const constNSWMul = LLVMConstNSWMul;
179 extern fn LLVMConstNSWMul(LHSConstant: *Value, RHSConstant: *Value) *Value;
180
181 pub const constNUWMul = LLVMConstNUWMul;
182 extern fn LLVMConstNUWMul(LHSConstant: *Value, RHSConstant: *Value) *Value;
183
184 pub const constAnd = LLVMConstAnd;
185 extern fn LLVMConstAnd(LHSConstant: *Value, RHSConstant: *Value) *Value;
186
187 pub const constOr = LLVMConstOr;
188 extern fn LLVMConstOr(LHSConstant: *Value, RHSConstant: *Value) *Value;
189
190 pub const constXor = LLVMConstXor;
191 extern fn LLVMConstXor(LHSConstant: *Value, RHSConstant: *Value) *Value;
192
193 pub const constShl = LLVMConstShl;
194 extern fn LLVMConstShl(LHSConstant: *Value, RHSConstant: *Value) *Value;
195
196 pub const constLShr = LLVMConstLShr;
197 extern fn LLVMConstLShr(LHSConstant: *Value, RHSConstant: *Value) *Value;
198
199 pub const constAShr = LLVMConstAShr;
200 extern fn LLVMConstAShr(LHSConstant: *Value, RHSConstant: *Value) *Value;
201
202 pub const constTrunc = LLVMConstTrunc;
203 extern fn LLVMConstTrunc(ConstantVal: *Value, ToType: *Type) *Value;
204
205 pub const constSExt = LLVMConstSExt;
206 extern fn LLVMConstSExt(ConstantVal: *Value, ToType: *Type) *Value;
207
208 pub const constZExt = LLVMConstZExt;
209 extern fn LLVMConstZExt(ConstantVal: *Value, ToType: *Type) *Value;
210
211 pub const constFPTrunc = LLVMConstFPTrunc;
212 extern fn LLVMConstFPTrunc(ConstantVal: *Value, ToType: *Type) *Value;
213
214 pub const constFPExt = LLVMConstFPExt;
215 extern fn LLVMConstFPExt(ConstantVal: *Value, ToType: *Type) *Value;
216
217 pub const constUIToFP = LLVMConstUIToFP;
218 extern fn LLVMConstUIToFP(ConstantVal: *Value, ToType: *Type) *Value;
219
220 pub const constSIToFP = LLVMConstSIToFP;
221 extern fn LLVMConstSIToFP(ConstantVal: *Value, ToType: *Type) *Value;
222
223 pub const constFPToUI = LLVMConstFPToUI;
224 extern fn LLVMConstFPToUI(ConstantVal: *Value, ToType: *Type) *Value;
225
226 pub const constFPToSI = LLVMConstFPToSI;
227 extern fn LLVMConstFPToSI(ConstantVal: *Value, ToType: *Type) *Value;
228
229 pub const constPtrToInt = LLVMConstPtrToInt;
230 extern fn LLVMConstPtrToInt(ConstantVal: *Value, ToType: *Type) *Value;
231
232 pub const constIntToPtr = LLVMConstIntToPtr;
233 extern fn LLVMConstIntToPtr(ConstantVal: *Value, ToType: *Type) *Value;
234
235 pub const constBitCast = LLVMConstBitCast;
236 extern fn LLVMConstBitCast(ConstantVal: *Value, ToType: *Type) *Value;
237
238 pub const constAddrSpaceCast = LLVMConstAddrSpaceCast;
239 extern fn LLVMConstAddrSpaceCast(ConstantVal: *Value, ToType: *Type) *Value;
240
241 pub const constExtractElement = LLVMConstExtractElement;
242 extern fn LLVMConstExtractElement(VectorConstant: *Value, IndexConstant: *Value) *Value;
243
244 pub const constInsertElement = LLVMConstInsertElement;
245 extern fn LLVMConstInsertElement(
246 VectorConstant: *Value,
247 ElementValueConstant: *Value,
248 IndexConstant: *Value,
249 ) *Value;
250
251 pub const constShuffleVector = LLVMConstShuffleVector;
252 extern fn LLVMConstShuffleVector(
253 VectorAConstant: *Value,
254 VectorBConstant: *Value,
255 MaskConstant: *Value,
256 ) *Value;
257
258 pub const isConstant = LLVMIsConstant;
259 extern fn LLVMIsConstant(Val: *Value) Bool;
260
261 pub const blockAddress = LLVMBlockAddress;
262 extern fn LLVMBlockAddress(F: *Value, BB: *BasicBlock) *Value;
263
264 pub const setWeak = LLVMSetWeak;
265 extern fn LLVMSetWeak(CmpXchgInst: *Value, IsWeak: Bool) void;
266
267 pub const setOrdering = LLVMSetOrdering;
268 extern fn LLVMSetOrdering(MemoryAccessInst: *Value, Ordering: AtomicOrdering) void;
269
270 pub const setVolatile = LLVMSetVolatile;
271 extern fn LLVMSetVolatile(MemoryAccessInst: *Value, IsVolatile: Bool) void;
272
273 pub const setAlignment = LLVMSetAlignment;
274 extern fn LLVMSetAlignment(V: *Value, Bytes: c_uint) void;
275
276 pub const getAlignment = LLVMGetAlignment;
277 extern fn LLVMGetAlignment(V: *Value) c_uint;
278
279 pub const setFunctionCallConv = LLVMSetFunctionCallConv;
280 extern fn LLVMSetFunctionCallConv(Fn: *Value, CC: CallConv) void;
281
282 pub const setInstructionCallConv = LLVMSetInstructionCallConv;
283 extern fn LLVMSetInstructionCallConv(Instr: *Value, CC: CallConv) void;
284
285 pub const setTailCallKind = ZigLLVMSetTailCallKind;
286 extern fn ZigLLVMSetTailCallKind(CallInst: *Value, TailCallKind: TailCallKind) void;
287
288 pub const addCallSiteAttribute = LLVMAddCallSiteAttribute;
289 extern fn LLVMAddCallSiteAttribute(C: *Value, Idx: AttributeIndex, A: *Attribute) void;
290
291 pub const fnSetSubprogram = ZigLLVMFnSetSubprogram;
292 extern fn ZigLLVMFnSetSubprogram(f: *Value, subprogram: *DISubprogram) void;
293
294 pub const setValueName = LLVMSetValueName2;
295 extern fn LLVMSetValueName2(Val: *Value, Name: [*]const u8, NameLen: usize) void;
296
297 pub const takeName = ZigLLVMTakeName;
298 extern fn ZigLLVMTakeName(new_owner: *Value, victim: *Value) void;
299
300 pub const getParam = LLVMGetParam;
301 extern fn LLVMGetParam(Fn: *Value, Index: c_uint) *Value;
302
303 pub const setInitializer = ZigLLVMSetInitializer;
304 extern fn ZigLLVMSetInitializer(GlobalVar: *Value, ConstantVal: ?*Value) void;
305
306 pub const setDLLStorageClass = LLVMSetDLLStorageClass;
307 extern fn LLVMSetDLLStorageClass(Global: *Value, Class: DLLStorageClass) void;
308
309 pub const addCase = LLVMAddCase;
310 extern fn LLVMAddCase(Switch: *Value, OnVal: *Value, Dest: *BasicBlock) void;
311
312 pub const replaceAllUsesWith = LLVMReplaceAllUsesWith;
313 extern fn LLVMReplaceAllUsesWith(OldVal: *Value, NewVal: *Value) void;
314
315 pub const attachMetaData = ZigLLVMAttachMetaData;
316 extern fn ZigLLVMAttachMetaData(GlobalVar: *Value, DIG: *DIGlobalVariableExpression) void;
317
318 pub const dump = LLVMDumpValue;
319 extern fn LLVMDumpValue(Val: *Value) void;
320};
321
322pub const Type = opaque {
323 pub const constNull = LLVMConstNull;
324 extern fn LLVMConstNull(Ty: *Type) *Value;
325
326 pub const constInt = LLVMConstInt;
327 extern fn LLVMConstInt(IntTy: *Type, N: c_ulonglong, SignExtend: Bool) *Value;
328
329 pub const constIntOfArbitraryPrecision = LLVMConstIntOfArbitraryPrecision;
330 extern fn LLVMConstIntOfArbitraryPrecision(IntTy: *Type, NumWords: c_uint, Words: [*]const u64) *Value;
331
332 pub const constReal = LLVMConstReal;
333 extern fn LLVMConstReal(RealTy: *Type, N: f64) *Value;
334
335 pub const constArray2 = LLVMConstArray2;
336 extern fn LLVMConstArray2(ElementTy: *Type, ConstantVals: [*]const *Value, Length: u64) *Value;
337
338 pub const constNamedStruct = LLVMConstNamedStruct;
339 extern fn LLVMConstNamedStruct(
340 StructTy: *Type,
341 ConstantVals: [*]const *Value,
342 Count: c_uint,
343 ) *Value;
344
345 pub const getUndef = LLVMGetUndef;
346 extern fn LLVMGetUndef(Ty: *Type) *Value;
347
348 pub const getPoison = LLVMGetPoison;
349 extern fn LLVMGetPoison(Ty: *Type) *Value;
350
351 pub const arrayType2 = LLVMArrayType2;
352 extern fn LLVMArrayType2(ElementType: *Type, ElementCount: u64) *Type;
353
354 pub const vectorType = LLVMVectorType;
355 extern fn LLVMVectorType(ElementType: *Type, ElementCount: c_uint) *Type;
356
357 pub const scalableVectorType = LLVMScalableVectorType;
358 extern fn LLVMScalableVectorType(ElementType: *Type, ElementCount: c_uint) *Type;
359
360 pub const structSetBody = LLVMStructSetBody;
361 extern fn LLVMStructSetBody(
362 StructTy: *Type,
363 ElementTypes: [*]*Type,
364 ElementCount: c_uint,
365 Packed: Bool,
366 ) void;
367
368 pub const isSized = LLVMTypeIsSized;
369 extern fn LLVMTypeIsSized(Ty: *Type) Bool;
370
371 pub const constGEP = LLVMConstGEP2;
372 extern fn LLVMConstGEP2(
373 Ty: *Type,
374 ConstantVal: *Value,
375 ConstantIndices: [*]const *Value,
376 NumIndices: c_uint,
377 ) *Value;
378
379 pub const constInBoundsGEP = LLVMConstInBoundsGEP2;
380 extern fn LLVMConstInBoundsGEP2(
381 Ty: *Type,
382 ConstantVal: *Value,
383 ConstantIndices: [*]const *Value,
384 NumIndices: c_uint,
385 ) *Value;
386
387 pub const dump = LLVMDumpType;
388 extern fn LLVMDumpType(Ty: *Type) void;
389};
390
39142pub const Module = opaque {
392 pub const createWithName = LLVMModuleCreateWithNameInContext;
393 extern fn LLVMModuleCreateWithNameInContext(ModuleID: [*:0]const u8, C: *Context) *Module;
394
39543 pub const dispose = LLVMDisposeModule;
39644 extern fn LLVMDisposeModule(*Module) void;
39745
398 pub const verify = LLVMVerifyModule;
399 extern fn LLVMVerifyModule(*Module, Action: VerifierFailureAction, OutMessage: *[*:0]const u8) Bool;
400
401 pub const setModuleDataLayout = LLVMSetModuleDataLayout;
402 extern fn LLVMSetModuleDataLayout(*Module, *TargetData) void;
403
40446 pub const setModulePICLevel = ZigLLVMSetModulePICLevel;
40547 extern fn ZigLLVMSetModulePICLevel(module: *Module) void;
40648
......@@ -409,508 +51,11 @@ pub const Module = opaque {
40951
41052 pub const setModuleCodeModel = ZigLLVMSetModuleCodeModel;
41153 extern fn ZigLLVMSetModuleCodeModel(module: *Module, code_model: CodeModel) void;
412
413 pub const addFunctionInAddressSpace = ZigLLVMAddFunctionInAddressSpace;
414 extern fn ZigLLVMAddFunctionInAddressSpace(*Module, Name: [*:0]const u8, FunctionTy: *Type, AddressSpace: c_uint) *Value;
415
416 pub const printToString = LLVMPrintModuleToString;
417 extern fn LLVMPrintModuleToString(*Module) [*:0]const u8;
418
419 pub const addGlobalInAddressSpace = LLVMAddGlobalInAddressSpace;
420 extern fn LLVMAddGlobalInAddressSpace(M: *Module, Ty: *Type, Name: [*:0]const u8, AddressSpace: c_uint) *Value;
421
422 pub const dump = LLVMDumpModule;
423 extern fn LLVMDumpModule(M: *Module) void;
424
425 pub const addAlias = LLVMAddAlias2;
426 extern fn LLVMAddAlias2(
427 M: *Module,
428 Ty: *Type,
429 AddrSpace: c_uint,
430 Aliasee: *Value,
431 Name: [*:0]const u8,
432 ) *Value;
433
434 pub const setTarget = LLVMSetTarget;
435 extern fn LLVMSetTarget(M: *Module, Triple: [*:0]const u8) void;
436
437 pub const addModuleDebugInfoFlag = ZigLLVMAddModuleDebugInfoFlag;
438 extern fn ZigLLVMAddModuleDebugInfoFlag(module: *Module, dwarf64: bool) void;
439
440 pub const addModuleCodeViewFlag = ZigLLVMAddModuleCodeViewFlag;
441 extern fn ZigLLVMAddModuleCodeViewFlag(module: *Module) void;
442
443 pub const createDIBuilder = ZigLLVMCreateDIBuilder;
444 extern fn ZigLLVMCreateDIBuilder(module: *Module, allow_unresolved: bool) *DIBuilder;
445
446 pub const setModuleInlineAsm = LLVMSetModuleInlineAsm2;
447 extern fn LLVMSetModuleInlineAsm2(M: *Module, Asm: [*]const u8, Len: usize) void;
448
449 pub const printModuleToFile = LLVMPrintModuleToFile;
450 extern fn LLVMPrintModuleToFile(M: *Module, Filename: [*:0]const u8, ErrorMessage: *[*:0]const u8) Bool;
451
452 pub const writeBitcodeToFile = LLVMWriteBitcodeToFile;
453 extern fn LLVMWriteBitcodeToFile(M: *Module, Path: [*:0]const u8) c_int;
45454};
45555
45656pub const disposeMessage = LLVMDisposeMessage;
45757extern fn LLVMDisposeMessage(Message: [*:0]const u8) void;
45858
459pub const VerifierFailureAction = enum(c_int) {
460 AbortProcess,
461 PrintMessage,
462 ReturnStatus,
463};
464
465pub const constVector = LLVMConstVector;
466extern fn LLVMConstVector(
467 ScalarConstantVals: [*]*Value,
468 Size: c_uint,
469) *Value;
470
471pub const constICmp = LLVMConstICmp;
472extern fn LLVMConstICmp(Predicate: IntPredicate, LHSConstant: *Value, RHSConstant: *Value) *Value;
473
474pub const constFCmp = LLVMConstFCmp;
475extern fn LLVMConstFCmp(Predicate: RealPredicate, LHSConstant: *Value, RHSConstant: *Value) *Value;
476
477pub const getEnumAttributeKindForName = LLVMGetEnumAttributeKindForName;
478extern fn LLVMGetEnumAttributeKindForName(Name: [*]const u8, SLen: usize) c_uint;
479
480pub const getInlineAsm = LLVMGetInlineAsm;
481extern fn LLVMGetInlineAsm(
482 Ty: *Type,
483 AsmString: [*]const u8,
484 AsmStringSize: usize,
485 Constraints: [*]const u8,
486 ConstraintsSize: usize,
487 HasSideEffects: Bool,
488 IsAlignStack: Bool,
489 Dialect: InlineAsmDialect,
490 CanThrow: Bool,
491) *Value;
492
493pub const functionType = LLVMFunctionType;
494extern fn LLVMFunctionType(
495 ReturnType: *Type,
496 ParamTypes: [*]const *Type,
497 ParamCount: c_uint,
498 IsVarArg: Bool,
499) *Type;
500
501pub const InlineAsmDialect = enum(c_uint) { ATT, Intel };
502
503pub const Attribute = opaque {};
504
505pub const Builder = opaque {
506 pub const dispose = LLVMDisposeBuilder;
507 extern fn LLVMDisposeBuilder(Builder: *Builder) void;
508
509 pub const positionBuilder = LLVMPositionBuilder;
510 extern fn LLVMPositionBuilder(
511 Builder: *Builder,
512 Block: *BasicBlock,
513 Instr: ?*Value,
514 ) void;
515
516 pub const buildZExt = LLVMBuildZExt;
517 extern fn LLVMBuildZExt(
518 *Builder,
519 Value: *Value,
520 DestTy: *Type,
521 Name: [*:0]const u8,
522 ) *Value;
523
524 pub const buildSExt = LLVMBuildSExt;
525 extern fn LLVMBuildSExt(
526 *Builder,
527 Val: *Value,
528 DestTy: *Type,
529 Name: [*:0]const u8,
530 ) *Value;
531
532 pub const buildCall = LLVMBuildCall2;
533 extern fn LLVMBuildCall2(
534 *Builder,
535 *Type,
536 Fn: *Value,
537 Args: [*]const *Value,
538 NumArgs: c_uint,
539 Name: [*:0]const u8,
540 ) *Value;
541
542 pub const buildRetVoid = LLVMBuildRetVoid;
543 extern fn LLVMBuildRetVoid(*Builder) *Value;
544
545 pub const buildRet = LLVMBuildRet;
546 extern fn LLVMBuildRet(*Builder, V: *Value) *Value;
547
548 pub const buildUnreachable = LLVMBuildUnreachable;
549 extern fn LLVMBuildUnreachable(*Builder) *Value;
550
551 pub const buildAlloca = LLVMBuildAlloca;
552 extern fn LLVMBuildAlloca(*Builder, Ty: *Type, Name: [*:0]const u8) *Value;
553
554 pub const buildStore = LLVMBuildStore;
555 extern fn LLVMBuildStore(*Builder, Val: *Value, Ptr: *Value) *Value;
556
557 pub const buildLoad = LLVMBuildLoad2;
558 extern fn LLVMBuildLoad2(*Builder, Ty: *Type, PointerVal: *Value, Name: [*:0]const u8) *Value;
559
560 pub const buildFAdd = LLVMBuildFAdd;
561 extern fn LLVMBuildFAdd(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
562
563 pub const buildAdd = LLVMBuildAdd;
564 extern fn LLVMBuildAdd(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
565
566 pub const buildNSWAdd = LLVMBuildNSWAdd;
567 extern fn LLVMBuildNSWAdd(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
568
569 pub const buildNUWAdd = LLVMBuildNUWAdd;
570 extern fn LLVMBuildNUWAdd(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
571
572 pub const buildFSub = LLVMBuildFSub;
573 extern fn LLVMBuildFSub(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
574
575 pub const buildFNeg = LLVMBuildFNeg;
576 extern fn LLVMBuildFNeg(*Builder, V: *Value, Name: [*:0]const u8) *Value;
577
578 pub const buildSub = LLVMBuildSub;
579 extern fn LLVMBuildSub(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
580
581 pub const buildNSWSub = LLVMBuildNSWSub;
582 extern fn LLVMBuildNSWSub(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
583
584 pub const buildNUWSub = LLVMBuildNUWSub;
585 extern fn LLVMBuildNUWSub(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
586
587 pub const buildFMul = LLVMBuildFMul;
588 extern fn LLVMBuildFMul(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
589
590 pub const buildMul = LLVMBuildMul;
591 extern fn LLVMBuildMul(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
592
593 pub const buildNSWMul = LLVMBuildNSWMul;
594 extern fn LLVMBuildNSWMul(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
595
596 pub const buildNUWMul = LLVMBuildNUWMul;
597 extern fn LLVMBuildNUWMul(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
598
599 pub const buildUDiv = LLVMBuildUDiv;
600 extern fn LLVMBuildUDiv(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
601
602 pub const buildSDiv = LLVMBuildSDiv;
603 extern fn LLVMBuildSDiv(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
604
605 pub const buildFDiv = LLVMBuildFDiv;
606 extern fn LLVMBuildFDiv(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
607
608 pub const buildURem = LLVMBuildURem;
609 extern fn LLVMBuildURem(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
610
611 pub const buildSRem = LLVMBuildSRem;
612 extern fn LLVMBuildSRem(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
613
614 pub const buildFRem = LLVMBuildFRem;
615 extern fn LLVMBuildFRem(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
616
617 pub const buildAnd = LLVMBuildAnd;
618 extern fn LLVMBuildAnd(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
619
620 pub const buildLShr = LLVMBuildLShr;
621 extern fn LLVMBuildLShr(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
622
623 pub const buildAShr = LLVMBuildAShr;
624 extern fn LLVMBuildAShr(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
625
626 pub const buildLShrExact = ZigLLVMBuildLShrExact;
627 extern fn ZigLLVMBuildLShrExact(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
628
629 pub const buildAShrExact = ZigLLVMBuildAShrExact;
630 extern fn ZigLLVMBuildAShrExact(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
631
632 pub const buildShl = LLVMBuildShl;
633 extern fn LLVMBuildShl(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
634
635 pub const buildNUWShl = ZigLLVMBuildNUWShl;
636 extern fn ZigLLVMBuildNUWShl(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
637
638 pub const buildNSWShl = ZigLLVMBuildNSWShl;
639 extern fn ZigLLVMBuildNSWShl(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
640
641 pub const buildOr = LLVMBuildOr;
642 extern fn LLVMBuildOr(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
643
644 pub const buildXor = LLVMBuildXor;
645 extern fn LLVMBuildXor(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
646
647 pub const buildBitCast = LLVMBuildBitCast;
648 extern fn LLVMBuildBitCast(*Builder, Val: *Value, DestTy: *Type, Name: [*:0]const u8) *Value;
649
650 pub const buildGEP = LLVMBuildGEP2;
651 extern fn LLVMBuildGEP2(
652 B: *Builder,
653 Ty: *Type,
654 Pointer: *Value,
655 Indices: [*]const *Value,
656 NumIndices: c_uint,
657 Name: [*:0]const u8,
658 ) *Value;
659
660 pub const buildInBoundsGEP = LLVMBuildInBoundsGEP2;
661 extern fn LLVMBuildInBoundsGEP2(
662 B: *Builder,
663 Ty: *Type,
664 Pointer: *Value,
665 Indices: [*]const *Value,
666 NumIndices: c_uint,
667 Name: [*:0]const u8,
668 ) *Value;
669
670 pub const buildICmp = LLVMBuildICmp;
671 extern fn LLVMBuildICmp(*Builder, Op: IntPredicate, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
672
673 pub const buildFCmp = LLVMBuildFCmp;
674 extern fn LLVMBuildFCmp(*Builder, Op: RealPredicate, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
675
676 pub const buildBr = LLVMBuildBr;
677 extern fn LLVMBuildBr(*Builder, Dest: *BasicBlock) *Value;
678
679 pub const buildCondBr = LLVMBuildCondBr;
680 extern fn LLVMBuildCondBr(*Builder, If: *Value, Then: *BasicBlock, Else: *BasicBlock) *Value;
681
682 pub const buildSwitch = LLVMBuildSwitch;
683 extern fn LLVMBuildSwitch(*Builder, V: *Value, Else: *BasicBlock, NumCases: c_uint) *Value;
684
685 pub const buildPhi = LLVMBuildPhi;
686 extern fn LLVMBuildPhi(*Builder, Ty: *Type, Name: [*:0]const u8) *Value;
687
688 pub const buildExtractValue = LLVMBuildExtractValue;
689 extern fn LLVMBuildExtractValue(
690 *Builder,
691 AggVal: *Value,
692 Index: c_uint,
693 Name: [*:0]const u8,
694 ) *Value;
695
696 pub const buildExtractElement = LLVMBuildExtractElement;
697 extern fn LLVMBuildExtractElement(
698 *Builder,
699 VecVal: *Value,
700 Index: *Value,
701 Name: [*:0]const u8,
702 ) *Value;
703
704 pub const buildInsertElement = LLVMBuildInsertElement;
705 extern fn LLVMBuildInsertElement(
706 *Builder,
707 VecVal: *Value,
708 EltVal: *Value,
709 Index: *Value,
710 Name: [*:0]const u8,
711 ) *Value;
712
713 pub const buildPtrToInt = LLVMBuildPtrToInt;
714 extern fn LLVMBuildPtrToInt(
715 *Builder,
716 Val: *Value,
717 DestTy: *Type,
718 Name: [*:0]const u8,
719 ) *Value;
720
721 pub const buildIntToPtr = LLVMBuildIntToPtr;
722 extern fn LLVMBuildIntToPtr(
723 *Builder,
724 Val: *Value,
725 DestTy: *Type,
726 Name: [*:0]const u8,
727 ) *Value;
728
729 pub const buildTrunc = LLVMBuildTrunc;
730 extern fn LLVMBuildTrunc(
731 *Builder,
732 Val: *Value,
733 DestTy: *Type,
734 Name: [*:0]const u8,
735 ) *Value;
736
737 pub const buildInsertValue = LLVMBuildInsertValue;
738 extern fn LLVMBuildInsertValue(
739 *Builder,
740 AggVal: *Value,
741 EltVal: *Value,
742 Index: c_uint,
743 Name: [*:0]const u8,
744 ) *Value;
745
746 pub const buildAtomicCmpXchg = LLVMBuildAtomicCmpXchg;
747 extern fn LLVMBuildAtomicCmpXchg(
748 builder: *Builder,
749 ptr: *Value,
750 cmp: *Value,
751 new_val: *Value,
752 success_ordering: AtomicOrdering,
753 failure_ordering: AtomicOrdering,
754 is_single_threaded: Bool,
755 ) *Value;
756
757 pub const buildSelect = LLVMBuildSelect;
758 extern fn LLVMBuildSelect(
759 *Builder,
760 If: *Value,
761 Then: *Value,
762 Else: *Value,
763 Name: [*:0]const u8,
764 ) *Value;
765
766 pub const buildFence = LLVMBuildFence;
767 extern fn LLVMBuildFence(
768 B: *Builder,
769 ordering: AtomicOrdering,
770 singleThread: Bool,
771 Name: [*:0]const u8,
772 ) *Value;
773
774 pub const buildAtomicRmw = LLVMBuildAtomicRMW;
775 extern fn LLVMBuildAtomicRMW(
776 B: *Builder,
777 op: AtomicRMWBinOp,
778 PTR: *Value,
779 Val: *Value,
780 ordering: AtomicOrdering,
781 singleThread: Bool,
782 ) *Value;
783
784 pub const buildFPToUI = LLVMBuildFPToUI;
785 extern fn LLVMBuildFPToUI(
786 *Builder,
787 Val: *Value,
788 DestTy: *Type,
789 Name: [*:0]const u8,
790 ) *Value;
791
792 pub const buildFPToSI = LLVMBuildFPToSI;
793 extern fn LLVMBuildFPToSI(
794 *Builder,
795 Val: *Value,
796 DestTy: *Type,
797 Name: [*:0]const u8,
798 ) *Value;
799
800 pub const buildUIToFP = LLVMBuildUIToFP;
801 extern fn LLVMBuildUIToFP(
802 *Builder,
803 Val: *Value,
804 DestTy: *Type,
805 Name: [*:0]const u8,
806 ) *Value;
807
808 pub const buildSIToFP = LLVMBuildSIToFP;
809 extern fn LLVMBuildSIToFP(
810 *Builder,
811 Val: *Value,
812 DestTy: *Type,
813 Name: [*:0]const u8,
814 ) *Value;
815
816 pub const buildFPTrunc = LLVMBuildFPTrunc;
817 extern fn LLVMBuildFPTrunc(
818 *Builder,
819 Val: *Value,
820 DestTy: *Type,
821 Name: [*:0]const u8,
822 ) *Value;
823
824 pub const buildFPExt = LLVMBuildFPExt;
825 extern fn LLVMBuildFPExt(
826 *Builder,
827 Val: *Value,
828 DestTy: *Type,
829 Name: [*:0]const u8,
830 ) *Value;
831
832 pub const buildExactUDiv = LLVMBuildExactUDiv;
833 extern fn LLVMBuildExactUDiv(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
834
835 pub const buildExactSDiv = LLVMBuildExactSDiv;
836 extern fn LLVMBuildExactSDiv(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
837
838 pub const setCurrentDebugLocation = ZigLLVMSetCurrentDebugLocation2;
839 extern fn ZigLLVMSetCurrentDebugLocation2(builder: *Builder, line: c_uint, column: c_uint, scope: *DIScope, inlined_at: ?*DILocation) void;
840
841 pub const clearCurrentDebugLocation = ZigLLVMClearCurrentDebugLocation;
842 extern fn ZigLLVMClearCurrentDebugLocation(builder: *Builder) void;
843
844 pub const getCurrentDebugLocation2 = LLVMGetCurrentDebugLocation2;
845 extern fn LLVMGetCurrentDebugLocation2(Builder: *Builder) *Metadata;
846
847 pub const setCurrentDebugLocation2 = LLVMSetCurrentDebugLocation2;
848 extern fn LLVMSetCurrentDebugLocation2(Builder: *Builder, Loc: *Metadata) void;
849
850 pub const buildShuffleVector = LLVMBuildShuffleVector;
851 extern fn LLVMBuildShuffleVector(*Builder, V1: *Value, V2: *Value, Mask: *Value, Name: [*:0]const u8) *Value;
852
853 pub const setFastMath = ZigLLVMSetFastMath;
854 extern fn ZigLLVMSetFastMath(B: *Builder, on_state: bool) void;
855
856 pub const buildAddrSpaceCast = LLVMBuildAddrSpaceCast;
857 extern fn LLVMBuildAddrSpaceCast(B: *Builder, Val: *Value, DestTy: *Type, Name: [*:0]const u8) *Value;
858
859 pub const buildAllocaInAddressSpace = ZigLLVMBuildAllocaInAddressSpace;
860 extern fn ZigLLVMBuildAllocaInAddressSpace(B: *Builder, Ty: *Type, AddressSpace: c_uint, Name: [*:0]const u8) *Value;
861
862 pub const buildVAArg = LLVMBuildVAArg;
863 extern fn LLVMBuildVAArg(*Builder, List: *Value, Ty: *Type, Name: [*:0]const u8) *Value;
864};
865
866pub const MDString = opaque {
867 pub const get = LLVMMDStringInContext2;
868 extern fn LLVMMDStringInContext2(C: *Context, Str: [*]const u8, SLen: usize) *MDString;
869};
870
871pub const DIScope = opaque {
872 pub const toNode = ZigLLVMScopeToNode;
873 extern fn ZigLLVMScopeToNode(scope: *DIScope) *DINode;
874};
875
876pub const DINode = opaque {};
877pub const Metadata = opaque {};
878
879pub const IntPredicate = enum(c_uint) {
880 EQ = 32,
881 NE = 33,
882 UGT = 34,
883 UGE = 35,
884 ULT = 36,
885 ULE = 37,
886 SGT = 38,
887 SGE = 39,
888 SLT = 40,
889 SLE = 41,
890};
891
892pub const RealPredicate = enum(c_uint) {
893 OEQ = 1,
894 OGT = 2,
895 OGE = 3,
896 OLT = 4,
897 OLE = 5,
898 ONE = 6,
899 ORD = 7,
900 UNO = 8,
901 UEQ = 9,
902 UGT = 10,
903 UGE = 11,
904 ULT = 12,
905 ULE = 13,
906 UNE = 14,
907};
908
909pub const BasicBlock = opaque {
910 pub const deleteBasicBlock = LLVMDeleteBasicBlock;
911 extern fn LLVMDeleteBasicBlock(BB: *BasicBlock) void;
912};
913
91459pub const TargetMachine = opaque {
91560 pub const create = ZigLLVMCreateTargetMachine;
91661 extern fn ZigLLVMCreateTargetMachine(
......@@ -945,23 +90,11 @@ pub const TargetMachine = opaque {
94590 llvm_ir_filename: ?[*:0]const u8,
94691 bitcode_filename: ?[*:0]const u8,
94792 ) bool;
948
949 pub const createTargetDataLayout = LLVMCreateTargetDataLayout;
950 extern fn LLVMCreateTargetDataLayout(*TargetMachine) *TargetData;
95193};
95294
95395pub const TargetData = opaque {
95496 pub const dispose = LLVMDisposeTargetData;
95597 extern fn LLVMDisposeTargetData(*TargetData) void;
956
957 pub const abiAlignmentOfType = LLVMABIAlignmentOfType;
958 extern fn LLVMABIAlignmentOfType(TD: *TargetData, Ty: *Type) c_uint;
959
960 pub const abiSizeOfType = LLVMABISizeOfType;
961 extern fn LLVMABISizeOfType(TD: *TargetData, Ty: *Type) c_ulonglong;
962
963 pub const stringRep = LLVMCopyStringRepOfTargetData;
964 extern fn LLVMCopyStringRepOfTargetData(TD: *TargetData) [*:0]const u8;
96598};
96699
967100pub const CodeModel = enum(c_int) {
......@@ -991,11 +124,6 @@ pub const RelocMode = enum(c_int) {
991124 ROPI_RWPI,
992125};
993126
994pub const CodeGenFileType = enum(c_int) {
995 AssemblyFile,
996 ObjectFile,
997};
998
999127pub const ABIType = enum(c_int) {
1000128 /// Target-specific (either soft or hard depending on triple, etc).
1001129 Default,
......@@ -1266,576 +394,3 @@ extern fn ZigLLVMWriteImportLibrary(
1266394 output_lib_path: [*:0]const u8,
1267395 kill_at: bool,
1268396) bool;
1269
1270pub const Linkage = enum(c_uint) {
1271 External,
1272 AvailableExternally,
1273 LinkOnceAny,
1274 LinkOnceODR,
1275 LinkOnceODRAutoHide,
1276 WeakAny,
1277 WeakODR,
1278 Appending,
1279 Internal,
1280 Private,
1281 DLLImport,
1282 DLLExport,
1283 ExternalWeak,
1284 Ghost,
1285 Common,
1286 LinkerPrivate,
1287 LinkerPrivateWeak,
1288};
1289
1290pub const Visibility = enum(c_uint) {
1291 Default,
1292 Hidden,
1293 Protected,
1294};
1295
1296pub const ThreadLocalMode = enum(c_uint) {
1297 NotThreadLocal,
1298 GeneralDynamicTLSModel,
1299 LocalDynamicTLSModel,
1300 InitialExecTLSModel,
1301 LocalExecTLSModel,
1302};
1303
1304pub const AtomicOrdering = enum(c_uint) {
1305 NotAtomic = 0,
1306 Unordered = 1,
1307 Monotonic = 2,
1308 Acquire = 4,
1309 Release = 5,
1310 AcquireRelease = 6,
1311 SequentiallyConsistent = 7,
1312};
1313
1314pub const AtomicRMWBinOp = enum(c_int) {
1315 Xchg,
1316 Add,
1317 Sub,
1318 And,
1319 Nand,
1320 Or,
1321 Xor,
1322 Max,
1323 Min,
1324 UMax,
1325 UMin,
1326 FAdd,
1327 FSub,
1328 FMax,
1329 FMin,
1330};
1331
1332pub const CallConv = enum(c_uint) {
1333 C = 0,
1334 Fast = 8,
1335 Cold = 9,
1336 GHC = 10,
1337 HiPE = 11,
1338 WebKit_JS = 12,
1339 AnyReg = 13,
1340 PreserveMost = 14,
1341 PreserveAll = 15,
1342 Swift = 16,
1343 CXX_FAST_TLS = 17,
1344
1345 X86_StdCall = 64,
1346 X86_FastCall = 65,
1347 ARM_APCS = 66,
1348 ARM_AAPCS = 67,
1349 ARM_AAPCS_VFP = 68,
1350 MSP430_INTR = 69,
1351 X86_ThisCall = 70,
1352 PTX_Kernel = 71,
1353 PTX_Device = 72,
1354 SPIR_FUNC = 75,
1355 SPIR_KERNEL = 76,
1356 Intel_OCL_BI = 77,
1357 X86_64_SysV = 78,
1358 Win64 = 79,
1359 X86_VectorCall = 80,
1360 HHVM = 81,
1361 HHVM_C = 82,
1362 X86_INTR = 83,
1363 AVR_INTR = 84,
1364 AVR_SIGNAL = 85,
1365 AVR_BUILTIN = 86,
1366 AMDGPU_VS = 87,
1367 AMDGPU_GS = 88,
1368 AMDGPU_PS = 89,
1369 AMDGPU_CS = 90,
1370 AMDGPU_KERNEL = 91,
1371 X86_RegCall = 92,
1372 AMDGPU_HS = 93,
1373 MSP430_BUILTIN = 94,
1374 AMDGPU_LS = 95,
1375 AMDGPU_ES = 96,
1376 AArch64_VectorCall = 97,
1377};
1378
1379pub const CallAttr = enum(c_int) {
1380 Auto,
1381 NeverTail,
1382 NeverInline,
1383 AlwaysTail,
1384 AlwaysInline,
1385};
1386
1387pub const TailCallKind = enum(c_uint) {
1388 None,
1389 Tail,
1390 MustTail,
1391 NoTail,
1392};
1393
1394pub const DLLStorageClass = enum(c_uint) {
1395 Default,
1396 DLLImport,
1397 DLLExport,
1398};
1399
1400pub const address_space = struct {
1401 pub const default: c_uint = 0;
1402
1403 // See llvm/lib/Target/X86/X86.h
1404 pub const x86_64 = x86;
1405 pub const x86 = struct {
1406 pub const gs: c_uint = 256;
1407 pub const fs: c_uint = 257;
1408 pub const ss: c_uint = 258;
1409
1410 pub const ptr32_sptr: c_uint = 270;
1411 pub const ptr32_uptr: c_uint = 271;
1412 pub const ptr64: c_uint = 272;
1413 };
1414
1415 // See llvm/lib/Target/AVR/AVR.h
1416 pub const avr = struct {
1417 pub const flash: c_uint = 1;
1418 pub const flash1: c_uint = 2;
1419 pub const flash2: c_uint = 3;
1420 pub const flash3: c_uint = 4;
1421 pub const flash4: c_uint = 5;
1422 pub const flash5: c_uint = 6;
1423 };
1424
1425 // See llvm/lib/Target/NVPTX/NVPTX.h
1426 pub const nvptx = struct {
1427 pub const generic: c_uint = 0;
1428 pub const global: c_uint = 1;
1429 pub const constant: c_uint = 2;
1430 pub const shared: c_uint = 3;
1431 pub const param: c_uint = 4;
1432 pub const local: c_uint = 5;
1433 };
1434
1435 // See llvm/lib/Target/AMDGPU/AMDGPU.h
1436 pub const amdgpu = struct {
1437 pub const flat: c_uint = 0;
1438 pub const global: c_uint = 1;
1439 pub const region: c_uint = 2;
1440 pub const local: c_uint = 3;
1441 pub const constant: c_uint = 4;
1442 pub const private: c_uint = 5;
1443 pub const constant_32bit: c_uint = 6;
1444 pub const buffer_fat_pointer: c_uint = 7;
1445 pub const param_d: c_uint = 6;
1446 pub const param_i: c_uint = 7;
1447 pub const constant_buffer_0: c_uint = 8;
1448 pub const constant_buffer_1: c_uint = 9;
1449 pub const constant_buffer_2: c_uint = 10;
1450 pub const constant_buffer_3: c_uint = 11;
1451 pub const constant_buffer_4: c_uint = 12;
1452 pub const constant_buffer_5: c_uint = 13;
1453 pub const constant_buffer_6: c_uint = 14;
1454 pub const constant_buffer_7: c_uint = 15;
1455 pub const constant_buffer_8: c_uint = 16;
1456 pub const constant_buffer_9: c_uint = 17;
1457 pub const constant_buffer_10: c_uint = 18;
1458 pub const constant_buffer_11: c_uint = 19;
1459 pub const constant_buffer_12: c_uint = 20;
1460 pub const constant_buffer_13: c_uint = 21;
1461 pub const constant_buffer_14: c_uint = 22;
1462 pub const constant_buffer_15: c_uint = 23;
1463 };
1464
1465 // See llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypetilities.h
1466 pub const wasm = struct {
1467 pub const variable: c_uint = 1;
1468 pub const externref: c_uint = 10;
1469 pub const funcref: c_uint = 20;
1470 };
1471};
1472
1473pub const DIEnumerator = opaque {};
1474pub const DILocalVariable = opaque {};
1475pub const DILocation = opaque {};
1476pub const DIGlobalExpression = opaque {};
1477
1478pub const DIGlobalVariable = opaque {
1479 pub const toNode = ZigLLVMGlobalVariableToNode;
1480 extern fn ZigLLVMGlobalVariableToNode(global_variable: *DIGlobalVariable) *DINode;
1481
1482 pub const replaceLinkageName = ZigLLVMGlobalVariableReplaceLinkageName;
1483 extern fn ZigLLVMGlobalVariableReplaceLinkageName(global_variable: *DIGlobalVariable, linkage_name: *MDString) void;
1484};
1485pub const DIGlobalVariableExpression = opaque {
1486 pub const getVariable = ZigLLVMGlobalGetVariable;
1487 extern fn ZigLLVMGlobalGetVariable(global_variable: *DIGlobalVariableExpression) *DIGlobalVariable;
1488};
1489pub const DIType = opaque {
1490 pub const toScope = ZigLLVMTypeToScope;
1491 extern fn ZigLLVMTypeToScope(ty: *DIType) *DIScope;
1492
1493 pub const toNode = ZigLLVMTypeToNode;
1494 extern fn ZigLLVMTypeToNode(ty: *DIType) *DINode;
1495};
1496pub const DIFile = opaque {
1497 pub const toScope = ZigLLVMFileToScope;
1498 extern fn ZigLLVMFileToScope(difile: *DIFile) *DIScope;
1499
1500 pub const toNode = ZigLLVMFileToNode;
1501 extern fn ZigLLVMFileToNode(difile: *DIFile) *DINode;
1502};
1503pub const DILexicalBlock = opaque {
1504 pub const toScope = ZigLLVMLexicalBlockToScope;
1505 extern fn ZigLLVMLexicalBlockToScope(lexical_block: *DILexicalBlock) *DIScope;
1506
1507 pub const toNode = ZigLLVMLexicalBlockToNode;
1508 extern fn ZigLLVMLexicalBlockToNode(lexical_block: *DILexicalBlock) *DINode;
1509};
1510pub const DICompileUnit = opaque {
1511 pub const toScope = ZigLLVMCompileUnitToScope;
1512 extern fn ZigLLVMCompileUnitToScope(compile_unit: *DICompileUnit) *DIScope;
1513
1514 pub const toNode = ZigLLVMCompileUnitToNode;
1515 extern fn ZigLLVMCompileUnitToNode(compile_unit: *DICompileUnit) *DINode;
1516};
1517pub const DISubprogram = opaque {
1518 pub const toScope = ZigLLVMSubprogramToScope;
1519 extern fn ZigLLVMSubprogramToScope(subprogram: *DISubprogram) *DIScope;
1520
1521 pub const toNode = ZigLLVMSubprogramToNode;
1522 extern fn ZigLLVMSubprogramToNode(subprogram: *DISubprogram) *DINode;
1523
1524 pub const replaceLinkageName = ZigLLVMSubprogramReplaceLinkageName;
1525 extern fn ZigLLVMSubprogramReplaceLinkageName(subprogram: *DISubprogram, linkage_name: *MDString) void;
1526};
1527
1528pub const getDebugLoc = ZigLLVMGetDebugLoc2;
1529extern fn ZigLLVMGetDebugLoc2(line: c_uint, col: c_uint, scope: *DIScope, inlined_at: ?*DILocation) *DILocation;
1530
1531pub const DIBuilder = opaque {
1532 pub const dispose = ZigLLVMDisposeDIBuilder;
1533 extern fn ZigLLVMDisposeDIBuilder(dib: *DIBuilder) void;
1534
1535 pub const finalize = ZigLLVMDIBuilderFinalize;
1536 extern fn ZigLLVMDIBuilderFinalize(dib: *DIBuilder) void;
1537
1538 pub const createPointerType = ZigLLVMCreateDebugPointerType;
1539 extern fn ZigLLVMCreateDebugPointerType(
1540 dib: *DIBuilder,
1541 pointee_type: *DIType,
1542 size_in_bits: u64,
1543 align_in_bits: u64,
1544 name: [*:0]const u8,
1545 ) *DIType;
1546
1547 pub const createBasicType = ZigLLVMCreateDebugBasicType;
1548 extern fn ZigLLVMCreateDebugBasicType(
1549 dib: *DIBuilder,
1550 name: [*:0]const u8,
1551 size_in_bits: u64,
1552 encoding: c_uint,
1553 ) *DIType;
1554
1555 pub const createArrayType = ZigLLVMCreateDebugArrayType;
1556 extern fn ZigLLVMCreateDebugArrayType(
1557 dib: *DIBuilder,
1558 size_in_bits: u64,
1559 align_in_bits: u64,
1560 elem_type: *DIType,
1561 elem_count: i64,
1562 ) *DIType;
1563
1564 pub const createEnumerator = ZigLLVMCreateDebugEnumerator;
1565 extern fn ZigLLVMCreateDebugEnumerator(
1566 dib: *DIBuilder,
1567 name: [*:0]const u8,
1568 val: u64,
1569 is_unsigned: bool,
1570 ) *DIEnumerator;
1571
1572 pub const createEnumerator2 = ZigLLVMCreateDebugEnumeratorOfArbitraryPrecision;
1573 extern fn ZigLLVMCreateDebugEnumeratorOfArbitraryPrecision(
1574 dib: *DIBuilder,
1575 name: [*:0]const u8,
1576 num_words: c_uint,
1577 words: [*]const u64,
1578 bits: c_uint,
1579 is_unsigned: bool,
1580 ) *DIEnumerator;
1581
1582 pub const createEnumerationType = ZigLLVMCreateDebugEnumerationType;
1583 extern fn ZigLLVMCreateDebugEnumerationType(
1584 dib: *DIBuilder,
1585 scope: *DIScope,
1586 name: [*:0]const u8,
1587 file: *DIFile,
1588 line_number: c_uint,
1589 size_in_bits: u64,
1590 align_in_bits: u64,
1591 enumerator_array: [*]const *DIEnumerator,
1592 enumerator_array_len: c_int,
1593 underlying_type: *DIType,
1594 unique_id: [*:0]const u8,
1595 ) *DIType;
1596
1597 pub const createStructType = ZigLLVMCreateDebugStructType;
1598 extern fn ZigLLVMCreateDebugStructType(
1599 dib: *DIBuilder,
1600 scope: *DIScope,
1601 name: [*:0]const u8,
1602 file: ?*DIFile,
1603 line_number: c_uint,
1604 size_in_bits: u64,
1605 align_in_bits: u64,
1606 flags: c_uint,
1607 derived_from: ?*DIType,
1608 types_array: [*]const *DIType,
1609 types_array_len: c_int,
1610 run_time_lang: c_uint,
1611 vtable_holder: ?*DIType,
1612 unique_id: [*:0]const u8,
1613 ) *DIType;
1614
1615 pub const createUnionType = ZigLLVMCreateDebugUnionType;
1616 extern fn ZigLLVMCreateDebugUnionType(
1617 dib: *DIBuilder,
1618 scope: *DIScope,
1619 name: [*:0]const u8,
1620 file: ?*DIFile,
1621 line_number: c_uint,
1622 size_in_bits: u64,
1623 align_in_bits: u64,
1624 flags: c_uint,
1625 types_array: [*]const *DIType,
1626 types_array_len: c_int,
1627 run_time_lang: c_uint,
1628 unique_id: [*:0]const u8,
1629 ) *DIType;
1630
1631 pub const createMemberType = ZigLLVMCreateDebugMemberType;
1632 extern fn ZigLLVMCreateDebugMemberType(
1633 dib: *DIBuilder,
1634 scope: *DIScope,
1635 name: [*:0]const u8,
1636 file: ?*DIFile,
1637 line: c_uint,
1638 size_in_bits: u64,
1639 align_in_bits: u64,
1640 offset_in_bits: u64,
1641 flags: c_uint,
1642 ty: *DIType,
1643 ) *DIType;
1644
1645 pub const createReplaceableCompositeType = ZigLLVMCreateReplaceableCompositeType;
1646 extern fn ZigLLVMCreateReplaceableCompositeType(
1647 dib: *DIBuilder,
1648 tag: c_uint,
1649 name: [*:0]const u8,
1650 scope: *DIScope,
1651 file: ?*DIFile,
1652 line: c_uint,
1653 ) *DIType;
1654
1655 pub const createForwardDeclType = ZigLLVMCreateDebugForwardDeclType;
1656 extern fn ZigLLVMCreateDebugForwardDeclType(
1657 dib: *DIBuilder,
1658 tag: c_uint,
1659 name: [*:0]const u8,
1660 scope: ?*DIScope,
1661 file: ?*DIFile,
1662 line: c_uint,
1663 ) *DIType;
1664
1665 pub const replaceTemporary = ZigLLVMReplaceTemporary;
1666 extern fn ZigLLVMReplaceTemporary(dib: *DIBuilder, ty: *DIType, replacement: *DIType) void;
1667
1668 pub const replaceDebugArrays = ZigLLVMReplaceDebugArrays;
1669 extern fn ZigLLVMReplaceDebugArrays(
1670 dib: *DIBuilder,
1671 ty: *DIType,
1672 types_array: [*]const *DIType,
1673 types_array_len: c_int,
1674 ) void;
1675
1676 pub const createSubroutineType = ZigLLVMCreateSubroutineType;
1677 extern fn ZigLLVMCreateSubroutineType(
1678 dib: *DIBuilder,
1679 types_array: [*]const *DIType,
1680 types_array_len: c_int,
1681 flags: c_uint,
1682 ) *DIType;
1683
1684 pub const createAutoVariable = ZigLLVMCreateAutoVariable;
1685 extern fn ZigLLVMCreateAutoVariable(
1686 dib: *DIBuilder,
1687 scope: *DIScope,
1688 name: [*:0]const u8,
1689 file: *DIFile,
1690 line_no: c_uint,
1691 ty: *DIType,
1692 always_preserve: bool,
1693 flags: c_uint,
1694 ) *DILocalVariable;
1695
1696 pub const createGlobalVariableExpression = ZigLLVMCreateGlobalVariableExpression;
1697 extern fn ZigLLVMCreateGlobalVariableExpression(
1698 dib: *DIBuilder,
1699 scope: *DIScope,
1700 name: [*:0]const u8,
1701 linkage_name: [*:0]const u8,
1702 file: *DIFile,
1703 line_no: c_uint,
1704 di_type: *DIType,
1705 is_local_to_unit: bool,
1706 ) *DIGlobalVariableExpression;
1707
1708 pub const createParameterVariable = ZigLLVMCreateParameterVariable;
1709 extern fn ZigLLVMCreateParameterVariable(
1710 dib: *DIBuilder,
1711 scope: *DIScope,
1712 name: [*:0]const u8,
1713 file: *DIFile,
1714 line_no: c_uint,
1715 ty: *DIType,
1716 always_preserve: bool,
1717 flags: c_uint,
1718 arg_no: c_uint,
1719 ) *DILocalVariable;
1720
1721 pub const createLexicalBlock = ZigLLVMCreateLexicalBlock;
1722 extern fn ZigLLVMCreateLexicalBlock(
1723 dib: *DIBuilder,
1724 scope: *DIScope,
1725 file: *DIFile,
1726 line: c_uint,
1727 col: c_uint,
1728 ) *DILexicalBlock;
1729
1730 pub const createCompileUnit = ZigLLVMCreateCompileUnit;
1731 extern fn ZigLLVMCreateCompileUnit(
1732 dib: *DIBuilder,
1733 lang: c_uint,
1734 difile: *DIFile,
1735 producer: [*:0]const u8,
1736 is_optimized: bool,
1737 flags: [*:0]const u8,
1738 runtime_version: c_uint,
1739 split_name: [*:0]const u8,
1740 dwo_id: u64,
1741 emit_debug_info: bool,
1742 ) *DICompileUnit;
1743
1744 pub const createFile = ZigLLVMCreateFile;
1745 extern fn ZigLLVMCreateFile(
1746 dib: *DIBuilder,
1747 filename: [*:0]const u8,
1748 directory: [*:0]const u8,
1749 ) *DIFile;
1750
1751 pub const createFunction = ZigLLVMCreateFunction;
1752 extern fn ZigLLVMCreateFunction(
1753 dib: *DIBuilder,
1754 scope: *DIScope,
1755 name: [*:0]const u8,
1756 linkage_name: [*:0]const u8,
1757 file: *DIFile,
1758 lineno: c_uint,
1759 fn_di_type: *DIType,
1760 is_local_to_unit: bool,
1761 is_definition: bool,
1762 scope_line: c_uint,
1763 flags: c_uint,
1764 is_optimized: bool,
1765 decl_subprogram: ?*DISubprogram,
1766 ) *DISubprogram;
1767
1768 pub const createVectorType = ZigLLVMDIBuilderCreateVectorType;
1769 extern fn ZigLLVMDIBuilderCreateVectorType(
1770 dib: *DIBuilder,
1771 SizeInBits: u64,
1772 AlignInBits: u32,
1773 Ty: *DIType,
1774 elem_count: u32,
1775 ) *DIType;
1776
1777 pub const insertDeclareAtEnd = ZigLLVMInsertDeclareAtEnd;
1778 extern fn ZigLLVMInsertDeclareAtEnd(
1779 dib: *DIBuilder,
1780 storage: *Value,
1781 var_info: *DILocalVariable,
1782 debug_loc: *DILocation,
1783 basic_block_ref: *BasicBlock,
1784 ) *Value;
1785
1786 pub const insertDeclare = ZigLLVMInsertDeclare;
1787 extern fn ZigLLVMInsertDeclare(
1788 dib: *DIBuilder,
1789 storage: *Value,
1790 var_info: *DILocalVariable,
1791 debug_loc: *DILocation,
1792 insert_before_instr: *Value,
1793 ) *Value;
1794
1795 pub const insertDbgValueIntrinsicAtEnd = ZigLLVMInsertDbgValueIntrinsicAtEnd;
1796 extern fn ZigLLVMInsertDbgValueIntrinsicAtEnd(
1797 dib: *DIBuilder,
1798 val: *Value,
1799 var_info: *DILocalVariable,
1800 debug_loc: *DILocation,
1801 basic_block_ref: *BasicBlock,
1802 ) *Value;
1803};
1804
1805pub const DIFlags = opaque {
1806 pub const Zero = 0;
1807 pub const Private = 1;
1808 pub const Protected = 2;
1809 pub const Public = 3;
1810
1811 pub const FwdDecl = 1 << 2;
1812 pub const AppleBlock = 1 << 3;
1813 pub const BlockByrefStruct = 1 << 4;
1814 pub const Virtual = 1 << 5;
1815 pub const Artificial = 1 << 6;
1816 pub const Explicit = 1 << 7;
1817 pub const Prototyped = 1 << 8;
1818 pub const ObjcClassComplete = 1 << 9;
1819 pub const ObjectPointer = 1 << 10;
1820 pub const Vector = 1 << 11;
1821 pub const StaticMember = 1 << 12;
1822 pub const LValueReference = 1 << 13;
1823 pub const RValueReference = 1 << 14;
1824 pub const Reserved = 1 << 15;
1825
1826 pub const SingleInheritance = 1 << 16;
1827 pub const MultipleInheritance = 2 << 16;
1828 pub const VirtualInheritance = 3 << 16;
1829
1830 pub const IntroducedVirtual = 1 << 18;
1831 pub const BitField = 1 << 19;
1832 pub const NoReturn = 1 << 20;
1833 pub const TypePassByValue = 1 << 22;
1834 pub const TypePassByReference = 1 << 23;
1835 pub const EnumClass = 1 << 24;
1836 pub const Thunk = 1 << 25;
1837 pub const NonTrivial = 1 << 26;
1838 pub const BigEndian = 1 << 27;
1839 pub const LittleEndian = 1 << 28;
1840 pub const AllCallsDescribed = 1 << 29;
1841};
src/codegen/llvm/bitcode_writer.zig created+421
......@@ -0,0 +1,421 @@
1const std = @import("std");
2
3pub const AbbrevOp = union(enum) {
4 literal: u32, // 0
5 fixed: u16, // 1
6 fixed_runtime: type, // 1
7 vbr: u16, // 2
8 char6: void, // 4
9 blob: void, // 5
10 array_fixed: u16, // 3, 1
11 array_fixed_runtime: type, // 3, 1
12 array_vbr: u16, // 3, 2
13 array_char6: void, // 3, 4
14};
15
16pub const Error = error{OutOfMemory};
17
18pub fn BitcodeWriter(comptime types: []const type) type {
19 return struct {
20 const BcWriter = @This();
21
22 buffer: std.ArrayList(u32),
23 bit_buffer: u32 = 0,
24 bit_count: u5 = 0,
25
26 widths: [types.len]u16,
27
28 pub fn getTypeWidth(self: BcWriter, comptime Type: type) u16 {
29 return self.widths[comptime std.mem.indexOfScalar(type, types, Type).?];
30 }
31
32 pub fn init(allocator: std.mem.Allocator, widths: [types.len]u16) BcWriter {
33 return .{
34 .buffer = std.ArrayList(u32).init(allocator),
35 .widths = widths,
36 };
37 }
38
39 pub fn deinit(self: BcWriter) void {
40 self.buffer.deinit();
41 }
42
43 pub fn toSlice(self: BcWriter) []const u32 {
44 std.debug.assert(self.bit_count == 0);
45 return self.buffer.items;
46 }
47
48 pub fn length(self: BcWriter) usize {
49 std.debug.assert(self.bit_count == 0);
50 return self.buffer.items.len;
51 }
52
53 pub fn writeBits(self: *BcWriter, value: anytype, bits: u16) Error!void {
54 if (bits == 0) return;
55
56 var in_buffer = bufValue(value, 32);
57 var in_bits = bits;
58
59 // Store input bits in buffer if they fit otherwise store as many as possible and flush
60 if (self.bit_count > 0) {
61 const bits_remaining = 31 - self.bit_count + 1;
62 const n: u5 = @intCast(@min(bits_remaining, in_bits));
63 const v = @as(u32, @truncate(in_buffer)) << self.bit_count;
64 self.bit_buffer |= v;
65 in_buffer >>= n;
66
67 self.bit_count +%= n;
68 in_bits -= n;
69
70 if (self.bit_count != 0) return;
71 try self.buffer.append(self.bit_buffer);
72 self.bit_buffer = 0;
73 }
74
75 // Write 32-bit chunks of input bits
76 while (in_bits >= 32) {
77 try self.buffer.append(@truncate(in_buffer));
78
79 in_buffer >>= 31;
80 in_buffer >>= 1;
81 in_bits -= 32;
82 }
83
84 // Store remaining input bits in buffer
85 if (in_bits > 0) {
86 self.bit_count = @intCast(in_bits);
87 self.bit_buffer = @truncate(in_buffer);
88 }
89 }
90
91 pub fn writeVBR(self: *BcWriter, value: anytype, comptime vbr_bits: usize) Error!void {
92 comptime {
93 std.debug.assert(vbr_bits > 1);
94 if (@bitSizeOf(@TypeOf(value)) > 64) @compileError("Unsupported VBR block type: " ++ @typeName(@TypeOf(value)));
95 }
96
97 var in_buffer = bufValue(value, vbr_bits);
98
99 const continue_bit = @as(@TypeOf(in_buffer), 1) << @intCast(vbr_bits - 1);
100 const mask = continue_bit - 1;
101
102 // If input is larger than one VBR block can store
103 // then store vbr_bits - 1 bits and a continue bit
104 while (in_buffer > mask) {
105 try self.writeBits(in_buffer & mask | continue_bit, vbr_bits);
106 in_buffer >>= @intCast(vbr_bits - 1);
107 }
108
109 // Store remaining bits
110 try self.writeBits(in_buffer, vbr_bits);
111 }
112
113 pub fn bitsVBR(_: *const BcWriter, value: anytype, comptime vbr_bits: usize) u16 {
114 comptime {
115 std.debug.assert(vbr_bits > 1);
116 if (@bitSizeOf(@TypeOf(value)) > 64) @compileError("Unsupported VBR block type: " ++ @typeName(@TypeOf(value)));
117 }
118
119 var bits: u16 = 0;
120
121 var in_buffer = bufValue(value, vbr_bits);
122
123 const continue_bit = @as(@TypeOf(in_buffer), 1) << @intCast(vbr_bits - 1);
124 const mask = continue_bit - 1;
125
126 // If input is larger than one VBR block can store
127 // then store vbr_bits - 1 bits and a continue bit
128 while (in_buffer > mask) {
129 bits += @intCast(vbr_bits);
130 in_buffer >>= @intCast(vbr_bits - 1);
131 }
132
133 // Store remaining bits
134 bits += @intCast(vbr_bits);
135 return bits;
136 }
137
138 pub fn write6BitChar(self: *BcWriter, c: u8) Error!void {
139 try self.writeBits(charTo6Bit(c), 6);
140 }
141
142 pub fn alignTo32(self: *BcWriter) Error!void {
143 if (self.bit_count == 0) return;
144
145 try self.buffer.append(self.bit_buffer);
146 self.bit_buffer = 0;
147 self.bit_count = 0;
148 }
149
150 pub fn enterTopBlock(self: *BcWriter, comptime SubBlock: type) Error!BlockWriter(SubBlock) {
151 return BlockWriter(SubBlock).init(self, 2);
152 }
153
154 fn BlockWriter(comptime Block: type) type {
155 return struct {
156 const Self = @This();
157
158 // The minimum abbrev id length based on the number of abbrevs present in the block
159 pub const abbrev_len = std.math.log2_int_ceil(
160 u6,
161 4 + (if (@hasDecl(Block, "abbrevs")) Block.abbrevs.len else 0),
162 );
163
164 start: usize,
165 bitcode: *BcWriter,
166
167 pub fn init(bitcode: *BcWriter, comptime parent_abbrev_len: u6) Error!Self {
168 try bitcode.writeBits(1, parent_abbrev_len);
169 try bitcode.writeVBR(Block.id, 8);
170 try bitcode.writeVBR(abbrev_len, 4);
171 try bitcode.alignTo32();
172
173 // We store the index of the block size and store a dummy value as the number of words in the block
174 const start = bitcode.length();
175 try bitcode.writeBits(0, 32);
176
177 // Predefine all block abbrevs
178 inline for (Block.abbrevs) |Abbrev| {
179 try defineAbbrev(bitcode, &Abbrev.ops);
180 }
181
182 return .{
183 .start = start,
184 .bitcode = bitcode,
185 };
186 }
187
188 pub fn enterSubBlock(self: Self, comptime SubBlock: type) Error!BlockWriter(SubBlock) {
189 return BlockWriter(SubBlock).init(self.bitcode, abbrev_len);
190 }
191
192 pub fn end(self: *Self) Error!void {
193 try self.bitcode.writeBits(0, abbrev_len);
194 try self.bitcode.alignTo32();
195
196 // Set the number of words in the block at the start of the block
197 self.bitcode.buffer.items[self.start] = @truncate(self.bitcode.length() - self.start - 1);
198 }
199
200 pub fn writeUnabbrev(self: *Self, code: u32, values: []const u64) Error!void {
201 try self.bitcode.writeBits(3, abbrev_len);
202 try self.bitcode.writeVBR(code, 6);
203 try self.bitcode.writeVBR(values.len, 6);
204 for (values) |val| {
205 try self.bitcode.writeVBR(val, 6);
206 }
207 }
208
209 pub fn writeAbbrev(self: *Self, params: anytype) Error!void {
210 return self.writeAbbrevAdapted(params, struct {
211 pub fn get(_: @This(), param: anytype, comptime _: []const u8) @TypeOf(param) {
212 return param;
213 }
214 }{});
215 }
216
217 pub fn abbrevId(comptime Abbrev: type) u32 {
218 inline for (Block.abbrevs, 0..) |abbrev, i| {
219 if (Abbrev == abbrev) return i + 4;
220 }
221
222 @compileError("Unknown abbrev: " ++ @typeName(Abbrev));
223 }
224
225 pub fn writeAbbrevAdapted(
226 self: *Self,
227 params: anytype,
228 adapter: anytype,
229 ) Error!void {
230 const Abbrev = @TypeOf(params);
231
232 try self.bitcode.writeBits(comptime abbrevId(Abbrev), abbrev_len);
233
234 const fields = std.meta.fields(Abbrev);
235
236 // This abbreviation might only contain literals
237 if (fields.len == 0) return;
238
239 comptime var field_index: usize = 0;
240 inline for (Abbrev.ops) |ty| {
241 const field_name = fields[field_index].name;
242 const param = @field(params, field_name);
243
244 switch (ty) {
245 .literal => continue,
246 .fixed => |len| try self.bitcode.writeBits(adapter.get(param, field_name), len),
247 .fixed_runtime => |width_ty| try self.bitcode.writeBits(
248 adapter.get(param, field_name),
249 self.bitcode.getTypeWidth(width_ty),
250 ),
251 .vbr => |len| try self.bitcode.writeVBR(adapter.get(param, field_name), len),
252 .char6 => try self.bitcode.write6BitChar(adapter.get(param, field_name)),
253 .blob => {
254 try self.bitcode.writeVBR(param.len, 6);
255 try self.bitcode.alignTo32();
256 for (param) |x| {
257 try self.bitcode.writeBits(x, 8);
258 }
259 try self.bitcode.alignTo32();
260 },
261 .array_fixed => |len| {
262 try self.bitcode.writeVBR(param.len, 6);
263 for (param) |x| {
264 try self.bitcode.writeBits(adapter.get(x, field_name), len);
265 }
266 },
267 .array_fixed_runtime => |width_ty| {
268 try self.bitcode.writeVBR(param.len, 6);
269 for (param) |x| {
270 try self.bitcode.writeBits(
271 adapter.get(x, field_name),
272 self.bitcode.getTypeWidth(width_ty),
273 );
274 }
275 },
276 .array_vbr => |len| {
277 try self.bitcode.writeVBR(param.len, 6);
278 for (param) |x| {
279 try self.bitcode.writeVBR(adapter.get(x, field_name), len);
280 }
281 },
282 .array_char6 => {
283 try self.bitcode.writeVBR(param.len, 6);
284 for (param) |x| {
285 try self.bitcode.write6BitChar(adapter.get(x, field_name));
286 }
287 },
288 }
289 field_index += 1;
290 if (field_index == fields.len) break;
291 }
292 }
293
294 fn defineAbbrev(bitcode: *BcWriter, comptime ops: []const AbbrevOp) Error!void {
295 try bitcode.writeBits(2, abbrev_len);
296
297 // ops.len is not accurate because arrays are actually two ops
298 try bitcode.writeVBR(blk: {
299 var count: usize = 0;
300 inline for (ops) |op| {
301 count += switch (op) {
302 .literal, .fixed, .fixed_runtime, .vbr, .char6, .blob => 1,
303 .array_fixed, .array_fixed_runtime, .array_vbr, .array_char6 => 2,
304 };
305 }
306 break :blk count;
307 }, 5);
308
309 inline for (ops) |op| {
310 switch (op) {
311 .literal => |value| {
312 try bitcode.writeBits(1, 1);
313 try bitcode.writeVBR(value, 8);
314 },
315 .fixed => |width| {
316 try bitcode.writeBits(0, 1);
317 try bitcode.writeBits(1, 3);
318 try bitcode.writeVBR(width, 5);
319 },
320 .fixed_runtime => |width_ty| {
321 try bitcode.writeBits(0, 1);
322 try bitcode.writeBits(1, 3);
323 try bitcode.writeVBR(bitcode.getTypeWidth(width_ty), 5);
324 },
325 .vbr => |width| {
326 try bitcode.writeBits(0, 1);
327 try bitcode.writeBits(2, 3);
328 try bitcode.writeVBR(width, 5);
329 },
330 .char6 => {
331 try bitcode.writeBits(0, 1);
332 try bitcode.writeBits(4, 3);
333 },
334 .blob => {
335 try bitcode.writeBits(0, 1);
336 try bitcode.writeBits(5, 3);
337 },
338 .array_fixed => |width| {
339 // Array op
340 try bitcode.writeBits(0, 1);
341 try bitcode.writeBits(3, 3);
342
343 // Fixed or VBR op
344 try bitcode.writeBits(0, 1);
345 try bitcode.writeBits(1, 3);
346 try bitcode.writeVBR(width, 5);
347 },
348 .array_fixed_runtime => |width_ty| {
349 // Array op
350 try bitcode.writeBits(0, 1);
351 try bitcode.writeBits(3, 3);
352
353 // Fixed or VBR op
354 try bitcode.writeBits(0, 1);
355 try bitcode.writeBits(1, 3);
356 try bitcode.writeVBR(bitcode.getTypeWidth(width_ty), 5);
357 },
358 .array_vbr => |width| {
359 // Array op
360 try bitcode.writeBits(0, 1);
361 try bitcode.writeBits(3, 3);
362
363 // Fixed or VBR op
364 try bitcode.writeBits(0, 1);
365 try bitcode.writeBits(2, 3);
366 try bitcode.writeVBR(width, 5);
367 },
368 .array_char6 => {
369 // Array op
370 try bitcode.writeBits(0, 1);
371 try bitcode.writeBits(3, 3);
372
373 // Char6 op
374 try bitcode.writeBits(0, 1);
375 try bitcode.writeBits(4, 3);
376 },
377 }
378 }
379 }
380 };
381 }
382 };
383}
384
385fn charTo6Bit(c: u8) u8 {
386 return switch (c) {
387 'a'...'z' => c - 'a',
388 'A'...'Z' => c - 'A' + 26,
389 '0'...'9' => c - '0' + 52,
390 '.' => 62,
391 '_' => 63,
392 else => @panic("Failed to encode byte as 6-bit char"),
393 };
394}
395
396fn BufType(comptime T: type, comptime min_len: usize) type {
397 return std.meta.Int(.unsigned, @max(min_len, @bitSizeOf(switch (@typeInfo(T)) {
398 .ComptimeInt => u32,
399 .Int => |info| if (info.signedness == .unsigned)
400 T
401 else
402 @compileError("Unsupported type: " ++ @typeName(T)),
403 .Enum => |info| info.tag_type,
404 .Bool => u1,
405 .Struct => |info| switch (info.layout) {
406 .Auto, .Extern => @compileError("Unsupported type: " ++ @typeName(T)),
407 .Packed => std.meta.Int(.unsigned, @bitSizeOf(T)),
408 },
409 else => @compileError("Unsupported type: " ++ @typeName(T)),
410 })));
411}
412
413fn bufValue(value: anytype, comptime min_len: usize) BufType(@TypeOf(value), min_len) {
414 return switch (@typeInfo(@TypeOf(value))) {
415 .ComptimeInt, .Int => @intCast(value),
416 .Enum => @intFromEnum(value),
417 .Bool => @intFromBool(value),
418 .Struct => @intCast(@as(std.meta.Int(.unsigned, @bitSizeOf(@TypeOf(value))), @bitCast(value))),
419 else => unreachable,
420 };
421}
src/codegen/llvm/ir.zig created+1636
......@@ -0,0 +1,1636 @@
1const std = @import("std");
2const Builder = @import("Builder.zig");
3const bitcode_writer = @import("bitcode_writer.zig");
4
5const AbbrevOp = bitcode_writer.AbbrevOp;
6
7pub const MAGIC: u32 = 0xdec04342;
8
9const ValueAbbrev = AbbrevOp{ .vbr = 6 };
10const ValueArrayAbbrev = AbbrevOp{ .array_vbr = 6 };
11
12const ConstantAbbrev = AbbrevOp{ .vbr = 6 };
13const ConstantArrayAbbrev = AbbrevOp{ .array_vbr = 6 };
14
15const MetadataAbbrev = AbbrevOp{ .vbr = 16 };
16const MetadataArrayAbbrev = AbbrevOp{ .array_vbr = 16 };
17
18const LineAbbrev = AbbrevOp{ .vbr = 8 };
19const ColumnAbbrev = AbbrevOp{ .vbr = 8 };
20
21const BlockAbbrev = AbbrevOp{ .vbr = 6 };
22
23pub const MetadataKind = enum(u1) {
24 dbg = 0,
25};
26
27pub const Identification = struct {
28 pub const id = 13;
29
30 pub const abbrevs = [_]type{
31 Version,
32 Epoch,
33 };
34
35 pub const Version = struct {
36 pub const ops = [_]AbbrevOp{
37 .{ .literal = 1 },
38 .{ .array_fixed = 8 },
39 };
40 string: []const u8,
41 };
42
43 pub const Epoch = struct {
44 pub const ops = [_]AbbrevOp{
45 .{ .literal = 2 },
46 .{ .vbr = 6 },
47 };
48 epoch: u32,
49 };
50};
51
52pub const Module = struct {
53 pub const id = 8;
54
55 pub const abbrevs = [_]type{
56 Version,
57 String,
58 Variable,
59 Function,
60 Alias,
61 };
62
63 pub const Version = struct {
64 pub const ops = [_]AbbrevOp{
65 .{ .literal = 1 },
66 .{ .literal = 2 },
67 };
68 };
69
70 pub const String = struct {
71 pub const ops = [_]AbbrevOp{
72 .{ .vbr = 4 },
73 .{ .array_fixed = 8 },
74 };
75 code: u16,
76 string: []const u8,
77 };
78
79 pub const Variable = struct {
80 const AddrSpaceAndIsConst = packed struct {
81 is_const: bool,
82 one: u1 = 1,
83 addr_space: Builder.AddrSpace,
84 };
85
86 pub const ops = [_]AbbrevOp{
87 .{ .literal = 7 }, // Code
88 .{ .vbr = 16 }, // strtab_offset
89 .{ .vbr = 16 }, // strtab_size
90 .{ .fixed_runtime = Builder.Type },
91 .{ .fixed = @bitSizeOf(AddrSpaceAndIsConst) }, // isconst
92 ConstantAbbrev, // initid
93 .{ .fixed = @bitSizeOf(Builder.Linkage) },
94 .{ .fixed = @bitSizeOf(Builder.Alignment) },
95 .{ .vbr = 16 }, // section
96 .{ .fixed = @bitSizeOf(Builder.Visibility) },
97 .{ .fixed = @bitSizeOf(Builder.ThreadLocal) }, // threadlocal
98 .{ .fixed = @bitSizeOf(Builder.UnnamedAddr) },
99 .{ .fixed = @bitSizeOf(Builder.ExternallyInitialized) },
100 .{ .fixed = @bitSizeOf(Builder.DllStorageClass) },
101 .{ .literal = 0 }, // comdat
102 .{ .literal = 0 }, // attributes
103 .{ .fixed = @bitSizeOf(Builder.Preemption) },
104 };
105 strtab_offset: usize,
106 strtab_size: usize,
107 type_index: Builder.Type,
108 is_const: AddrSpaceAndIsConst,
109 initid: u32,
110 linkage: Builder.Linkage,
111 alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)),
112 section: usize,
113 visibility: Builder.Visibility,
114 thread_local: Builder.ThreadLocal,
115 unnamed_addr: Builder.UnnamedAddr,
116 externally_initialized: Builder.ExternallyInitialized,
117 dllstorageclass: Builder.DllStorageClass,
118 preemption: Builder.Preemption,
119 };
120
121 pub const Function = struct {
122 pub const ops = [_]AbbrevOp{
123 .{ .literal = 8 }, // Code
124 .{ .vbr = 16 }, // strtab_offset
125 .{ .vbr = 16 }, // strtab_size
126 .{ .fixed_runtime = Builder.Type },
127 .{ .fixed = @bitSizeOf(Builder.CallConv) },
128 .{ .fixed = 1 }, // isproto
129 .{ .fixed = @bitSizeOf(Builder.Linkage) },
130 .{ .vbr = 16 }, // paramattr
131 .{ .fixed = @bitSizeOf(Builder.Alignment) },
132 .{ .vbr = 16 }, // section
133 .{ .fixed = @bitSizeOf(Builder.Visibility) },
134 .{ .literal = 0 }, // gc
135 .{ .fixed = @bitSizeOf(Builder.UnnamedAddr) },
136 .{ .literal = 0 }, // prologuedata
137 .{ .fixed = @bitSizeOf(Builder.DllStorageClass) },
138 .{ .literal = 0 }, // comdat
139 .{ .literal = 0 }, // prefixdata
140 .{ .literal = 0 }, // personalityfn
141 .{ .fixed = @bitSizeOf(Builder.Preemption) },
142 .{ .fixed = @bitSizeOf(Builder.AddrSpace) },
143 };
144 strtab_offset: usize,
145 strtab_size: usize,
146 type_index: Builder.Type,
147 call_conv: Builder.CallConv,
148 is_proto: bool,
149 linkage: Builder.Linkage,
150 paramattr: usize,
151 alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)),
152 section: usize,
153 visibility: Builder.Visibility,
154 unnamed_addr: Builder.UnnamedAddr,
155 dllstorageclass: Builder.DllStorageClass,
156 preemption: Builder.Preemption,
157 addr_space: Builder.AddrSpace,
158 };
159
160 pub const Alias = struct {
161 pub const ops = [_]AbbrevOp{
162 .{ .literal = 14 }, // Code
163 .{ .vbr = 16 }, // strtab_offset
164 .{ .vbr = 16 }, // strtab_size
165 .{ .fixed_runtime = Builder.Type },
166 .{ .fixed = @bitSizeOf(Builder.AddrSpace) },
167 ConstantAbbrev, // aliasee val
168 .{ .fixed = @bitSizeOf(Builder.Linkage) },
169 .{ .fixed = @bitSizeOf(Builder.Visibility) },
170 .{ .fixed = @bitSizeOf(Builder.DllStorageClass) },
171 .{ .fixed = @bitSizeOf(Builder.ThreadLocal) },
172 .{ .fixed = @bitSizeOf(Builder.UnnamedAddr) },
173 .{ .fixed = @bitSizeOf(Builder.Preemption) },
174 };
175 strtab_offset: usize,
176 strtab_size: usize,
177 type_index: Builder.Type,
178 addr_space: Builder.AddrSpace,
179 aliasee: u32,
180 linkage: Builder.Linkage,
181 visibility: Builder.Visibility,
182 dllstorageclass: Builder.DllStorageClass,
183 thread_local: Builder.ThreadLocal,
184 unnamed_addr: Builder.UnnamedAddr,
185 preemption: Builder.Preemption,
186 };
187};
188
189pub const Type = struct {
190 pub const id = 17;
191
192 pub const abbrevs = [_]type{
193 NumEntry,
194 Simple,
195 Opaque,
196 Integer,
197 StructAnon,
198 StructNamed,
199 StructName,
200 Array,
201 Vector,
202 Pointer,
203 Target,
204 Function,
205 };
206
207 pub const NumEntry = struct {
208 pub const ops = [_]AbbrevOp{
209 .{ .literal = 1 },
210 .{ .fixed = 32 },
211 };
212 num: u32,
213 };
214
215 pub const Simple = struct {
216 pub const ops = [_]AbbrevOp{
217 .{ .vbr = 4 },
218 };
219 code: u5,
220 };
221
222 pub const Opaque = struct {
223 pub const ops = [_]AbbrevOp{
224 .{ .literal = 6 },
225 .{ .literal = 0 },
226 };
227 };
228
229 pub const Integer = struct {
230 pub const ops = [_]AbbrevOp{
231 .{ .literal = 7 },
232 .{ .fixed = 28 },
233 };
234 width: u28,
235 };
236
237 pub const StructAnon = struct {
238 pub const ops = [_]AbbrevOp{
239 .{ .literal = 18 },
240 .{ .fixed = 1 },
241 .{ .array_fixed_runtime = Builder.Type },
242 };
243 is_packed: bool,
244 types: []const Builder.Type,
245 };
246
247 pub const StructNamed = struct {
248 pub const ops = [_]AbbrevOp{
249 .{ .literal = 20 },
250 .{ .fixed = 1 },
251 .{ .array_fixed_runtime = Builder.Type },
252 };
253 is_packed: bool,
254 types: []const Builder.Type,
255 };
256
257 pub const StructName = struct {
258 pub const ops = [_]AbbrevOp{
259 .{ .literal = 19 },
260 .{ .array_fixed = 8 },
261 };
262 string: []const u8,
263 };
264
265 pub const Array = struct {
266 pub const ops = [_]AbbrevOp{
267 .{ .literal = 11 },
268 .{ .vbr = 16 },
269 .{ .fixed_runtime = Builder.Type },
270 };
271 len: u64,
272 child: Builder.Type,
273 };
274
275 pub const Vector = struct {
276 pub const ops = [_]AbbrevOp{
277 .{ .literal = 12 },
278 .{ .vbr = 16 },
279 .{ .fixed_runtime = Builder.Type },
280 };
281 len: u64,
282 child: Builder.Type,
283 };
284
285 pub const Pointer = struct {
286 pub const ops = [_]AbbrevOp{
287 .{ .literal = 25 },
288 .{ .vbr = 4 },
289 };
290 addr_space: Builder.AddrSpace,
291 };
292
293 pub const Target = struct {
294 pub const ops = [_]AbbrevOp{
295 .{ .literal = 26 },
296 .{ .vbr = 4 },
297 .{ .array_fixed_runtime = Builder.Type },
298 .{ .array_fixed = 32 },
299 };
300 num_types: u32,
301 types: []const Builder.Type,
302 ints: []const u32,
303 };
304
305 pub const Function = struct {
306 pub const ops = [_]AbbrevOp{
307 .{ .literal = 21 },
308 .{ .fixed = 1 },
309 .{ .fixed_runtime = Builder.Type },
310 .{ .array_fixed_runtime = Builder.Type },
311 };
312 is_vararg: bool,
313 return_type: Builder.Type,
314 param_types: []const Builder.Type,
315 };
316};
317
318pub const Paramattr = struct {
319 pub const id = 9;
320
321 pub const abbrevs = [_]type{
322 Entry,
323 };
324
325 pub const Entry = struct {
326 pub const ops = [_]AbbrevOp{
327 .{ .literal = 2 },
328 .{ .array_vbr = 8 },
329 };
330 group_indices: []const u64,
331 };
332};
333
334pub const ParamattrGroup = struct {
335 pub const id = 10;
336
337 pub const abbrevs = [_]type{};
338};
339
340pub const Constants = struct {
341 pub const id = 11;
342
343 pub const abbrevs = [_]type{
344 SetType,
345 Null,
346 Undef,
347 Poison,
348 Integer,
349 Half,
350 Float,
351 Double,
352 Fp80,
353 Fp128,
354 Aggregate,
355 String,
356 CString,
357 Cast,
358 Binary,
359 Cmp,
360 ExtractElement,
361 InsertElement,
362 ShuffleVector,
363 ShuffleVectorEx,
364 BlockAddress,
365 DsoLocalEquivalentOrNoCfi,
366 };
367
368 pub const SetType = struct {
369 pub const ops = [_]AbbrevOp{
370 .{ .literal = 1 },
371 .{ .fixed_runtime = Builder.Type },
372 };
373 type_id: Builder.Type,
374 };
375
376 pub const Null = struct {
377 pub const ops = [_]AbbrevOp{
378 .{ .literal = 2 },
379 };
380 };
381
382 pub const Undef = struct {
383 pub const ops = [_]AbbrevOp{
384 .{ .literal = 3 },
385 };
386 };
387
388 pub const Poison = struct {
389 pub const ops = [_]AbbrevOp{
390 .{ .literal = 26 },
391 };
392 };
393
394 pub const Integer = struct {
395 pub const ops = [_]AbbrevOp{
396 .{ .literal = 4 },
397 .{ .vbr = 16 },
398 };
399 value: u64,
400 };
401
402 pub const Half = struct {
403 pub const ops = [_]AbbrevOp{
404 .{ .literal = 6 },
405 .{ .fixed = 16 },
406 };
407 value: u16,
408 };
409
410 pub const Float = struct {
411 pub const ops = [_]AbbrevOp{
412 .{ .literal = 6 },
413 .{ .fixed = 32 },
414 };
415 value: u32,
416 };
417
418 pub const Double = struct {
419 pub const ops = [_]AbbrevOp{
420 .{ .literal = 6 },
421 .{ .vbr = 6 },
422 };
423 value: u64,
424 };
425
426 pub const Fp80 = struct {
427 pub const ops = [_]AbbrevOp{
428 .{ .literal = 6 },
429 .{ .vbr = 6 },
430 .{ .vbr = 6 },
431 };
432 hi: u64,
433 lo: u16,
434 };
435
436 pub const Fp128 = struct {
437 pub const ops = [_]AbbrevOp{
438 .{ .literal = 6 },
439 .{ .vbr = 6 },
440 .{ .vbr = 6 },
441 };
442 lo: u64,
443 hi: u64,
444 };
445
446 pub const Aggregate = struct {
447 pub const ops = [_]AbbrevOp{
448 .{ .literal = 7 },
449 .{ .array_fixed = 32 },
450 };
451 values: []const Builder.Constant,
452 };
453
454 pub const String = struct {
455 pub const ops = [_]AbbrevOp{
456 .{ .literal = 8 },
457 .{ .array_fixed = 8 },
458 };
459 string: []const u8,
460 };
461
462 pub const CString = struct {
463 pub const ops = [_]AbbrevOp{
464 .{ .literal = 9 },
465 .{ .array_fixed = 8 },
466 };
467 string: []const u8,
468 };
469
470 pub const Cast = struct {
471 const CastOpcode = Builder.CastOpcode;
472 pub const ops = [_]AbbrevOp{
473 .{ .literal = 11 },
474 .{ .fixed = @bitSizeOf(CastOpcode) },
475 .{ .fixed_runtime = Builder.Type },
476 ConstantAbbrev,
477 };
478
479 opcode: CastOpcode,
480 type_index: Builder.Type,
481 val: Builder.Constant,
482 };
483
484 pub const Binary = struct {
485 const BinaryOpcode = Builder.BinaryOpcode;
486 pub const ops = [_]AbbrevOp{
487 .{ .literal = 10 },
488 .{ .fixed = @bitSizeOf(BinaryOpcode) },
489 ConstantAbbrev,
490 ConstantAbbrev,
491 };
492
493 opcode: BinaryOpcode,
494 lhs: Builder.Constant,
495 rhs: Builder.Constant,
496 };
497
498 pub const Cmp = struct {
499 pub const ops = [_]AbbrevOp{
500 .{ .literal = 17 },
501 .{ .fixed_runtime = Builder.Type },
502 ConstantAbbrev,
503 ConstantAbbrev,
504 .{ .vbr = 6 },
505 };
506
507 ty: Builder.Type,
508 lhs: Builder.Constant,
509 rhs: Builder.Constant,
510 pred: u32,
511 };
512
513 pub const ExtractElement = struct {
514 pub const ops = [_]AbbrevOp{
515 .{ .literal = 14 },
516 .{ .fixed_runtime = Builder.Type },
517 ConstantAbbrev,
518 .{ .fixed_runtime = Builder.Type },
519 ConstantAbbrev,
520 };
521
522 val_type: Builder.Type,
523 val: Builder.Constant,
524 index_type: Builder.Type,
525 index: Builder.Constant,
526 };
527
528 pub const InsertElement = struct {
529 pub const ops = [_]AbbrevOp{
530 .{ .literal = 15 },
531 ConstantAbbrev,
532 ConstantAbbrev,
533 .{ .fixed_runtime = Builder.Type },
534 ConstantAbbrev,
535 };
536
537 val: Builder.Constant,
538 elem: Builder.Constant,
539 index_type: Builder.Type,
540 index: Builder.Constant,
541 };
542
543 pub const ShuffleVector = struct {
544 pub const ops = [_]AbbrevOp{
545 .{ .literal = 16 },
546 ValueAbbrev,
547 ValueAbbrev,
548 ValueAbbrev,
549 };
550
551 lhs: Builder.Constant,
552 rhs: Builder.Constant,
553 mask: Builder.Constant,
554 };
555
556 pub const ShuffleVectorEx = struct {
557 pub const ops = [_]AbbrevOp{
558 .{ .literal = 19 },
559 .{ .fixed_runtime = Builder.Type },
560 ValueAbbrev,
561 ValueAbbrev,
562 ValueAbbrev,
563 };
564
565 ty: Builder.Type,
566 lhs: Builder.Constant,
567 rhs: Builder.Constant,
568 mask: Builder.Constant,
569 };
570
571 pub const BlockAddress = struct {
572 pub const ops = [_]AbbrevOp{
573 .{ .literal = 21 },
574 .{ .fixed_runtime = Builder.Type },
575 ConstantAbbrev,
576 BlockAbbrev,
577 };
578 type_id: Builder.Type,
579 function: u32,
580 block: u32,
581 };
582
583 pub const DsoLocalEquivalentOrNoCfi = struct {
584 pub const ops = [_]AbbrevOp{
585 .{ .fixed = 5 },
586 .{ .fixed_runtime = Builder.Type },
587 ConstantAbbrev,
588 };
589 code: u5,
590 type_id: Builder.Type,
591 function: u32,
592 };
593};
594
595pub const MetadataKindBlock = struct {
596 pub const id = 22;
597
598 pub const abbrevs = [_]type{
599 Kind,
600 };
601
602 pub const Kind = struct {
603 pub const ops = [_]AbbrevOp{
604 .{ .literal = 6 },
605 .{ .vbr = 4 },
606 .{ .array_fixed = 8 },
607 };
608 id: u32,
609 name: []const u8,
610 };
611};
612
613pub const MetadataAttachmentBlock = struct {
614 pub const id = 16;
615
616 pub const abbrevs = [_]type{
617 AttachmentSingle,
618 };
619
620 pub const AttachmentSingle = struct {
621 pub const ops = [_]AbbrevOp{
622 .{ .literal = 11 },
623 .{ .fixed = 1 },
624 MetadataAbbrev,
625 };
626 kind: MetadataKind,
627 metadata: Builder.Metadata,
628 };
629};
630
631pub const MetadataBlock = struct {
632 pub const id = 15;
633
634 pub const abbrevs = [_]type{
635 Strings,
636 File,
637 CompileUnit,
638 Subprogram,
639 LexicalBlock,
640 Location,
641 BasicType,
642 CompositeType,
643 DerivedType,
644 SubroutineType,
645 Enumerator,
646 Subrange,
647 Expression,
648 Node,
649 LocalVar,
650 Parameter,
651 GlobalVar,
652 GlobalVarExpression,
653 Constant,
654 Name,
655 NamedNode,
656 GlobalDeclAttachment,
657 };
658
659 pub const Strings = struct {
660 pub const ops = [_]AbbrevOp{
661 .{ .literal = 35 },
662 .{ .vbr = 6 },
663 .{ .vbr = 6 },
664 .blob,
665 };
666 num_strings: u32,
667 strings_offset: u32,
668 blob: []const u8,
669 };
670
671 pub const File = struct {
672 pub const ops = [_]AbbrevOp{
673 .{ .literal = 16 },
674 .{ .literal = 0 }, // is distinct
675 MetadataAbbrev, // filename
676 MetadataAbbrev, // directory
677 .{ .literal = 0 }, // checksum
678 .{ .literal = 0 }, // checksum
679 };
680
681 filename: Builder.MetadataString,
682 directory: Builder.MetadataString,
683 };
684
685 pub const CompileUnit = struct {
686 pub const ops = [_]AbbrevOp{
687 .{ .literal = 20 },
688 .{ .literal = 1 }, // is distinct
689 .{ .literal = std.dwarf.LANG.C99 }, // source language
690 MetadataAbbrev, // file
691 MetadataAbbrev, // producer
692 .{ .fixed = 1 }, // isOptimized
693 .{ .literal = 0 }, // raw flags
694 .{ .literal = 0 }, // runtime version
695 .{ .literal = 0 }, // split debug file name
696 .{ .literal = 1 }, // emission kind
697 MetadataAbbrev, // enums
698 .{ .literal = 0 }, // retained types
699 .{ .literal = 0 }, // subprograms
700 MetadataAbbrev, // globals
701 .{ .literal = 0 }, // imported entities
702 .{ .literal = 0 }, // DWO ID
703 .{ .literal = 0 }, // macros
704 .{ .literal = 0 }, // split debug inlining
705 .{ .literal = 0 }, // debug info profiling
706 .{ .literal = 0 }, // name table kind
707 .{ .literal = 0 }, // ranges base address
708 .{ .literal = 0 }, // raw sysroot
709 .{ .literal = 0 }, // raw SDK
710 };
711
712 file: Builder.Metadata,
713 producer: Builder.MetadataString,
714 is_optimized: bool,
715 enums: Builder.Metadata,
716 globals: Builder.Metadata,
717 };
718
719 pub const Subprogram = struct {
720 pub const ops = [_]AbbrevOp{
721 .{ .literal = 21 },
722 .{ .literal = 0b111 }, // is distinct | has sp flags | has flags
723 MetadataAbbrev, // scope
724 MetadataAbbrev, // name
725 MetadataAbbrev, // linkage name
726 MetadataAbbrev, // file
727 LineAbbrev, // line
728 MetadataAbbrev, // type
729 LineAbbrev, // scope line
730 .{ .literal = 0 }, // containing type
731 .{ .fixed = 32 }, // sp flags
732 .{ .literal = 0 }, // virtual index
733 .{ .fixed = 32 }, // flags
734 MetadataAbbrev, // compile unit
735 .{ .literal = 0 }, // template params
736 .{ .literal = 0 }, // declaration
737 .{ .literal = 0 }, // retained nodes
738 .{ .literal = 0 }, // this adjustment
739 .{ .literal = 0 }, // thrown types
740 .{ .literal = 0 }, // annotations
741 .{ .literal = 0 }, // target function name
742 };
743
744 scope: Builder.Metadata,
745 name: Builder.MetadataString,
746 linkage_name: Builder.MetadataString,
747 file: Builder.Metadata,
748 line: u32,
749 ty: Builder.Metadata,
750 scope_line: u32,
751 sp_flags: Builder.Metadata.Subprogram.DISPFlags,
752 flags: Builder.Metadata.DIFlags,
753 compile_unit: Builder.Metadata,
754 };
755
756 pub const LexicalBlock = struct {
757 pub const ops = [_]AbbrevOp{
758 .{ .literal = 22 },
759 .{ .literal = 0 }, // is distinct
760 MetadataAbbrev, // scope
761 MetadataAbbrev, // file
762 LineAbbrev, // line
763 ColumnAbbrev, // column
764 };
765
766 scope: Builder.Metadata,
767 file: Builder.Metadata,
768 line: u32,
769 column: u32,
770 };
771
772 pub const Location = struct {
773 pub const ops = [_]AbbrevOp{
774 .{ .literal = 7 },
775 .{ .literal = 0 }, // is distinct
776 LineAbbrev, // line
777 ColumnAbbrev, // column
778 MetadataAbbrev, // scope
779 MetadataAbbrev, // inlined at
780 .{ .literal = 0 }, // is implicit code
781 };
782
783 line: u32,
784 column: u32,
785 scope: u32,
786 inlined_at: Builder.Metadata,
787 };
788
789 pub const BasicType = struct {
790 pub const ops = [_]AbbrevOp{
791 .{ .literal = 15 },
792 .{ .literal = 0 }, // is distinct
793 .{ .literal = std.dwarf.TAG.base_type }, // tag
794 MetadataAbbrev, // name
795 .{ .vbr = 6 }, // size in bits
796 .{ .literal = 0 }, // align in bits
797 .{ .vbr = 8 }, // encoding
798 .{ .literal = 0 }, // flags
799 };
800
801 name: Builder.MetadataString,
802 size_in_bits: u64,
803 encoding: u32,
804 };
805
806 pub const CompositeType = struct {
807 pub const ops = [_]AbbrevOp{
808 .{ .literal = 18 },
809 .{ .literal = 0 | 0x2 }, // is distinct | is not used in old type ref
810 .{ .fixed = 32 }, // tag
811 MetadataAbbrev, // name
812 MetadataAbbrev, // file
813 LineAbbrev, // line
814 MetadataAbbrev, // scope
815 MetadataAbbrev, // underlying type
816 .{ .vbr = 6 }, // size in bits
817 .{ .vbr = 6 }, // align in bits
818 .{ .literal = 0 }, // offset in bits
819 .{ .fixed = 32 }, // flags
820 MetadataAbbrev, // elements
821 .{ .literal = 0 }, // runtime lang
822 .{ .literal = 0 }, // vtable holder
823 .{ .literal = 0 }, // template params
824 .{ .literal = 0 }, // raw id
825 .{ .literal = 0 }, // discriminator
826 .{ .literal = 0 }, // data location
827 .{ .literal = 0 }, // associated
828 .{ .literal = 0 }, // allocated
829 .{ .literal = 0 }, // rank
830 .{ .literal = 0 }, // annotations
831 };
832
833 tag: u32,
834 name: Builder.MetadataString,
835 file: Builder.Metadata,
836 line: u32,
837 scope: Builder.Metadata,
838 underlying_type: Builder.Metadata,
839 size_in_bits: u64,
840 align_in_bits: u64,
841 flags: Builder.Metadata.DIFlags,
842 elements: Builder.Metadata,
843 };
844
845 pub const DerivedType = struct {
846 pub const ops = [_]AbbrevOp{
847 .{ .literal = 17 },
848 .{ .literal = 0 }, // is distinct
849 .{ .fixed = 32 }, // tag
850 MetadataAbbrev, // name
851 MetadataAbbrev, // file
852 LineAbbrev, // line
853 MetadataAbbrev, // scope
854 MetadataAbbrev, // underlying type
855 .{ .vbr = 6 }, // size in bits
856 .{ .vbr = 6 }, // align in bits
857 .{ .vbr = 6 }, // offset in bits
858 .{ .literal = 0 }, // flags
859 .{ .literal = 0 }, // extra data
860 };
861
862 tag: u32,
863 name: Builder.MetadataString,
864 file: Builder.Metadata,
865 line: u32,
866 scope: Builder.Metadata,
867 underlying_type: Builder.Metadata,
868 size_in_bits: u64,
869 align_in_bits: u64,
870 offset_in_bits: u64,
871 };
872
873 pub const SubroutineType = struct {
874 pub const ops = [_]AbbrevOp{
875 .{ .literal = 19 },
876 .{ .literal = 0 | 0x2 }, // is distinct | has no old type refs
877 .{ .literal = 0 }, // flags
878 MetadataAbbrev, // types
879 .{ .literal = 0 }, // cc
880 };
881
882 types: Builder.Metadata,
883 };
884
885 pub const Enumerator = struct {
886 pub const id = 14;
887
888 pub const Flags = packed struct(u3) {
889 distinct: bool = false,
890 unsigned: bool,
891 bigint: bool,
892 };
893
894 pub const ops = [_]AbbrevOp{
895 .{ .literal = Enumerator.id },
896 .{ .fixed = @bitSizeOf(Flags) }, // flags
897 .{ .vbr = 6 }, // bit width
898 MetadataAbbrev, // name
899 .{ .vbr = 16 }, // integer value
900 };
901
902 flags: Flags,
903 bit_width: u32,
904 name: Builder.MetadataString,
905 value: u64,
906 };
907
908 pub const Subrange = struct {
909 pub const ops = [_]AbbrevOp{
910 .{ .literal = 13 },
911 .{ .literal = 0b10 }, // is distinct | version
912 MetadataAbbrev, // count
913 MetadataAbbrev, // lower bound
914 .{ .literal = 0 }, // upper bound
915 .{ .literal = 0 }, // stride
916 };
917
918 count: Builder.Metadata,
919 lower_bound: Builder.Metadata,
920 };
921
922 pub const Expression = struct {
923 pub const ops = [_]AbbrevOp{
924 .{ .literal = 29 },
925 .{ .literal = 0 | (3 << 1) }, // is distinct | version
926 MetadataArrayAbbrev, // elements
927 };
928
929 elements: []const u32,
930 };
931
932 pub const Node = struct {
933 pub const ops = [_]AbbrevOp{
934 .{ .literal = 3 },
935 MetadataArrayAbbrev, // elements
936 };
937
938 elements: []const Builder.Metadata,
939 };
940
941 pub const LocalVar = struct {
942 pub const ops = [_]AbbrevOp{
943 .{ .literal = 28 },
944 .{ .literal = 0b10 }, // is distinct | has alignment
945 MetadataAbbrev, // scope
946 MetadataAbbrev, // name
947 MetadataAbbrev, // file
948 LineAbbrev, // line
949 MetadataAbbrev, // type
950 .{ .literal = 0 }, // arg
951 .{ .literal = 0 }, // flags
952 .{ .literal = 0 }, // align bits
953 .{ .literal = 0 }, // annotations
954 };
955
956 scope: Builder.Metadata,
957 name: Builder.MetadataString,
958 file: Builder.Metadata,
959 line: u32,
960 ty: Builder.Metadata,
961 };
962
963 pub const Parameter = struct {
964 pub const ops = [_]AbbrevOp{
965 .{ .literal = 28 },
966 .{ .literal = 0b10 }, // is distinct | has alignment
967 MetadataAbbrev, // scope
968 MetadataAbbrev, // name
969 MetadataAbbrev, // file
970 LineAbbrev, // line
971 MetadataAbbrev, // type
972 .{ .vbr = 4 }, // arg
973 .{ .literal = 0 }, // flags
974 .{ .literal = 0 }, // align bits
975 .{ .literal = 0 }, // annotations
976 };
977
978 scope: Builder.Metadata,
979 name: Builder.MetadataString,
980 file: Builder.Metadata,
981 line: u32,
982 ty: Builder.Metadata,
983 arg: u32,
984 };
985
986 pub const GlobalVar = struct {
987 pub const ops = [_]AbbrevOp{
988 .{ .literal = 27 },
989 .{ .literal = 0b101 }, // is distinct | version
990 MetadataAbbrev, // scope
991 MetadataAbbrev, // name
992 MetadataAbbrev, // linkage name
993 MetadataAbbrev, // file
994 LineAbbrev, // line
995 MetadataAbbrev, // type
996 .{ .fixed = 1 }, // local
997 .{ .literal = 1 }, // defined
998 .{ .literal = 0 }, // static data members declaration
999 .{ .literal = 0 }, // template params
1000 .{ .literal = 0 }, // align in bits
1001 .{ .literal = 0 }, // annotations
1002 };
1003
1004 scope: Builder.Metadata,
1005 name: Builder.MetadataString,
1006 linkage_name: Builder.MetadataString,
1007 file: Builder.Metadata,
1008 line: u32,
1009 ty: Builder.Metadata,
1010 local: bool,
1011 };
1012
1013 pub const GlobalVarExpression = struct {
1014 pub const ops = [_]AbbrevOp{
1015 .{ .literal = 37 },
1016 .{ .literal = 0 }, // is distinct
1017 MetadataAbbrev, // variable
1018 MetadataAbbrev, // expression
1019 };
1020
1021 variable: Builder.Metadata,
1022 expression: Builder.Metadata,
1023 };
1024
1025 pub const Constant = struct {
1026 pub const ops = [_]AbbrevOp{
1027 .{ .literal = 2 },
1028 MetadataAbbrev, // type
1029 MetadataAbbrev, // value
1030 };
1031
1032 ty: Builder.Type,
1033 constant: Builder.Constant,
1034 };
1035
1036 pub const Name = struct {
1037 pub const ops = [_]AbbrevOp{
1038 .{ .literal = 4 },
1039 .{ .array_fixed = 8 }, // name
1040 };
1041
1042 name: []const u8,
1043 };
1044
1045 pub const NamedNode = struct {
1046 pub const ops = [_]AbbrevOp{
1047 .{ .literal = 10 },
1048 MetadataArrayAbbrev, // elements
1049 };
1050
1051 elements: []const Builder.Metadata,
1052 };
1053
1054 pub const GlobalDeclAttachment = struct {
1055 pub const ops = [_]AbbrevOp{
1056 .{ .literal = 36 },
1057 ValueAbbrev, // value id
1058 .{ .fixed = 1 }, // kind
1059 MetadataAbbrev, // elements
1060 };
1061
1062 value: Builder.Constant,
1063 kind: MetadataKind,
1064 metadata: Builder.Metadata,
1065 };
1066};
1067
1068pub const FunctionMetadataBlock = struct {
1069 pub const id = 15;
1070
1071 pub const abbrevs = [_]type{
1072 Value,
1073 };
1074
1075 pub const Value = struct {
1076 pub const ops = [_]AbbrevOp{
1077 .{ .literal = 2 },
1078 .{ .fixed = 32 }, // variable
1079 .{ .fixed = 32 }, // expression
1080 };
1081
1082 ty: Builder.Type,
1083 value: Builder.Value,
1084 };
1085};
1086
1087pub const FunctionBlock = struct {
1088 pub const id = 12;
1089
1090 pub const abbrevs = [_]type{
1091 DeclareBlocks,
1092 Call,
1093 CallFast,
1094 FNeg,
1095 FNegFast,
1096 Binary,
1097 BinaryFast,
1098 Cmp,
1099 CmpFast,
1100 Select,
1101 SelectFast,
1102 Cast,
1103 Alloca,
1104 GetElementPtr,
1105 ExtractValue,
1106 InsertValue,
1107 ExtractElement,
1108 InsertElement,
1109 ShuffleVector,
1110 RetVoid,
1111 Ret,
1112 Unreachable,
1113 Load,
1114 LoadAtomic,
1115 Store,
1116 StoreAtomic,
1117 BrUnconditional,
1118 BrConditional,
1119 VaArg,
1120 AtomicRmw,
1121 CmpXchg,
1122 Fence,
1123 DebugLoc,
1124 DebugLocAgain,
1125 };
1126
1127 pub const DeclareBlocks = struct {
1128 pub const ops = [_]AbbrevOp{
1129 .{ .literal = 1 },
1130 .{ .vbr = 8 },
1131 };
1132 num_blocks: usize,
1133 };
1134
1135 pub const Call = struct {
1136 pub const CallType = packed struct(u17) {
1137 tail: bool = false,
1138 call_conv: Builder.CallConv,
1139 reserved: u3 = 0,
1140 must_tail: bool = false,
1141 // We always use the explicit type version as that is what LLVM does
1142 explicit_type: bool = true,
1143 no_tail: bool = false,
1144 };
1145 pub const ops = [_]AbbrevOp{
1146 .{ .literal = 34 },
1147 .{ .fixed_runtime = Builder.FunctionAttributes },
1148 .{ .fixed = @bitSizeOf(CallType) },
1149 .{ .fixed_runtime = Builder.Type },
1150 ValueAbbrev, // Callee
1151 ValueArrayAbbrev, // Args
1152 };
1153
1154 attributes: Builder.FunctionAttributes,
1155 call_type: CallType,
1156 type_id: Builder.Type,
1157 callee: Builder.Value,
1158 args: []const Builder.Value,
1159 };
1160
1161 pub const CallFast = struct {
1162 const CallType = packed struct(u18) {
1163 tail: bool = false,
1164 call_conv: Builder.CallConv,
1165 reserved: u3 = 0,
1166 must_tail: bool = false,
1167 // We always use the explicit type version as that is what LLVM does
1168 explicit_type: bool = true,
1169 no_tail: bool = false,
1170 fast: bool = true,
1171 };
1172
1173 pub const ops = [_]AbbrevOp{
1174 .{ .literal = 34 },
1175 .{ .fixed_runtime = Builder.FunctionAttributes },
1176 .{ .fixed = @bitSizeOf(CallType) },
1177 .{ .fixed = @bitSizeOf(Builder.FastMath) },
1178 .{ .fixed_runtime = Builder.Type },
1179 ValueAbbrev, // Callee
1180 ValueArrayAbbrev, // Args
1181 };
1182
1183 attributes: Builder.FunctionAttributes,
1184 call_type: CallType,
1185 fast_math: Builder.FastMath,
1186 type_id: Builder.Type,
1187 callee: Builder.Value,
1188 args: []const Builder.Value,
1189 };
1190
1191 pub const FNeg = struct {
1192 pub const ops = [_]AbbrevOp{
1193 .{ .literal = 56 },
1194 ValueAbbrev,
1195 .{ .literal = 0 },
1196 };
1197
1198 val: u32,
1199 };
1200
1201 pub const FNegFast = struct {
1202 pub const ops = [_]AbbrevOp{
1203 .{ .literal = 56 },
1204 ValueAbbrev,
1205 .{ .literal = 0 },
1206 .{ .fixed = @bitSizeOf(Builder.FastMath) },
1207 };
1208
1209 val: u32,
1210 fast_math: Builder.FastMath,
1211 };
1212
1213 pub const Binary = struct {
1214 const BinaryOpcode = Builder.BinaryOpcode;
1215 pub const ops = [_]AbbrevOp{
1216 .{ .literal = 2 },
1217 ValueAbbrev,
1218 ValueAbbrev,
1219 .{ .fixed = @bitSizeOf(BinaryOpcode) },
1220 };
1221
1222 lhs: u32,
1223 rhs: u32,
1224 opcode: BinaryOpcode,
1225 };
1226
1227 pub const BinaryFast = struct {
1228 const BinaryOpcode = Builder.BinaryOpcode;
1229 pub const ops = [_]AbbrevOp{
1230 .{ .literal = 2 },
1231 ValueAbbrev,
1232 ValueAbbrev,
1233 .{ .fixed = @bitSizeOf(BinaryOpcode) },
1234 .{ .fixed = @bitSizeOf(Builder.FastMath) },
1235 };
1236
1237 lhs: u32,
1238 rhs: u32,
1239 opcode: BinaryOpcode,
1240 fast_math: Builder.FastMath,
1241 };
1242
1243 pub const Cmp = struct {
1244 const CmpPredicate = Builder.CmpPredicate;
1245 pub const ops = [_]AbbrevOp{
1246 .{ .literal = 28 },
1247 ValueAbbrev,
1248 ValueAbbrev,
1249 .{ .fixed = @bitSizeOf(CmpPredicate) },
1250 };
1251
1252 lhs: u32,
1253 rhs: u32,
1254 pred: CmpPredicate,
1255 };
1256
1257 pub const CmpFast = struct {
1258 const CmpPredicate = Builder.CmpPredicate;
1259 pub const ops = [_]AbbrevOp{
1260 .{ .literal = 28 },
1261 ValueAbbrev,
1262 ValueAbbrev,
1263 .{ .fixed = @bitSizeOf(CmpPredicate) },
1264 .{ .fixed = @bitSizeOf(Builder.FastMath) },
1265 };
1266
1267 lhs: u32,
1268 rhs: u32,
1269 pred: CmpPredicate,
1270 fast_math: Builder.FastMath,
1271 };
1272
1273 pub const Select = struct {
1274 pub const ops = [_]AbbrevOp{
1275 .{ .literal = 29 },
1276 ValueAbbrev,
1277 ValueAbbrev,
1278 ValueAbbrev,
1279 };
1280
1281 lhs: u32,
1282 rhs: u32,
1283 cond: u32,
1284 };
1285
1286 pub const SelectFast = struct {
1287 pub const ops = [_]AbbrevOp{
1288 .{ .literal = 29 },
1289 ValueAbbrev,
1290 ValueAbbrev,
1291 ValueAbbrev,
1292 .{ .fixed = @bitSizeOf(Builder.FastMath) },
1293 };
1294
1295 lhs: u32,
1296 rhs: u32,
1297 cond: u32,
1298 fast_math: Builder.FastMath,
1299 };
1300
1301 pub const Cast = struct {
1302 const CastOpcode = Builder.CastOpcode;
1303 pub const ops = [_]AbbrevOp{
1304 .{ .literal = 3 },
1305 ValueAbbrev,
1306 .{ .fixed_runtime = Builder.Type },
1307 .{ .fixed = @bitSizeOf(CastOpcode) },
1308 };
1309
1310 val: u32,
1311 type_index: Builder.Type,
1312 opcode: CastOpcode,
1313 };
1314
1315 pub const Alloca = struct {
1316 pub const Flags = packed struct(u11) {
1317 align_lower: u5,
1318 inalloca: bool,
1319 explicit_type: bool,
1320 swift_error: bool,
1321 align_upper: u3,
1322 };
1323 pub const ops = [_]AbbrevOp{
1324 .{ .literal = 19 },
1325 .{ .fixed_runtime = Builder.Type },
1326 .{ .fixed_runtime = Builder.Type },
1327 ValueAbbrev,
1328 .{ .fixed = @bitSizeOf(Flags) },
1329 };
1330
1331 inst_type: Builder.Type,
1332 len_type: Builder.Type,
1333 len_value: u32,
1334 flags: Flags,
1335 };
1336
1337 pub const RetVoid = struct {
1338 pub const ops = [_]AbbrevOp{
1339 .{ .literal = 10 },
1340 };
1341 };
1342
1343 pub const Ret = struct {
1344 pub const ops = [_]AbbrevOp{
1345 .{ .literal = 10 },
1346 ValueAbbrev,
1347 };
1348 val: u32,
1349 };
1350
1351 pub const GetElementPtr = struct {
1352 pub const ops = [_]AbbrevOp{
1353 .{ .literal = 43 },
1354 .{ .fixed = 1 },
1355 .{ .fixed_runtime = Builder.Type },
1356 ValueAbbrev,
1357 ValueArrayAbbrev,
1358 };
1359
1360 is_inbounds: bool,
1361 type_index: Builder.Type,
1362 base: Builder.Value,
1363 indices: []const Builder.Value,
1364 };
1365
1366 pub const ExtractValue = struct {
1367 pub const ops = [_]AbbrevOp{
1368 .{ .literal = 26 },
1369 ValueAbbrev,
1370 ValueArrayAbbrev,
1371 };
1372
1373 val: u32,
1374 indices: []const u32,
1375 };
1376
1377 pub const InsertValue = struct {
1378 pub const ops = [_]AbbrevOp{
1379 .{ .literal = 27 },
1380 ValueAbbrev,
1381 ValueAbbrev,
1382 ValueArrayAbbrev,
1383 };
1384
1385 val: u32,
1386 elem: u32,
1387 indices: []const u32,
1388 };
1389
1390 pub const ExtractElement = struct {
1391 pub const ops = [_]AbbrevOp{
1392 .{ .literal = 6 },
1393 ValueAbbrev,
1394 ValueAbbrev,
1395 };
1396
1397 val: u32,
1398 index: u32,
1399 };
1400
1401 pub const InsertElement = struct {
1402 pub const ops = [_]AbbrevOp{
1403 .{ .literal = 7 },
1404 ValueAbbrev,
1405 ValueAbbrev,
1406 ValueAbbrev,
1407 };
1408
1409 val: u32,
1410 elem: u32,
1411 index: u32,
1412 };
1413
1414 pub const ShuffleVector = struct {
1415 pub const ops = [_]AbbrevOp{
1416 .{ .literal = 8 },
1417 ValueAbbrev,
1418 ValueAbbrev,
1419 ValueAbbrev,
1420 };
1421
1422 lhs: u32,
1423 rhs: u32,
1424 mask: u32,
1425 };
1426
1427 pub const Unreachable = struct {
1428 pub const ops = [_]AbbrevOp{
1429 .{ .literal = 15 },
1430 };
1431 };
1432
1433 pub const Load = struct {
1434 pub const ops = [_]AbbrevOp{
1435 .{ .literal = 20 },
1436 ValueAbbrev,
1437 .{ .fixed_runtime = Builder.Type },
1438 .{ .fixed = @bitSizeOf(Builder.Alignment) },
1439 .{ .fixed = 1 },
1440 };
1441 ptr: u32,
1442 ty: Builder.Type,
1443 alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)),
1444 is_volatile: bool,
1445 };
1446
1447 pub const LoadAtomic = struct {
1448 pub const ops = [_]AbbrevOp{
1449 .{ .literal = 41 },
1450 ValueAbbrev,
1451 .{ .fixed_runtime = Builder.Type },
1452 .{ .fixed = @bitSizeOf(Builder.Alignment) },
1453 .{ .fixed = 1 },
1454 .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) },
1455 .{ .fixed = @bitSizeOf(Builder.SyncScope) },
1456 };
1457 ptr: u32,
1458 ty: Builder.Type,
1459 alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)),
1460 is_volatile: bool,
1461 success_ordering: Builder.AtomicOrdering,
1462 sync_scope: Builder.SyncScope,
1463 };
1464
1465 pub const Store = struct {
1466 pub const ops = [_]AbbrevOp{
1467 .{ .literal = 44 },
1468 ValueAbbrev,
1469 ValueAbbrev,
1470 .{ .fixed = @bitSizeOf(Builder.Alignment) },
1471 .{ .fixed = 1 },
1472 };
1473 ptr: u32,
1474 val: u32,
1475 alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)),
1476 is_volatile: bool,
1477 };
1478
1479 pub const StoreAtomic = struct {
1480 pub const ops = [_]AbbrevOp{
1481 .{ .literal = 45 },
1482 ValueAbbrev,
1483 ValueAbbrev,
1484 .{ .fixed = @bitSizeOf(Builder.Alignment) },
1485 .{ .fixed = 1 },
1486 .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) },
1487 .{ .fixed = @bitSizeOf(Builder.SyncScope) },
1488 };
1489 ptr: u32,
1490 val: u32,
1491 alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)),
1492 is_volatile: bool,
1493 success_ordering: Builder.AtomicOrdering,
1494 sync_scope: Builder.SyncScope,
1495 };
1496
1497 pub const BrUnconditional = struct {
1498 pub const ops = [_]AbbrevOp{
1499 .{ .literal = 11 },
1500 BlockAbbrev,
1501 };
1502 block: u32,
1503 };
1504
1505 pub const BrConditional = struct {
1506 pub const ops = [_]AbbrevOp{
1507 .{ .literal = 11 },
1508 BlockAbbrev,
1509 BlockAbbrev,
1510 BlockAbbrev,
1511 };
1512 then_block: u32,
1513 else_block: u32,
1514 condition: u32,
1515 };
1516
1517 pub const VaArg = struct {
1518 pub const ops = [_]AbbrevOp{
1519 .{ .literal = 23 },
1520 .{ .fixed_runtime = Builder.Type },
1521 ValueAbbrev,
1522 .{ .fixed_runtime = Builder.Type },
1523 };
1524 list_type: Builder.Type,
1525 list: u32,
1526 type: Builder.Type,
1527 };
1528
1529 pub const AtomicRmw = struct {
1530 pub const ops = [_]AbbrevOp{
1531 .{ .literal = 59 },
1532 ValueAbbrev,
1533 ValueAbbrev,
1534 .{ .fixed = @bitSizeOf(Builder.Function.Instruction.AtomicRmw.Operation) },
1535 .{ .fixed = 1 },
1536 .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) },
1537 .{ .fixed = @bitSizeOf(Builder.SyncScope) },
1538 .{ .fixed = @bitSizeOf(Builder.Alignment) },
1539 };
1540 ptr: u32,
1541 val: u32,
1542 operation: Builder.Function.Instruction.AtomicRmw.Operation,
1543 is_volatile: bool,
1544 success_ordering: Builder.AtomicOrdering,
1545 sync_scope: Builder.SyncScope,
1546 alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)),
1547 };
1548
1549 pub const CmpXchg = struct {
1550 pub const ops = [_]AbbrevOp{
1551 .{ .literal = 46 },
1552 ValueAbbrev,
1553 ValueAbbrev,
1554 ValueAbbrev,
1555 .{ .fixed = 1 },
1556 .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) },
1557 .{ .fixed = @bitSizeOf(Builder.SyncScope) },
1558 .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) },
1559 .{ .fixed = 1 },
1560 .{ .fixed = @bitSizeOf(Builder.Alignment) },
1561 };
1562 ptr: u32,
1563 cmp: u32,
1564 new: u32,
1565 is_volatile: bool,
1566 success_ordering: Builder.AtomicOrdering,
1567 sync_scope: Builder.SyncScope,
1568 failure_ordering: Builder.AtomicOrdering,
1569 is_weak: bool,
1570 alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)),
1571 };
1572
1573 pub const Fence = struct {
1574 pub const ops = [_]AbbrevOp{
1575 .{ .literal = 36 },
1576 .{ .fixed = @bitSizeOf(Builder.AtomicOrdering) },
1577 .{ .fixed = @bitSizeOf(Builder.SyncScope) },
1578 };
1579 ordering: Builder.AtomicOrdering,
1580 sync_scope: Builder.SyncScope,
1581 };
1582
1583 pub const DebugLoc = struct {
1584 pub const ops = [_]AbbrevOp{
1585 .{ .literal = 35 },
1586 .{ .fixed = 32 },
1587 .{ .fixed = 32 },
1588 .{ .fixed = 32 },
1589 .{ .fixed = 32 },
1590 .{ .fixed = 1 },
1591 };
1592 line: u32,
1593 column: u32,
1594 scope: Builder.Metadata,
1595 inlined_at: Builder.Metadata,
1596 is_implicit: bool,
1597 };
1598
1599 pub const DebugLocAgain = struct {
1600 pub const ops = [_]AbbrevOp{
1601 .{ .literal = 33 },
1602 };
1603 };
1604};
1605
1606pub const FunctionValueSymbolTable = struct {
1607 pub const id = 14;
1608
1609 pub const abbrevs = [_]type{
1610 BlockEntry,
1611 };
1612
1613 pub const BlockEntry = struct {
1614 pub const ops = [_]AbbrevOp{
1615 .{ .literal = 2 },
1616 ValueAbbrev,
1617 .{ .array_fixed = 8 },
1618 };
1619 value_id: u32,
1620 string: []const u8,
1621 };
1622};
1623
1624pub const Strtab = struct {
1625 pub const id = 23;
1626
1627 pub const abbrevs = [_]type{Blob};
1628
1629 pub const Blob = struct {
1630 pub const ops = [_]AbbrevOp{
1631 .{ .literal = 1 },
1632 .blob,
1633 };
1634 blob: []const u8,
1635 };
1636};
src/link.zig+1-2
......@@ -839,10 +839,9 @@ pub const File = struct {
839839 }
840840
841841 const llvm_bindings = @import("codegen/llvm/bindings.zig");
842 const Builder = @import("codegen/llvm/Builder.zig");
843842 const llvm = @import("codegen/llvm.zig");
844843 const target = comp.root_mod.resolved_target.result;
845 Builder.initializeLLVMTarget(target.cpu.arch);
844 llvm.initializeLLVMTarget(target.cpu.arch);
846845 const os_tag = llvm.targetOs(target.os.tag);
847846 const bad = llvm_bindings.WriteArchive(full_out_path_z, object_files.items.ptr, object_files.items.len, os_tag);
848847 if (bad) return error.UnableToWriteArchive;
src/zig_llvm.cpp-624
......@@ -24,9 +24,7 @@
2424#include <llvm/Analysis/TargetLibraryInfo.h>
2525#include <llvm/Analysis/TargetTransformInfo.h>
2626#include <llvm/Bitcode/BitcodeWriter.h>
27#include <llvm/IR/DIBuilder.h>
2827#include <llvm/IR/DiagnosticInfo.h>
29#include <llvm/IR/IRBuilder.h>
3028#include <llvm/IR/InlineAsm.h>
3129#include <llvm/IR/Instructions.h>
3230#include <llvm/IR/LegacyPassManager.h>
......@@ -382,566 +380,10 @@ void ZigLLVMSetOptBisectLimit(LLVMContextRef context_ref, int limit) {
382380 unwrap(context_ref)->setOptPassGate(opt_bisect);
383381}
384382
385LLVMValueRef ZigLLVMAddFunctionInAddressSpace(LLVMModuleRef M, const char *Name, LLVMTypeRef FunctionTy, unsigned AddressSpace) {
386 Function* func = Function::Create(unwrap<FunctionType>(FunctionTy), GlobalValue::ExternalLinkage, AddressSpace, Name, unwrap(M));
387 return wrap(func);
388}
389
390void ZigLLVMSetTailCallKind(LLVMValueRef Call, enum ZigLLVMTailCallKind TailCallKind) {
391 CallInst::TailCallKind TCK;
392 switch (TailCallKind) {
393 case ZigLLVMTailCallKindNone:
394 TCK = CallInst::TCK_None;
395 break;
396 case ZigLLVMTailCallKindTail:
397 TCK = CallInst::TCK_Tail;
398 break;
399 case ZigLLVMTailCallKindMustTail:
400 TCK = CallInst::TCK_MustTail;
401 break;
402 case ZigLLVMTailCallKindNoTail:
403 TCK = CallInst::TCK_NoTail;
404 break;
405 }
406 unwrap<CallInst>(Call)->setTailCallKind(TCK);
407}
408
409void ZigLLVMFnSetSubprogram(LLVMValueRef fn, ZigLLVMDISubprogram *subprogram) {
410 assert( isa<Function>(unwrap(fn)) );
411 Function *unwrapped_function = reinterpret_cast<Function*>(unwrap(fn));
412 unwrapped_function->setSubprogram(reinterpret_cast<DISubprogram*>(subprogram));
413}
414
415
416ZigLLVMDIType *ZigLLVMCreateDebugPointerType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIType *pointee_type,
417 uint64_t size_in_bits, uint64_t align_in_bits, const char *name)
418{
419 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createPointerType(
420 reinterpret_cast<DIType*>(pointee_type), size_in_bits, align_in_bits, std::optional<unsigned>(), name);
421 return reinterpret_cast<ZigLLVMDIType*>(di_type);
422}
423
424ZigLLVMDIType *ZigLLVMCreateDebugBasicType(ZigLLVMDIBuilder *dibuilder, const char *name,
425 uint64_t size_in_bits, unsigned encoding)
426{
427 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createBasicType(
428 name, size_in_bits, encoding);
429 return reinterpret_cast<ZigLLVMDIType*>(di_type);
430}
431
432struct ZigLLVMDIType *ZigLLVMDIBuilderCreateVectorType(struct ZigLLVMDIBuilder *dibuilder,
433 uint64_t SizeInBits, uint32_t AlignInBits, struct ZigLLVMDIType *Ty, uint32_t elem_count)
434{
435 SmallVector<Metadata *, 1> subrange;
436 subrange.push_back(reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateSubrange(0, elem_count));
437 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createVectorType(
438 SizeInBits,
439 AlignInBits,
440 reinterpret_cast<DIType*>(Ty),
441 reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(subrange));
442 return reinterpret_cast<ZigLLVMDIType*>(di_type);
443}
444
445ZigLLVMDIType *ZigLLVMCreateDebugArrayType(ZigLLVMDIBuilder *dibuilder, uint64_t size_in_bits,
446 uint64_t align_in_bits, ZigLLVMDIType *elem_type, int64_t elem_count)
447{
448 SmallVector<Metadata *, 1> subrange;
449 subrange.push_back(reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateSubrange(0, elem_count));
450 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createArrayType(
451 size_in_bits, align_in_bits,
452 reinterpret_cast<DIType*>(elem_type),
453 reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(subrange));
454 return reinterpret_cast<ZigLLVMDIType*>(di_type);
455}
456
457ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(ZigLLVMDIBuilder *dibuilder, const char *name, uint64_t val, bool isUnsigned) {
458 DIEnumerator *di_enumerator = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerator(name, val, isUnsigned);
459 return reinterpret_cast<ZigLLVMDIEnumerator*>(di_enumerator);
460}
461
462ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumeratorOfArbitraryPrecision(ZigLLVMDIBuilder *dibuilder,
463 const char *name, unsigned NumWords, const uint64_t Words[], unsigned int bits, bool isUnsigned)
464{
465 DIEnumerator *di_enumerator = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerator(name,
466 APSInt(APInt(bits, ArrayRef(Words, NumWords)), isUnsigned));
467 return reinterpret_cast<ZigLLVMDIEnumerator*>(di_enumerator);
468}
469
470ZigLLVMDIType *ZigLLVMCreateDebugEnumerationType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
471 const char *name, ZigLLVMDIFile *file, unsigned line_number, uint64_t size_in_bits,
472 uint64_t align_in_bits, ZigLLVMDIEnumerator **enumerator_array, int enumerator_array_len,
473 ZigLLVMDIType *underlying_type, const char *unique_id)
474{
475 SmallVector<Metadata *, 8> fields;
476 for (int i = 0; i < enumerator_array_len; i += 1) {
477 DIEnumerator *dienumerator = reinterpret_cast<DIEnumerator*>(enumerator_array[i]);
478 fields.push_back(dienumerator);
479 }
480 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerationType(
481 reinterpret_cast<DIScope*>(scope),
482 name,
483 reinterpret_cast<DIFile*>(file),
484 line_number, size_in_bits, align_in_bits,
485 reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),
486 reinterpret_cast<DIType*>(underlying_type),
487 unique_id);
488 return reinterpret_cast<ZigLLVMDIType*>(di_type);
489}
490
491ZigLLVMDIType *ZigLLVMCreateDebugMemberType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
492 const char *name, ZigLLVMDIFile *file, unsigned line, uint64_t size_in_bits,
493 uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags, ZigLLVMDIType *type)
494{
495 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createMemberType(
496 reinterpret_cast<DIScope*>(scope),
497 name,
498 reinterpret_cast<DIFile*>(file),
499 line, size_in_bits, align_in_bits, offset_in_bits,
500 static_cast<DINode::DIFlags>(flags),
501 reinterpret_cast<DIType*>(type));
502 return reinterpret_cast<ZigLLVMDIType*>(di_type);
503}
504
505ZigLLVMDIType *ZigLLVMCreateDebugUnionType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
506 const char *name, ZigLLVMDIFile *file, unsigned line_number, uint64_t size_in_bits,
507 uint64_t align_in_bits, unsigned flags, ZigLLVMDIType **types_array, int types_array_len,
508 unsigned run_time_lang, const char *unique_id)
509{
510 SmallVector<Metadata *, 8> fields;
511 for (int i = 0; i < types_array_len; i += 1) {
512 DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
513 fields.push_back(ditype);
514 }
515 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createUnionType(
516 reinterpret_cast<DIScope*>(scope),
517 name,
518 reinterpret_cast<DIFile*>(file),
519 line_number, size_in_bits, align_in_bits,
520 static_cast<DINode::DIFlags>(flags),
521 reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),
522 run_time_lang, unique_id);
523 return reinterpret_cast<ZigLLVMDIType*>(di_type);
524}
525
526ZigLLVMDIType *ZigLLVMCreateDebugStructType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
527 const char *name, ZigLLVMDIFile *file, unsigned line_number, uint64_t size_in_bits,
528 uint64_t align_in_bits, unsigned flags, ZigLLVMDIType *derived_from,
529 ZigLLVMDIType **types_array, int types_array_len, unsigned run_time_lang, ZigLLVMDIType *vtable_holder,
530 const char *unique_id)
531{
532 SmallVector<Metadata *, 8> fields;
533 for (int i = 0; i < types_array_len; i += 1) {
534 DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
535 fields.push_back(ditype);
536 }
537 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createStructType(
538 reinterpret_cast<DIScope*>(scope),
539 name,
540 reinterpret_cast<DIFile*>(file),
541 line_number, size_in_bits, align_in_bits,
542 static_cast<DINode::DIFlags>(flags),
543 reinterpret_cast<DIType*>(derived_from),
544 reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),
545 run_time_lang,
546 reinterpret_cast<DIType*>(vtable_holder),
547 unique_id);
548 return reinterpret_cast<ZigLLVMDIType*>(di_type);
549}
550
551ZigLLVMDIType *ZigLLVMCreateReplaceableCompositeType(ZigLLVMDIBuilder *dibuilder, unsigned tag,
552 const char *name, ZigLLVMDIScope *scope, ZigLLVMDIFile *file, unsigned line)
553{
554 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createReplaceableCompositeType(
555 tag, name,
556 reinterpret_cast<DIScope*>(scope),
557 reinterpret_cast<DIFile*>(file),
558 line);
559 return reinterpret_cast<ZigLLVMDIType*>(di_type);
560}
561
562ZigLLVMDIType *ZigLLVMCreateDebugForwardDeclType(ZigLLVMDIBuilder *dibuilder, unsigned tag,
563 const char *name, ZigLLVMDIScope *scope, ZigLLVMDIFile *file, unsigned line)
564{
565 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createForwardDecl(
566 tag, name,
567 reinterpret_cast<DIScope*>(scope),
568 reinterpret_cast<DIFile*>(file),
569 line);
570 return reinterpret_cast<ZigLLVMDIType*>(di_type);
571}
572
573void ZigLLVMReplaceTemporary(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIType *type,
574 ZigLLVMDIType *replacement)
575{
576 reinterpret_cast<DIBuilder*>(dibuilder)->replaceTemporary(
577 TempDIType(reinterpret_cast<DIType*>(type)),
578 reinterpret_cast<DIType*>(replacement));
579}
580
581void ZigLLVMReplaceDebugArrays(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIType *type,
582 ZigLLVMDIType **types_array, int types_array_len)
583{
584 SmallVector<Metadata *, 8> fields;
585 for (int i = 0; i < types_array_len; i += 1) {
586 DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
587 fields.push_back(ditype);
588 }
589 DICompositeType *composite_type = (DICompositeType*)reinterpret_cast<DIType*>(type);
590 reinterpret_cast<DIBuilder*>(dibuilder)->replaceArrays(
591 composite_type,
592 reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields));
593}
594
595ZigLLVMDIType *ZigLLVMCreateSubroutineType(ZigLLVMDIBuilder *dibuilder_wrapped,
596 ZigLLVMDIType **types_array, int types_array_len, unsigned flags)
597{
598 SmallVector<Metadata *, 8> types;
599 for (int i = 0; i < types_array_len; i += 1) {
600 DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
601 types.push_back(ditype);
602 }
603 DIBuilder *dibuilder = reinterpret_cast<DIBuilder*>(dibuilder_wrapped);
604 DISubroutineType *subroutine_type = dibuilder->createSubroutineType(
605 dibuilder->getOrCreateTypeArray(types),
606 static_cast<DINode::DIFlags>(flags));
607 DIType *ditype = subroutine_type;
608 return reinterpret_cast<ZigLLVMDIType*>(ditype);
609}
610
611unsigned ZigLLVMEncoding_DW_ATE_unsigned(void) {
612 return dwarf::DW_ATE_unsigned;
613}
614
615unsigned ZigLLVMEncoding_DW_ATE_signed(void) {
616 return dwarf::DW_ATE_signed;
617}
618
619unsigned ZigLLVMEncoding_DW_ATE_float(void) {
620 return dwarf::DW_ATE_float;
621}
622
623unsigned ZigLLVMEncoding_DW_ATE_boolean(void) {
624 return dwarf::DW_ATE_boolean;
625}
626
627unsigned ZigLLVMEncoding_DW_ATE_unsigned_char(void) {
628 return dwarf::DW_ATE_unsigned_char;
629}
630
631unsigned ZigLLVMEncoding_DW_ATE_signed_char(void) {
632 return dwarf::DW_ATE_signed_char;
633}
634
635unsigned ZigLLVMLang_DW_LANG_C99(void) {
636 return dwarf::DW_LANG_C99;
637}
638
639unsigned ZigLLVMTag_DW_variable(void) {
640 return dwarf::DW_TAG_variable;
641}
642
643unsigned ZigLLVMTag_DW_structure_type(void) {
644 return dwarf::DW_TAG_structure_type;
645}
646
647unsigned ZigLLVMTag_DW_enumeration_type(void) {
648 return dwarf::DW_TAG_enumeration_type;
649}
650
651unsigned ZigLLVMTag_DW_union_type(void) {
652 return dwarf::DW_TAG_union_type;
653}
654
655ZigLLVMDIBuilder *ZigLLVMCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved) {
656 DIBuilder *di_builder = new(std::nothrow) DIBuilder(*unwrap(module), allow_unresolved);
657 if (di_builder == nullptr)
658 return nullptr;
659 return reinterpret_cast<ZigLLVMDIBuilder *>(di_builder);
660}
661
662void ZigLLVMDisposeDIBuilder(ZigLLVMDIBuilder *dbuilder) {
663 DIBuilder *di_builder = reinterpret_cast<DIBuilder *>(dbuilder);
664 delete di_builder;
665}
666
667void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder,
668 unsigned int line, unsigned int column, ZigLLVMDIScope *scope)
669{
670 DIScope* di_scope = reinterpret_cast<DIScope*>(scope);
671 DebugLoc debug_loc = DILocation::get(di_scope->getContext(), line, column, di_scope, nullptr, false);
672 unwrap(builder)->SetCurrentDebugLocation(debug_loc);
673}
674
675void ZigLLVMSetCurrentDebugLocation2(LLVMBuilderRef builder, unsigned int line,
676 unsigned int column, ZigLLVMDIScope *scope, ZigLLVMDILocation *inlined_at)
677{
678 DIScope* di_scope = reinterpret_cast<DIScope*>(scope);
679 DebugLoc debug_loc = DILocation::get(di_scope->getContext(), line, column, di_scope,
680 reinterpret_cast<DILocation *>(inlined_at), false);
681 unwrap(builder)->SetCurrentDebugLocation(debug_loc);
682}
683
684void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder) {
685 unwrap(builder)->SetCurrentDebugLocation(DebugLoc());
686}
687
688
689ZigLLVMDILexicalBlock *ZigLLVMCreateLexicalBlock(ZigLLVMDIBuilder *dbuilder, ZigLLVMDIScope *scope,
690 ZigLLVMDIFile *file, unsigned line, unsigned col)
691{
692 DILexicalBlock *result = reinterpret_cast<DIBuilder*>(dbuilder)->createLexicalBlock(
693 reinterpret_cast<DIScope*>(scope),
694 reinterpret_cast<DIFile*>(file),
695 line,
696 col);
697 return reinterpret_cast<ZigLLVMDILexicalBlock*>(result);
698}
699
700ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(ZigLLVMDIBuilder *dbuilder,
701 ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no,
702 ZigLLVMDIType *type, bool always_preserve, unsigned flags)
703{
704 DILocalVariable *result = reinterpret_cast<DIBuilder*>(dbuilder)->createAutoVariable(
705 reinterpret_cast<DIScope*>(scope),
706 name,
707 reinterpret_cast<DIFile*>(file),
708 line_no,
709 reinterpret_cast<DIType*>(type),
710 always_preserve,
711 static_cast<DINode::DIFlags>(flags));
712 return reinterpret_cast<ZigLLVMDILocalVariable*>(result);
713}
714
715ZigLLVMDIGlobalVariableExpression *ZigLLVMCreateGlobalVariableExpression(ZigLLVMDIBuilder *dbuilder,
716 ZigLLVMDIScope *scope, const char *name, const char *linkage_name, ZigLLVMDIFile *file,
717 unsigned line_no, ZigLLVMDIType *di_type, bool is_local_to_unit)
718{
719 return reinterpret_cast<ZigLLVMDIGlobalVariableExpression*>(reinterpret_cast<DIBuilder*>(dbuilder)->createGlobalVariableExpression(
720 reinterpret_cast<DIScope*>(scope),
721 name,
722 linkage_name,
723 reinterpret_cast<DIFile*>(file),
724 line_no,
725 reinterpret_cast<DIType*>(di_type),
726 is_local_to_unit));
727}
728
729ZigLLVMDILocalVariable *ZigLLVMCreateParameterVariable(ZigLLVMDIBuilder *dbuilder,
730 ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no,
731 ZigLLVMDIType *type, bool always_preserve, unsigned flags, unsigned arg_no)
732{
733 assert(arg_no != 0);
734 DILocalVariable *result = reinterpret_cast<DIBuilder*>(dbuilder)->createParameterVariable(
735 reinterpret_cast<DIScope*>(scope),
736 name,
737 arg_no,
738 reinterpret_cast<DIFile*>(file),
739 line_no,
740 reinterpret_cast<DIType*>(type),
741 always_preserve,
742 static_cast<DINode::DIFlags>(flags));
743 return reinterpret_cast<ZigLLVMDILocalVariable*>(result);
744}
745
746ZigLLVMDIScope *ZigLLVMLexicalBlockToScope(ZigLLVMDILexicalBlock *lexical_block) {
747 DIScope *scope = reinterpret_cast<DILexicalBlock*>(lexical_block);
748 return reinterpret_cast<ZigLLVMDIScope*>(scope);
749}
750
751ZigLLVMDIScope *ZigLLVMCompileUnitToScope(ZigLLVMDICompileUnit *compile_unit) {
752 DIScope *scope = reinterpret_cast<DICompileUnit*>(compile_unit);
753 return reinterpret_cast<ZigLLVMDIScope*>(scope);
754}
755
756ZigLLVMDIScope *ZigLLVMFileToScope(ZigLLVMDIFile *difile) {
757 DIScope *scope = reinterpret_cast<DIFile*>(difile);
758 return reinterpret_cast<ZigLLVMDIScope*>(scope);
759}
760
761ZigLLVMDIScope *ZigLLVMSubprogramToScope(ZigLLVMDISubprogram *subprogram) {
762 DIScope *scope = reinterpret_cast<DISubprogram*>(subprogram);
763 return reinterpret_cast<ZigLLVMDIScope*>(scope);
764}
765
766ZigLLVMDIScope *ZigLLVMTypeToScope(ZigLLVMDIType *type) {
767 DIScope *scope = reinterpret_cast<DIType*>(type);
768 return reinterpret_cast<ZigLLVMDIScope*>(scope);
769}
770
771ZigLLVMDINode *ZigLLVMLexicalBlockToNode(ZigLLVMDILexicalBlock *lexical_block) {
772 DINode *node = reinterpret_cast<DILexicalBlock*>(lexical_block);
773 return reinterpret_cast<ZigLLVMDINode*>(node);
774}
775
776ZigLLVMDINode *ZigLLVMCompileUnitToNode(ZigLLVMDICompileUnit *compile_unit) {
777 DINode *node = reinterpret_cast<DICompileUnit*>(compile_unit);
778 return reinterpret_cast<ZigLLVMDINode*>(node);
779}
780
781ZigLLVMDINode *ZigLLVMFileToNode(ZigLLVMDIFile *difile) {
782 DINode *node = reinterpret_cast<DIFile*>(difile);
783 return reinterpret_cast<ZigLLVMDINode*>(node);
784}
785
786ZigLLVMDINode *ZigLLVMSubprogramToNode(ZigLLVMDISubprogram *subprogram) {
787 DINode *node = reinterpret_cast<DISubprogram*>(subprogram);
788 return reinterpret_cast<ZigLLVMDINode*>(node);
789}
790
791ZigLLVMDINode *ZigLLVMTypeToNode(ZigLLVMDIType *type) {
792 DINode *node = reinterpret_cast<DIType*>(type);
793 return reinterpret_cast<ZigLLVMDINode*>(node);
794}
795
796ZigLLVMDINode *ZigLLVMScopeToNode(ZigLLVMDIScope *scope) {
797 DINode *node = reinterpret_cast<DIScope*>(scope);
798 return reinterpret_cast<ZigLLVMDINode*>(node);
799}
800
801ZigLLVMDINode *ZigLLVMGlobalVariableToNode(ZigLLVMDIGlobalVariable *global_variable) {
802 DINode *node = reinterpret_cast<DIGlobalVariable*>(global_variable);
803 return reinterpret_cast<ZigLLVMDINode*>(node);
804}
805
806void ZigLLVMSubprogramReplaceLinkageName(ZigLLVMDISubprogram *subprogram,
807 ZigLLVMMDString *linkage_name)
808{
809 MDString *linkage_name_md = reinterpret_cast<MDString*>(linkage_name);
810 reinterpret_cast<DISubprogram*>(subprogram)->replaceLinkageName(linkage_name_md);
811}
812
813void ZigLLVMGlobalVariableReplaceLinkageName(ZigLLVMDIGlobalVariable *global_variable,
814 ZigLLVMMDString *linkage_name)
815{
816 Metadata *linkage_name_md = reinterpret_cast<MDString*>(linkage_name);
817 // NOTE: Operand index must match llvm::DIGlobalVariable
818 reinterpret_cast<DIGlobalVariable*>(global_variable)->replaceOperandWith(5, linkage_name_md);
819}
820
821ZigLLVMDICompileUnit *ZigLLVMCreateCompileUnit(ZigLLVMDIBuilder *dibuilder,
822 unsigned lang, ZigLLVMDIFile *difile, const char *producer,
823 bool is_optimized, const char *flags, unsigned runtime_version, const char *split_name,
824 uint64_t dwo_id, bool emit_debug_info)
825{
826 DICompileUnit *result = reinterpret_cast<DIBuilder*>(dibuilder)->createCompileUnit(
827 lang,
828 reinterpret_cast<DIFile*>(difile),
829 producer, is_optimized, flags, runtime_version, split_name,
830 (emit_debug_info ? DICompileUnit::DebugEmissionKind::FullDebug : DICompileUnit::DebugEmissionKind::NoDebug),
831 dwo_id);
832 return reinterpret_cast<ZigLLVMDICompileUnit*>(result);
833}
834
835
836ZigLLVMDIFile *ZigLLVMCreateFile(ZigLLVMDIBuilder *dibuilder, const char *filename, const char *directory) {
837 DIFile *result = reinterpret_cast<DIBuilder*>(dibuilder)->createFile(filename, directory);
838 return reinterpret_cast<ZigLLVMDIFile*>(result);
839}
840
841ZigLLVMDISubprogram *ZigLLVMCreateFunction(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
842 const char *name, const char *linkage_name, ZigLLVMDIFile *file, unsigned lineno,
843 ZigLLVMDIType *fn_di_type, bool is_local_to_unit, bool is_definition, unsigned scope_line,
844 unsigned flags, bool is_optimized, ZigLLVMDISubprogram *decl_subprogram)
845{
846 DISubroutineType *di_sub_type = static_cast<DISubroutineType*>(reinterpret_cast<DIType*>(fn_di_type));
847 DISubprogram *result = reinterpret_cast<DIBuilder*>(dibuilder)->createFunction(
848 reinterpret_cast<DIScope*>(scope),
849 name, linkage_name,
850 reinterpret_cast<DIFile*>(file),
851 lineno,
852 di_sub_type,
853 scope_line,
854 static_cast<DINode::DIFlags>(flags),
855 DISubprogram::toSPFlags(is_local_to_unit, is_definition, is_optimized),
856 nullptr,
857 reinterpret_cast<DISubprogram *>(decl_subprogram),
858 nullptr);
859 return reinterpret_cast<ZigLLVMDISubprogram*>(result);
860}
861
862void ZigLLVMDIBuilderFinalize(ZigLLVMDIBuilder *dibuilder) {
863 reinterpret_cast<DIBuilder*>(dibuilder)->finalize();
864}
865
866LLVMValueRef ZigLLVMInsertDeclareAtEnd(ZigLLVMDIBuilder *dibuilder, LLVMValueRef storage,
867 ZigLLVMDILocalVariable *var_info, ZigLLVMDILocation *debug_loc, LLVMBasicBlockRef basic_block_ref)
868{
869 Instruction *result = reinterpret_cast<DIBuilder*>(dibuilder)->insertDeclare(
870 unwrap(storage),
871 reinterpret_cast<DILocalVariable *>(var_info),
872 reinterpret_cast<DIBuilder*>(dibuilder)->createExpression(),
873 reinterpret_cast<DILocation*>(debug_loc),
874 static_cast<BasicBlock*>(unwrap(basic_block_ref)));
875 return wrap(result);
876}
877
878LLVMValueRef ZigLLVMInsertDbgValueIntrinsicAtEnd(ZigLLVMDIBuilder *dib, LLVMValueRef val,
879 ZigLLVMDILocalVariable *var_info, ZigLLVMDILocation *debug_loc,
880 LLVMBasicBlockRef basic_block_ref)
881{
882 Instruction *result = reinterpret_cast<DIBuilder*>(dib)->insertDbgValueIntrinsic(
883 unwrap(val),
884 reinterpret_cast<DILocalVariable *>(var_info),
885 reinterpret_cast<DIBuilder*>(dib)->createExpression(),
886 reinterpret_cast<DILocation*>(debug_loc),
887 static_cast<BasicBlock*>(unwrap(basic_block_ref)));
888 return wrap(result);
889}
890
891LLVMValueRef ZigLLVMInsertDeclare(ZigLLVMDIBuilder *dibuilder, LLVMValueRef storage,
892 ZigLLVMDILocalVariable *var_info, ZigLLVMDILocation *debug_loc, LLVMValueRef insert_before_instr)
893{
894 Instruction *result = reinterpret_cast<DIBuilder*>(dibuilder)->insertDeclare(
895 unwrap(storage),
896 reinterpret_cast<DILocalVariable *>(var_info),
897 reinterpret_cast<DIBuilder*>(dibuilder)->createExpression(),
898 reinterpret_cast<DILocation*>(debug_loc),
899 static_cast<Instruction*>(unwrap(insert_before_instr)));
900 return wrap(result);
901}
902
903ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, ZigLLVMDIScope *scope) {
904 DIScope* di_scope = reinterpret_cast<DIScope*>(scope);
905 DebugLoc debug_loc = DILocation::get(di_scope->getContext(), line, col, di_scope, nullptr, false);
906 return reinterpret_cast<ZigLLVMDILocation*>(debug_loc.get());
907}
908
909ZigLLVMDILocation *ZigLLVMGetDebugLoc2(unsigned line, unsigned col, ZigLLVMDIScope *scope,
910 ZigLLVMDILocation *inlined_at) {
911 DIScope* di_scope = reinterpret_cast<DIScope*>(scope);
912 DebugLoc debug_loc = DILocation::get(di_scope->getContext(), line, col, di_scope,
913 reinterpret_cast<DILocation *>(inlined_at), false);
914 return reinterpret_cast<ZigLLVMDILocation*>(debug_loc.get());
915}
916
917void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state) {
918 if (on_state) {
919 FastMathFlags fmf;
920 fmf.setFast();
921 unwrap(builder_wrapped)->setFastMathFlags(fmf);
922 } else {
923 unwrap(builder_wrapped)->clearFastMathFlags();
924 }
925}
926
927383void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv) {
928384 cl::ParseCommandLineOptions(argc, argv);
929385}
930386
931void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module, bool produce_dwarf64) {
932 unwrap(module)->addModuleFlag(Module::Warning, "Debug Info Version", DEBUG_METADATA_VERSION);
933 unwrap(module)->addModuleFlag(Module::Warning, "Dwarf Version", 4);
934
935 if (produce_dwarf64) {
936 unwrap(module)->addModuleFlag(Module::Warning, "DWARF64", 1);
937 }
938}
939
940void ZigLLVMAddModuleCodeViewFlag(LLVMModuleRef module) {
941 unwrap(module)->addModuleFlag(Module::Warning, "Debug Info Version", DEBUG_METADATA_VERSION);
942 unwrap(module)->addModuleFlag(Module::Warning, "CodeView", 1);
943}
944
945387void ZigLLVMSetModulePICLevel(LLVMModuleRef module) {
946388 unwrap(module)->setPICLevel(PICLevel::Level::BigPIC);
947389}
......@@ -956,35 +398,6 @@ void ZigLLVMSetModuleCodeModel(LLVMModuleRef module, LLVMCodeModel code_model) {
956398 assert(!JIT);
957399}
958400
959LLVMValueRef ZigLLVMBuildNSWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
960 const char *name)
961{
962 return wrap(unwrap(builder)->CreateShl(unwrap(LHS), unwrap(RHS), name, false, true));
963}
964
965LLVMValueRef ZigLLVMBuildNUWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
966 const char *name)
967{
968 return wrap(unwrap(builder)->CreateShl(unwrap(LHS), unwrap(RHS), name, true, false));
969}
970
971LLVMValueRef ZigLLVMBuildLShrExact(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
972 const char *name)
973{
974 return wrap(unwrap(builder)->CreateLShr(unwrap(LHS), unwrap(RHS), name, true));
975}
976
977LLVMValueRef ZigLLVMBuildAShrExact(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
978 const char *name)
979{
980 return wrap(unwrap(builder)->CreateAShr(unwrap(LHS), unwrap(RHS), name, true));
981}
982
983LLVMValueRef ZigLLVMBuildAllocaInAddressSpace(LLVMBuilderRef builder, LLVMTypeRef Ty,
984 unsigned AddressSpace, const char *Name) {
985 return wrap(unwrap(builder)->CreateAlloca(unwrap(Ty), AddressSpace, nullptr, Name));
986}
987
988401bool ZigLLVMWriteImportLibrary(const char *def_path, const ZigLLVM_ArchType arch,
989402 const char *output_lib_path, bool kill_at)
990403{
......@@ -1134,43 +547,6 @@ bool ZigLLDLinkWasm(int argc, const char **argv, bool can_exit_early, bool disab
1134547 return lld::wasm::link(args, llvm::outs(), llvm::errs(), can_exit_early, disable_output);
1135548}
1136549
1137void ZigLLVMTakeName(LLVMValueRef new_owner, LLVMValueRef victim) {
1138 unwrap(new_owner)->takeName(unwrap(victim));
1139}
1140
1141void ZigLLVMRemoveGlobalValue(LLVMValueRef GlobalVal) {
1142 unwrap<GlobalValue>(GlobalVal)->removeFromParent();
1143}
1144
1145void ZigLLVMEraseGlobalValue(LLVMValueRef GlobalVal) {
1146 unwrap<GlobalValue>(GlobalVal)->eraseFromParent();
1147}
1148
1149void ZigLLVMDeleteGlobalValue(LLVMValueRef GlobalVal) {
1150 auto *GV = unwrap<GlobalValue>(GlobalVal);
1151 assert(GV->getParent() == nullptr);
1152 switch (GV->getValueID()) {
1153#define HANDLE_GLOBAL_VALUE(NAME) \
1154 case Value::NAME##Val: \
1155 delete static_cast<NAME *>(GV); \
1156 break;
1157#include <llvm/IR/Value.def>
1158 default: llvm_unreachable("Expected global value");
1159 }
1160}
1161
1162void ZigLLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal) {
1163 unwrap<GlobalVariable>(GlobalVar)->setInitializer(ConstantVal ? unwrap<Constant>(ConstantVal) : nullptr);
1164}
1165
1166ZigLLVMDIGlobalVariable* ZigLLVMGlobalGetVariable(ZigLLVMDIGlobalVariableExpression *global_variable_expression) {
1167 return reinterpret_cast<ZigLLVMDIGlobalVariable*>(reinterpret_cast<DIGlobalVariableExpression*>(global_variable_expression)->getVariable());
1168}
1169
1170void ZigLLVMAttachMetaData(LLVMValueRef Val, ZigLLVMDIGlobalVariableExpression *global_variable_expression) {
1171 unwrap<GlobalVariable>(Val)->addDebugInfo(reinterpret_cast<DIGlobalVariableExpression*>(global_variable_expression));
1172}
1173
1174550static_assert((Triple::ArchType)ZigLLVM_UnknownArch == Triple::UnknownArch, "");
1175551static_assert((Triple::ArchType)ZigLLVM_arm == Triple::arm, "");
1176552static_assert((Triple::ArchType)ZigLLVM_armeb == Triple::armeb, "");
src/zig_llvm.h-193
......@@ -24,24 +24,6 @@
2424// ATTENTION: If you modify this file, be sure to update the corresponding
2525// extern function declarations in the self-hosted compiler.
2626
27struct ZigLLVMDIType;
28struct ZigLLVMDIBuilder;
29struct ZigLLVMDICompileUnit;
30struct ZigLLVMDIScope;
31struct ZigLLVMDIFile;
32struct ZigLLVMDILexicalBlock;
33struct ZigLLVMDISubprogram;
34struct ZigLLVMDISubroutineType;
35struct ZigLLVMDILocalVariable;
36struct ZigLLVMDIGlobalVariableExpression;
37struct ZigLLVMDIGlobalVariable;
38struct ZigLLVMDIGlobalExpression;
39struct ZigLLVMDILocation;
40struct ZigLLVMDIEnumerator;
41struct ZigLLVMInsertionPoint;
42struct ZigLLVMDINode;
43struct ZigLLVMMDString;
44
4527ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
4628 char **error_message, bool is_debug,
4729 bool is_small, bool time_report, bool tsan, bool lto,
......@@ -62,9 +44,6 @@ ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, co
6244
6345ZIG_EXTERN_C void ZigLLVMSetOptBisectLimit(LLVMContextRef context_ref, int limit);
6446
65ZIG_EXTERN_C LLVMValueRef ZigLLVMAddFunctionInAddressSpace(LLVMModuleRef M, const char *Name,
66 LLVMTypeRef FunctionTy, unsigned AddressSpace);
67
6847enum ZigLLVMTailCallKind {
6948 ZigLLVMTailCallKindNone,
7049 ZigLLVMTailCallKindTail,
......@@ -72,8 +51,6 @@ enum ZigLLVMTailCallKind {
7251 ZigLLVMTailCallKindNoTail,
7352};
7453
75ZIG_EXTERN_C void ZigLLVMSetTailCallKind(LLVMValueRef Call, enum ZigLLVMTailCallKind TailCallKind);
76
7754enum ZigLLVM_CallingConv {
7855 ZigLLVM_C = 0,
7956 ZigLLVM_Fast = 8,
......@@ -122,176 +99,12 @@ enum ZigLLVM_CallingConv {
12299 ZigLLVM_MaxID = 1023,
123100};
124101
125ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildNSWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
126 const char *name);
127ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildNUWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
128 const char *name);
129ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildLShrExact(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
130 const char *name);
131ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildAShrExact(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
132 const char *name);
133
134ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildAllocaInAddressSpace(LLVMBuilderRef builder, LLVMTypeRef Ty, unsigned AddressSpace,
135 const char *Name);
136
137ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugPointerType(struct ZigLLVMDIBuilder *dibuilder,
138 struct ZigLLVMDIType *pointee_type, uint64_t size_in_bits, uint64_t align_in_bits, const char *name);
139
140ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugBasicType(struct ZigLLVMDIBuilder *dibuilder, const char *name,
141 uint64_t size_in_bits, unsigned encoding);
142
143ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugArrayType(struct ZigLLVMDIBuilder *dibuilder,
144 uint64_t size_in_bits, uint64_t align_in_bits, struct ZigLLVMDIType *elem_type,
145 int64_t elem_count);
146
147ZIG_EXTERN_C struct ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(struct ZigLLVMDIBuilder *dibuilder,
148 const char *name, uint64_t val, bool isUnsigned);
149
150
151ZIG_EXTERN_C struct ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumeratorOfArbitraryPrecision(struct ZigLLVMDIBuilder *dibuilder,
152 const char *name, unsigned NumWords, const uint64_t Words[], unsigned int bits, bool isUnsigned);
153
154ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugEnumerationType(struct ZigLLVMDIBuilder *dibuilder,
155 struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line_number,
156 uint64_t size_in_bits, uint64_t align_in_bits, struct ZigLLVMDIEnumerator **enumerator_array,
157 int enumerator_array_len, struct ZigLLVMDIType *underlying_type, const char *unique_id);
158
159ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugStructType(struct ZigLLVMDIBuilder *dibuilder,
160 struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line_number,
161 uint64_t size_in_bits, uint64_t align_in_bits, unsigned flags, struct ZigLLVMDIType *derived_from,
162 struct ZigLLVMDIType **types_array, int types_array_len, unsigned run_time_lang,
163 struct ZigLLVMDIType *vtable_holder, const char *unique_id);
164
165ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugUnionType(struct ZigLLVMDIBuilder *dibuilder,
166 struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line_number,
167 uint64_t size_in_bits, uint64_t align_in_bits, unsigned flags, struct ZigLLVMDIType **types_array,
168 int types_array_len, unsigned run_time_lang, const char *unique_id);
169
170ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugMemberType(struct ZigLLVMDIBuilder *dibuilder,
171 struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line,
172 uint64_t size_in_bits, uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags,
173 struct ZigLLVMDIType *type);
174
175ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateReplaceableCompositeType(struct ZigLLVMDIBuilder *dibuilder,
176 unsigned tag, const char *name, struct ZigLLVMDIScope *scope, struct ZigLLVMDIFile *file, unsigned line);
177
178ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugForwardDeclType(struct ZigLLVMDIBuilder *dibuilder, unsigned tag,
179 const char *name, struct ZigLLVMDIScope *scope, struct ZigLLVMDIFile *file, unsigned line);
180
181ZIG_EXTERN_C void ZigLLVMReplaceTemporary(struct ZigLLVMDIBuilder *dibuilder, struct ZigLLVMDIType *type,
182 struct ZigLLVMDIType *replacement);
183
184ZIG_EXTERN_C void ZigLLVMReplaceDebugArrays(struct ZigLLVMDIBuilder *dibuilder, struct ZigLLVMDIType *type,
185 struct ZigLLVMDIType **types_array, int types_array_len);
186
187ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateSubroutineType(struct ZigLLVMDIBuilder *dibuilder_wrapped,
188 struct ZigLLVMDIType **types_array, int types_array_len, unsigned flags);
189
190ZIG_EXTERN_C unsigned ZigLLVMEncoding_DW_ATE_unsigned(void);
191ZIG_EXTERN_C unsigned ZigLLVMEncoding_DW_ATE_signed(void);
192ZIG_EXTERN_C unsigned ZigLLVMEncoding_DW_ATE_float(void);
193ZIG_EXTERN_C unsigned ZigLLVMEncoding_DW_ATE_boolean(void);
194ZIG_EXTERN_C unsigned ZigLLVMEncoding_DW_ATE_unsigned_char(void);
195ZIG_EXTERN_C unsigned ZigLLVMEncoding_DW_ATE_signed_char(void);
196ZIG_EXTERN_C unsigned ZigLLVMLang_DW_LANG_C99(void);
197ZIG_EXTERN_C unsigned ZigLLVMTag_DW_variable(void);
198ZIG_EXTERN_C unsigned ZigLLVMTag_DW_structure_type(void);
199ZIG_EXTERN_C unsigned ZigLLVMTag_DW_enumeration_type(void);
200ZIG_EXTERN_C unsigned ZigLLVMTag_DW_union_type(void);
201
202ZIG_EXTERN_C struct ZigLLVMDIBuilder *ZigLLVMCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved);
203ZIG_EXTERN_C void ZigLLVMDisposeDIBuilder(struct ZigLLVMDIBuilder *dbuilder);
204ZIG_EXTERN_C void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module, bool produce_dwarf64);
205ZIG_EXTERN_C void ZigLLVMAddModuleCodeViewFlag(LLVMModuleRef module);
206102ZIG_EXTERN_C void ZigLLVMSetModulePICLevel(LLVMModuleRef module);
207103ZIG_EXTERN_C void ZigLLVMSetModulePIELevel(LLVMModuleRef module);
208104ZIG_EXTERN_C void ZigLLVMSetModuleCodeModel(LLVMModuleRef module, LLVMCodeModel code_model);
209105
210ZIG_EXTERN_C void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder,
211 unsigned int line, unsigned int column, struct ZigLLVMDIScope *scope);
212ZIG_EXTERN_C void ZigLLVMSetCurrentDebugLocation2(LLVMBuilderRef builder, unsigned int line,
213 unsigned int column, struct ZigLLVMDIScope *scope, struct ZigLLVMDILocation *inlined_at);
214ZIG_EXTERN_C void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder);
215
216ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMLexicalBlockToScope(struct ZigLLVMDILexicalBlock *lexical_block);
217ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMCompileUnitToScope(struct ZigLLVMDICompileUnit *compile_unit);
218ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMFileToScope(struct ZigLLVMDIFile *difile);
219ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMSubprogramToScope(struct ZigLLVMDISubprogram *subprogram);
220ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMTypeToScope(struct ZigLLVMDIType *type);
221
222ZIG_EXTERN_C struct ZigLLVMDINode *ZigLLVMLexicalBlockToNode(struct ZigLLVMDILexicalBlock *lexical_block);
223ZIG_EXTERN_C struct ZigLLVMDINode *ZigLLVMCompileUnitToNode(struct ZigLLVMDICompileUnit *compile_unit);
224ZIG_EXTERN_C struct ZigLLVMDINode *ZigLLVMFileToNode(struct ZigLLVMDIFile *difile);
225ZIG_EXTERN_C struct ZigLLVMDINode *ZigLLVMSubprogramToNode(struct ZigLLVMDISubprogram *subprogram);
226ZIG_EXTERN_C struct ZigLLVMDINode *ZigLLVMTypeToNode(struct ZigLLVMDIType *type);
227ZIG_EXTERN_C struct ZigLLVMDINode *ZigLLVMScopeToNode(struct ZigLLVMDIScope *scope);
228ZIG_EXTERN_C struct ZigLLVMDINode *ZigLLVMGlobalVariableToNode(struct ZigLLVMDIGlobalVariable *global_variable);
229
230ZIG_EXTERN_C void ZigLLVMSubprogramReplaceLinkageName(struct ZigLLVMDISubprogram *subprogram,
231 struct ZigLLVMMDString *linkage_name);
232ZIG_EXTERN_C void ZigLLVMGlobalVariableReplaceLinkageName(struct ZigLLVMDIGlobalVariable *global_variable,
233 struct ZigLLVMMDString *linkage_name);
234
235ZIG_EXTERN_C struct ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(struct ZigLLVMDIBuilder *dbuilder,
236 struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line_no,
237 struct ZigLLVMDIType *type, bool always_preserve, unsigned flags);
238
239ZIG_EXTERN_C struct ZigLLVMDIGlobalVariableExpression *ZigLLVMCreateGlobalVariableExpression(struct ZigLLVMDIBuilder *dbuilder,
240 struct ZigLLVMDIScope *scope, const char *name, const char *linkage_name, struct ZigLLVMDIFile *file,
241 unsigned line_no, struct ZigLLVMDIType *di_type, bool is_local_to_unit);
242
243ZIG_EXTERN_C struct ZigLLVMDILocalVariable *ZigLLVMCreateParameterVariable(struct ZigLLVMDIBuilder *dbuilder,
244 struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line_no,
245 struct ZigLLVMDIType *type, bool always_preserve, unsigned flags, unsigned arg_no);
246
247ZIG_EXTERN_C struct ZigLLVMDILexicalBlock *ZigLLVMCreateLexicalBlock(struct ZigLLVMDIBuilder *dbuilder,
248 struct ZigLLVMDIScope *scope, struct ZigLLVMDIFile *file, unsigned line, unsigned col);
249
250ZIG_EXTERN_C struct ZigLLVMDICompileUnit *ZigLLVMCreateCompileUnit(struct ZigLLVMDIBuilder *dibuilder,
251 unsigned lang, struct ZigLLVMDIFile *difile, const char *producer,
252 bool is_optimized, const char *flags, unsigned runtime_version, const char *split_name,
253 uint64_t dwo_id, bool emit_debug_info);
254
255ZIG_EXTERN_C struct ZigLLVMDIFile *ZigLLVMCreateFile(struct ZigLLVMDIBuilder *dibuilder, const char *filename,
256 const char *directory);
257
258ZIG_EXTERN_C struct ZigLLVMDISubprogram *ZigLLVMCreateFunction(struct ZigLLVMDIBuilder *dibuilder,
259 struct ZigLLVMDIScope *scope, const char *name, const char *linkage_name, struct ZigLLVMDIFile *file,
260 unsigned lineno, struct ZigLLVMDIType *fn_di_type, bool is_local_to_unit, bool is_definition,
261 unsigned scope_line, unsigned flags, bool is_optimized, struct ZigLLVMDISubprogram *decl_subprogram);
262
263ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMDIBuilderCreateVectorType(struct ZigLLVMDIBuilder *dibuilder,
264 uint64_t SizeInBits, uint32_t AlignInBits, struct ZigLLVMDIType *Ty, uint32_t elem_count);
265
266ZIG_EXTERN_C void ZigLLVMFnSetSubprogram(LLVMValueRef fn, struct ZigLLVMDISubprogram *subprogram);
267
268ZIG_EXTERN_C void ZigLLVMDIBuilderFinalize(struct ZigLLVMDIBuilder *dibuilder);
269
270ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col,
271 struct ZigLLVMDIScope *scope);
272ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc2(unsigned line, unsigned col,
273 struct ZigLLVMDIScope *scope, struct ZigLLVMDILocation *inlined_at);
274
275ZIG_EXTERN_C LLVMValueRef ZigLLVMInsertDeclareAtEnd(struct ZigLLVMDIBuilder *dib,
276 LLVMValueRef storage, struct ZigLLVMDILocalVariable *var_info,
277 struct ZigLLVMDILocation *debug_loc, LLVMBasicBlockRef basic_block_ref);
278
279ZIG_EXTERN_C LLVMValueRef ZigLLVMInsertDeclare(struct ZigLLVMDIBuilder *dib,
280 LLVMValueRef storage, struct ZigLLVMDILocalVariable *var_info,
281 struct ZigLLVMDILocation *debug_loc, LLVMValueRef insert_before_instr);
282
283ZIG_EXTERN_C LLVMValueRef ZigLLVMInsertDbgValueIntrinsicAtEnd(struct ZigLLVMDIBuilder *dib,
284 LLVMValueRef val, struct ZigLLVMDILocalVariable *var_info,
285 struct ZigLLVMDILocation *debug_loc, LLVMBasicBlockRef basic_block_ref);
286
287ZIG_EXTERN_C void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state);
288
289106ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv);
290107
291ZIG_EXTERN_C ZigLLVMDIGlobalVariable* ZigLLVMGlobalGetVariable(ZigLLVMDIGlobalVariableExpression *global_variable_expression);
292ZIG_EXTERN_C void ZigLLVMAttachMetaData(LLVMValueRef Val, ZigLLVMDIGlobalVariableExpression *global_variable_expression);
293
294
295108// synchronize with llvm/include/ADT/Triple.h::ArchType
296109// synchronize with std.Target.Cpu.Arch
297110// synchronize with codegen/llvm/bindings.zig::ArchType
......@@ -494,12 +307,6 @@ enum ZigLLVM_ObjectFormatType {
494307 ZigLLVM_XCOFF,
495308};
496309
497ZIG_EXTERN_C void ZigLLVMTakeName(LLVMValueRef new_owner, LLVMValueRef victim);
498ZIG_EXTERN_C void ZigLLVMRemoveGlobalValue(LLVMValueRef GlobalVal);
499ZIG_EXTERN_C void ZigLLVMEraseGlobalValue(LLVMValueRef GlobalVal);
500ZIG_EXTERN_C void ZigLLVMDeleteGlobalValue(LLVMValueRef GlobalVal);
501ZIG_EXTERN_C void ZigLLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal);
502
503310#define ZigLLVM_DIFlags_Zero 0U
504311#define ZigLLVM_DIFlags_Private 1U
505312#define ZigLLVM_DIFlags_Protected 2U