authorgravatar for liljaanton2001@gmail.comantlilja <liljaanton2001@gmail.com> 2024-02-21 17:53:15+01:00
committergravatar for liljaanton2001@gmail.comantlilja <liljaanton2001@gmail.com> 2024-02-21 17:53:15+01:00
logf6d275b14e7097708c8f719fc2378a9ce79731fc
treef34ec5a74543e7e3e554eddd85d823def4d18e26
parent626c3f795990ea32878bcd3f93467d00478c2d69

LLVM: Remove use of LLVM in Builder


3 files changed, 264 insertions(+), 1623 deletions(-)

src/codegen/llvm.zig+248-43
...@@ -840,7 +840,6 @@ pub const Object = struct {...@@ -840,7 +840,6 @@ pub const Object = struct {
840840
841 var builder = try Builder.init(.{841 var builder = try Builder.init(.{
842 .allocator = gpa,842 .allocator = gpa,
843 .use_lib_llvm = false,
844 .strip = strip,843 .strip = strip,
845 .name = comp.root_name,844 .name = comp.root_name,
846 .target = target,845 .target = target,
...@@ -900,16 +899,48 @@ pub const Object = struct {...@@ -900,16 +899,48 @@ pub const Object = struct {
900 try builder.string("Debug Info Version"),899 try builder.string("Debug Info Version"),
901 try builder.debugConstant(try builder.intConst(.i32, 3)),900 try builder.debugConstant(try builder.intConst(.i32, 3)),
902 );901 );
903 const dwarf_version = try builder.debugModuleFlag(
904 try builder.debugConstant(try builder.intConst(.i32, 2)),
905 try builder.string("Dwarf Version"),
906 try builder.debugConstant(try builder.intConst(.i32, 4)),
907 );
908902
909 try builder.debugNamed(try builder.string("llvm.module.flags"), &.{903 switch (comp.config.debug_format) {
910 debug_info_version,904 .dwarf => |f| {
911 dwarf_version,905 const dwarf_version = try builder.debugModuleFlag(
912 });906 try builder.debugConstant(try builder.intConst(.i32, 2)),
907 try builder.string("Dwarf Version"),
908 try builder.debugConstant(try builder.intConst(.i32, 4)),
909 );
910 switch (f) {
911 .@"32" => {
912 try builder.debugNamed(try builder.string("llvm.module.flags"), &.{
913 debug_info_version,
914 dwarf_version,
915 });
916 },
917 .@"64" => {
918 const dwarf64 = try builder.debugModuleFlag(
919 try builder.debugConstant(try builder.intConst(.i32, 2)),
920 try builder.string("DWARF64"),
921 try builder.debugConstant(try builder.intConst(.i32, 1)),
922 );
923 try builder.debugNamed(try builder.string("llvm.module.flags"), &.{
924 debug_info_version,
925 dwarf_version,
926 dwarf64,
927 });
928 },
929 }
930 },
931 .code_view => {
932 const code_view = try builder.debugModuleFlag(
933 try builder.debugConstant(try builder.intConst(.i32, 2)),
934 try builder.string("CodeView"),
935 try builder.debugConstant(try builder.intConst(.i32, 1)),
936 );
937 try builder.debugNamed(try builder.string("llvm.module.flags"), &.{
938 debug_info_version,
939 code_view,
940 });
941 },
942 .strip => unreachable,
943 }
913944
914 try builder.debugNamed(try builder.string("llvm.dbg.cu"), &.{debug_compile_unit});945 try builder.debugNamed(try builder.string("llvm.dbg.cu"), &.{debug_compile_unit});
915 }946 }
...@@ -1145,10 +1176,21 @@ pub const Object = struct {...@@ -1145,10 +1176,21 @@ pub const Object = struct {
1145 }1176 }
1146 }1177 }
11471178
1148 if (options.pre_bc_path) |path| _ = try self.builder.writeBitcodeToFile(path);1179 var bitcode_arena_allocator = std.heap.ArenaAllocator.init(
1180 std.heap.page_allocator,
1181 );
1182 errdefer bitcode_arena_allocator.deinit();
11491183
1150 if (std.debug.runtime_safety and !try self.builder.verify()) {1184 const bitcode = try self.builder.toBitcode(
1151 @panic("LLVM module verification failed");1185 bitcode_arena_allocator.allocator(),
1186 );
1187
1188 if (options.pre_bc_path) |path| {
1189 var file = try std.fs.cwd().createFile(path, .{});
1190 defer file.close();
1191
1192 const ptr: [*]const u8 = @ptrCast(bitcode.ptr);
1193 try file.writeAll(ptr[0..(bitcode.len * 4)]);
1152 }1194 }
11531195
1154 const emit_asm_msg = options.asm_path orelse "(none)";1196 const emit_asm_msg = options.asm_path orelse "(none)";
...@@ -1162,15 +1204,6 @@ pub const Object = struct {...@@ -1162,15 +1204,6 @@ pub const Object = struct {
1162 if (options.asm_path == null and options.bin_path == null and1204 if (options.asm_path == null and options.bin_path == null and
1163 options.post_ir_path == null and options.post_bc_path == null) return;1205 options.post_ir_path == null and options.post_bc_path == null) return;
11641206
1165 var bitcode_arena_allocator = std.heap.ArenaAllocator.init(
1166 std.heap.page_allocator,
1167 );
1168 errdefer bitcode_arena_allocator.deinit();
1169
1170 const bitcode = try self.builder.toBitcode(
1171 bitcode_arena_allocator.allocator(),
1172 );
1173
1174 if (options.post_bc_path) |path| {1207 if (options.post_bc_path) |path| {
1175 var file = try std.fs.cwd().createFileZ(path, .{});1208 var file = try std.fs.cwd().createFileZ(path, .{});
1176 defer file.close();1209 defer file.close();
...@@ -1184,7 +1217,7 @@ pub const Object = struct {...@@ -1184,7 +1217,7 @@ pub const Object = struct {
1184 return error.FailedToEmit;1217 return error.FailedToEmit;
1185 }1218 }
11861219
1187 Builder.initializeLLVMTarget(self.module.comp.root_mod.resolved_target.result.cpu.arch);1220 initializeLLVMTarget(self.module.comp.root_mod.resolved_target.result.cpu.arch);
11881221
1189 const context: *llvm.Context = llvm.Context.create();1222 const context: *llvm.Context = llvm.Context.create();
1190 defer context.dispose();1223 defer context.dispose();
...@@ -3077,26 +3110,6 @@ pub const Object = struct {...@@ -3077,26 +3110,6 @@ pub const Object = struct {
3077 }3110 }
30783111
3079 fn lowerType(o: *Object, t: Type) Allocator.Error!Builder.Type {3112 fn lowerType(o: *Object, t: Type) Allocator.Error!Builder.Type {
3080 const ty = try o.lowerTypeInner(t);
3081 const mod = o.module;
3082 if (std.debug.runtime_safety and o.builder.useLibLlvm() and false) check: {
3083 const llvm_ty = ty.toLlvm(&o.builder);
3084 if (t.zigTypeTag(mod) == .Opaque) break :check;
3085 if (!t.hasRuntimeBits(mod)) break :check;
3086 if (!try ty.isSized(&o.builder)) break :check;
3087
3088 const zig_size = t.abiSize(mod);
3089 const llvm_size = o.target_data.abiSizeOfType(llvm_ty);
3090 if (llvm_size != zig_size) {
3091 log.err("when lowering {}, Zig ABI size = {d} but LLVM ABI size = {d}", .{
3092 t.fmt(o.module), zig_size, llvm_size,
3093 });
3094 }
3095 }
3096 return ty;
3097 }
3098
3099 fn lowerTypeInner(o: *Object, t: Type) Allocator.Error!Builder.Type {
3100 const mod = o.module;3113 const mod = o.module;
3101 const target = mod.getTarget();3114 const target = mod.getTarget();
3102 const ip = &mod.intern_pool;3115 const ip = &mod.intern_pool;
...@@ -11752,3 +11765,195 @@ fn constraintAllowsRegister(constraint: []const u8) bool {...@@ -11752,3 +11765,195 @@ fn constraintAllowsRegister(constraint: []const u8) bool {
11752 }11765 }
11753 } else return false;11766 } else return false;
11754}11767}
11768
11769pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
11770 switch (arch) {
11771 .aarch64, .aarch64_be, .aarch64_32 => {
11772 llvm.LLVMInitializeAArch64Target();
11773 llvm.LLVMInitializeAArch64TargetInfo();
11774 llvm.LLVMInitializeAArch64TargetMC();
11775 llvm.LLVMInitializeAArch64AsmPrinter();
11776 llvm.LLVMInitializeAArch64AsmParser();
11777 },
11778 .amdgcn => {
11779 llvm.LLVMInitializeAMDGPUTarget();
11780 llvm.LLVMInitializeAMDGPUTargetInfo();
11781 llvm.LLVMInitializeAMDGPUTargetMC();
11782 llvm.LLVMInitializeAMDGPUAsmPrinter();
11783 llvm.LLVMInitializeAMDGPUAsmParser();
11784 },
11785 .thumb, .thumbeb, .arm, .armeb => {
11786 llvm.LLVMInitializeARMTarget();
11787 llvm.LLVMInitializeARMTargetInfo();
11788 llvm.LLVMInitializeARMTargetMC();
11789 llvm.LLVMInitializeARMAsmPrinter();
11790 llvm.LLVMInitializeARMAsmParser();
11791 },
11792 .avr => {
11793 llvm.LLVMInitializeAVRTarget();
11794 llvm.LLVMInitializeAVRTargetInfo();
11795 llvm.LLVMInitializeAVRTargetMC();
11796 llvm.LLVMInitializeAVRAsmPrinter();
11797 llvm.LLVMInitializeAVRAsmParser();
11798 },
11799 .bpfel, .bpfeb => {
11800 llvm.LLVMInitializeBPFTarget();
11801 llvm.LLVMInitializeBPFTargetInfo();
11802 llvm.LLVMInitializeBPFTargetMC();
11803 llvm.LLVMInitializeBPFAsmPrinter();
11804 llvm.LLVMInitializeBPFAsmParser();
11805 },
11806 .hexagon => {
11807 llvm.LLVMInitializeHexagonTarget();
11808 llvm.LLVMInitializeHexagonTargetInfo();
11809 llvm.LLVMInitializeHexagonTargetMC();
11810 llvm.LLVMInitializeHexagonAsmPrinter();
11811 llvm.LLVMInitializeHexagonAsmParser();
11812 },
11813 .lanai => {
11814 llvm.LLVMInitializeLanaiTarget();
11815 llvm.LLVMInitializeLanaiTargetInfo();
11816 llvm.LLVMInitializeLanaiTargetMC();
11817 llvm.LLVMInitializeLanaiAsmPrinter();
11818 llvm.LLVMInitializeLanaiAsmParser();
11819 },
11820 .mips, .mipsel, .mips64, .mips64el => {
11821 llvm.LLVMInitializeMipsTarget();
11822 llvm.LLVMInitializeMipsTargetInfo();
11823 llvm.LLVMInitializeMipsTargetMC();
11824 llvm.LLVMInitializeMipsAsmPrinter();
11825 llvm.LLVMInitializeMipsAsmParser();
11826 },
11827 .msp430 => {
11828 llvm.LLVMInitializeMSP430Target();
11829 llvm.LLVMInitializeMSP430TargetInfo();
11830 llvm.LLVMInitializeMSP430TargetMC();
11831 llvm.LLVMInitializeMSP430AsmPrinter();
11832 llvm.LLVMInitializeMSP430AsmParser();
11833 },
11834 .nvptx, .nvptx64 => {
11835 llvm.LLVMInitializeNVPTXTarget();
11836 llvm.LLVMInitializeNVPTXTargetInfo();
11837 llvm.LLVMInitializeNVPTXTargetMC();
11838 llvm.LLVMInitializeNVPTXAsmPrinter();
11839 // There is no LLVMInitializeNVPTXAsmParser function available.
11840 },
11841 .powerpc, .powerpcle, .powerpc64, .powerpc64le => {
11842 llvm.LLVMInitializePowerPCTarget();
11843 llvm.LLVMInitializePowerPCTargetInfo();
11844 llvm.LLVMInitializePowerPCTargetMC();
11845 llvm.LLVMInitializePowerPCAsmPrinter();
11846 llvm.LLVMInitializePowerPCAsmParser();
11847 },
11848 .riscv32, .riscv64 => {
11849 llvm.LLVMInitializeRISCVTarget();
11850 llvm.LLVMInitializeRISCVTargetInfo();
11851 llvm.LLVMInitializeRISCVTargetMC();
11852 llvm.LLVMInitializeRISCVAsmPrinter();
11853 llvm.LLVMInitializeRISCVAsmParser();
11854 },
11855 .sparc, .sparc64, .sparcel => {
11856 llvm.LLVMInitializeSparcTarget();
11857 llvm.LLVMInitializeSparcTargetInfo();
11858 llvm.LLVMInitializeSparcTargetMC();
11859 llvm.LLVMInitializeSparcAsmPrinter();
11860 llvm.LLVMInitializeSparcAsmParser();
11861 },
11862 .s390x => {
11863 llvm.LLVMInitializeSystemZTarget();
11864 llvm.LLVMInitializeSystemZTargetInfo();
11865 llvm.LLVMInitializeSystemZTargetMC();
11866 llvm.LLVMInitializeSystemZAsmPrinter();
11867 llvm.LLVMInitializeSystemZAsmParser();
11868 },
11869 .wasm32, .wasm64 => {
11870 llvm.LLVMInitializeWebAssemblyTarget();
11871 llvm.LLVMInitializeWebAssemblyTargetInfo();
11872 llvm.LLVMInitializeWebAssemblyTargetMC();
11873 llvm.LLVMInitializeWebAssemblyAsmPrinter();
11874 llvm.LLVMInitializeWebAssemblyAsmParser();
11875 },
11876 .x86, .x86_64 => {
11877 llvm.LLVMInitializeX86Target();
11878 llvm.LLVMInitializeX86TargetInfo();
11879 llvm.LLVMInitializeX86TargetMC();
11880 llvm.LLVMInitializeX86AsmPrinter();
11881 llvm.LLVMInitializeX86AsmParser();
11882 },
11883 .xtensa => {
11884 if (build_options.llvm_has_xtensa) {
11885 llvm.LLVMInitializeXtensaTarget();
11886 llvm.LLVMInitializeXtensaTargetInfo();
11887 llvm.LLVMInitializeXtensaTargetMC();
11888 // There is no LLVMInitializeXtensaAsmPrinter function.
11889 llvm.LLVMInitializeXtensaAsmParser();
11890 }
11891 },
11892 .xcore => {
11893 llvm.LLVMInitializeXCoreTarget();
11894 llvm.LLVMInitializeXCoreTargetInfo();
11895 llvm.LLVMInitializeXCoreTargetMC();
11896 llvm.LLVMInitializeXCoreAsmPrinter();
11897 // There is no LLVMInitializeXCoreAsmParser function.
11898 },
11899 .m68k => {
11900 if (build_options.llvm_has_m68k) {
11901 llvm.LLVMInitializeM68kTarget();
11902 llvm.LLVMInitializeM68kTargetInfo();
11903 llvm.LLVMInitializeM68kTargetMC();
11904 llvm.LLVMInitializeM68kAsmPrinter();
11905 llvm.LLVMInitializeM68kAsmParser();
11906 }
11907 },
11908 .csky => {
11909 if (build_options.llvm_has_csky) {
11910 llvm.LLVMInitializeCSKYTarget();
11911 llvm.LLVMInitializeCSKYTargetInfo();
11912 llvm.LLVMInitializeCSKYTargetMC();
11913 // There is no LLVMInitializeCSKYAsmPrinter function.
11914 llvm.LLVMInitializeCSKYAsmParser();
11915 }
11916 },
11917 .ve => {
11918 llvm.LLVMInitializeVETarget();
11919 llvm.LLVMInitializeVETargetInfo();
11920 llvm.LLVMInitializeVETargetMC();
11921 llvm.LLVMInitializeVEAsmPrinter();
11922 llvm.LLVMInitializeVEAsmParser();
11923 },
11924 .arc => {
11925 if (build_options.llvm_has_arc) {
11926 llvm.LLVMInitializeARCTarget();
11927 llvm.LLVMInitializeARCTargetInfo();
11928 llvm.LLVMInitializeARCTargetMC();
11929 llvm.LLVMInitializeARCAsmPrinter();
11930 // There is no LLVMInitializeARCAsmParser function.
11931 }
11932 },
11933
11934 // LLVM backends that have no initialization functions.
11935 .tce,
11936 .tcele,
11937 .r600,
11938 .le32,
11939 .le64,
11940 .amdil,
11941 .amdil64,
11942 .hsail,
11943 .hsail64,
11944 .shave,
11945 .spir,
11946 .spir64,
11947 .kalimba,
11948 .renderscript32,
11949 .renderscript64,
11950 .dxil,
11951 .loongarch32,
11952 .loongarch64,
11953 => {},
11954
11955 .spu_2 => unreachable, // LLVM does not support this backend
11956 .spirv32 => unreachable, // LLVM does not support this backend
11957 .spirv64 => unreachable, // LLVM does not support this backend
11958 }
11959}
src/codegen/llvm/Builder.zig+15-1578
...@@ -1,21 +1,6 @@...@@ -1,21 +1,6 @@
1gpa: Allocator,1gpa: Allocator,
2use_lib_llvm: bool,
3strip: bool,2strip: 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
19source_filename: String,4source_filename: String,
20data_layout: String,5data_layout: String,
21target_triple: String,6target_triple: String,
...@@ -73,7 +58,6 @@ pub const expected_intrinsic_name_len = 64;...@@ -73,7 +58,6 @@ pub const expected_intrinsic_name_len = 64;
7358
74pub const Options = struct {59pub const Options = struct {
75 allocator: Allocator,60 allocator: Allocator,
76 use_lib_llvm: bool = false,
77 strip: bool = true,61 strip: bool = true,
78 name: []const u8 = &.{},62 name: []const u8 = &.{},
79 target: std.Target = builtin.target,63 target: std.Target = builtin.target,
...@@ -658,7 +642,6 @@ pub const Type = enum(u32) {...@@ -658,7 +642,6 @@ pub const Type = enum(u32) {
658 var visited: IsSizedVisited = .{};642 var visited: IsSizedVisited = .{};
659 defer visited.deinit(builder.gpa);643 defer visited.deinit(builder.gpa);
660 const result = try self.isSizedVisited(&visited, builder);644 const result = try self.isSizedVisited(&visited, builder);
661 if (builder.useLibLlvm()) assert(result == self.toLlvm(builder).isSized().toBool());
662 return result;645 return result;
663 }646 }
664647
...@@ -845,11 +828,6 @@ pub const Type = enum(u32) {...@@ -845,11 +828,6 @@ pub const Type = enum(u32) {
845 return .{ .data = .{ .type = self, .builder = builder } };828 return .{ .data = .{ .type = self, .builder = builder } };
846 }829 }
847830
848 pub fn toLlvm(self: Type, builder: *const Builder) *llvm.Type {
849 assert(builder.useLibLlvm());
850 return builder.llvm.types.items[@intFromEnum(self)];
851 }
852
853 const IsSizedVisited = std.AutoHashMapUnmanaged(Type, void);831 const IsSizedVisited = std.AutoHashMapUnmanaged(Type, void);
854 fn isSizedVisited(832 fn isSizedVisited(
855 self: Type,833 self: Type,
...@@ -1331,11 +1309,6 @@ pub const Attribute = union(Kind) {...@@ -1331,11 +1309,6 @@ pub const Attribute = union(Kind) {
1331 fn toStorage(self: Index, builder: *const Builder) Storage {1309 fn toStorage(self: Index, builder: *const Builder) Storage {
1332 return builder.attributes.keys()[@intFromEnum(self)];1310 return builder.attributes.keys()[@intFromEnum(self)];
1333 }1311 }
1334
1335 fn toLlvm(self: Index, builder: *const Builder) *llvm.Attribute {
1336 assert(builder.useLibLlvm());
1337 return builder.llvm.attributes.items[@intFromEnum(self)];
1338 }
1339 };1312 };
13401313
1341 pub const Kind = enum(u32) {1314 pub const Kind = enum(u32) {
...@@ -1453,11 +1426,6 @@ pub const Attribute = union(Kind) {...@@ -1453,11 +1426,6 @@ pub const Attribute = union(Kind) {
1453 const str: String = @enumFromInt(@intFromEnum(self));1426 const str: String = @enumFromInt(@intFromEnum(self));
1454 return if (str.isAnon()) null else str;1427 return if (str.isAnon()) null else str;
1455 }1428 }
1456
1457 fn toLlvm(self: Kind, builder: *const Builder) *c_uint {
1458 assert(builder.useLibLlvm());
1459 return &builder.llvm.attribute_kind_ids.?[@intFromEnum(self)];
1460 }
1461 };1429 };
14621430
1463 pub const FpClass = packed struct(u32) {1431 pub const FpClass = packed struct(u32) {
...@@ -1815,22 +1783,6 @@ pub const Linkage = enum(u4) {...@@ -1815,22 +1783,6 @@ pub const Linkage = enum(u4) {
1815 ) @TypeOf(writer).Error!void {1783 ) @TypeOf(writer).Error!void {
1816 if (self != .external) try writer.print(" {s}", .{@tagName(self)});1784 if (self != .external) try writer.print(" {s}", .{@tagName(self)});
1817 }1785 }
1818
1819 fn toLlvm(self: Linkage) llvm.Linkage {
1820 return switch (self) {
1821 .private => .Private,
1822 .internal => .Internal,
1823 .weak => .WeakAny,
1824 .weak_odr => .WeakODR,
1825 .linkonce => .LinkOnceAny,
1826 .linkonce_odr => .LinkOnceODR,
1827 .available_externally => .AvailableExternally,
1828 .appending => .Appending,
1829 .common => .Common,
1830 .extern_weak => .ExternalWeak,
1831 .external => .External,
1832 };
1833 }
1834};1786};
18351787
1836pub const Preemption = enum {1788pub const Preemption = enum {
...@@ -1861,14 +1813,6 @@ pub const Visibility = enum(u2) {...@@ -1861,14 +1813,6 @@ pub const Visibility = enum(u2) {
1861 ) @TypeOf(writer).Error!void {1813 ) @TypeOf(writer).Error!void {
1862 if (self != .default) try writer.print(" {s}", .{@tagName(self)});1814 if (self != .default) try writer.print(" {s}", .{@tagName(self)});
1863 }1815 }
1864
1865 fn toLlvm(self: Visibility) llvm.Visibility {
1866 return switch (self) {
1867 .default => .Default,
1868 .hidden => .Hidden,
1869 .protected => .Protected,
1870 };
1871 }
1872};1816};
18731817
1874pub const DllStorageClass = enum(u2) {1818pub const DllStorageClass = enum(u2) {
...@@ -1884,14 +1828,6 @@ pub const DllStorageClass = enum(u2) {...@@ -1884,14 +1828,6 @@ pub const DllStorageClass = enum(u2) {
1884 ) @TypeOf(writer).Error!void {1828 ) @TypeOf(writer).Error!void {
1885 if (self != .default) try writer.print(" {s}", .{@tagName(self)});1829 if (self != .default) try writer.print(" {s}", .{@tagName(self)});
1886 }1830 }
1887
1888 fn toLlvm(self: DllStorageClass) llvm.DLLStorageClass {
1889 return switch (self) {
1890 .default => .Default,
1891 .dllimport => .DLLImport,
1892 .dllexport => .DLLExport,
1893 };
1894 }
1895};1831};
18961832
1897pub const ThreadLocal = enum(u3) {1833pub const ThreadLocal = enum(u3) {
...@@ -1911,16 +1847,6 @@ pub const ThreadLocal = enum(u3) {...@@ -1911,16 +1847,6 @@ pub const ThreadLocal = enum(u3) {
1911 try writer.print("{s}thread_local", .{prefix});1847 try writer.print("{s}thread_local", .{prefix});
1912 if (self != .generaldynamic) try writer.print("({s})", .{@tagName(self)});1848 if (self != .generaldynamic) try writer.print("({s})", .{@tagName(self)});
1913 }1849 }
1914
1915 fn toLlvm(self: ThreadLocal) llvm.ThreadLocalMode {
1916 return switch (self) {
1917 .default => .NotThreadLocal,
1918 .generaldynamic => .GeneralDynamicTLSModel,
1919 .localdynamic => .LocalDynamicTLSModel,
1920 .initialexec => .InitialExecTLSModel,
1921 .localexec => .LocalExecTLSModel,
1922 };
1923 }
1924};1850};
19251851
1926pub const Mutability = enum { global, constant };1852pub const Mutability = enum { global, constant };
...@@ -2189,11 +2115,6 @@ pub const CallConv = enum(u10) {...@@ -2189,11 +2115,6 @@ pub const CallConv = enum(u10) {
2189 _ => try writer.print(" cc{d}", .{@intFromEnum(self)}),2115 _ => try writer.print(" cc{d}", .{@intFromEnum(self)}),
2190 }2116 }
2191 }2117 }
2192
2193 fn toLlvm(self: CallConv) llvm.CallConv {
2194 // These enum values appear in LLVM IR, and so are guaranteed to be stable.
2195 return @enumFromInt(@intFromEnum(self));
2196 }
2197};2118};
21982119
2199pub const Global = struct {2120pub const Global = struct {
...@@ -2263,34 +2184,23 @@ pub const Global = struct {...@@ -2263,34 +2184,23 @@ pub const Global = struct {
2263 }2184 }
22642185
2265 pub fn setLinkage(self: Index, linkage: Linkage, builder: *Builder) void {2186 pub fn setLinkage(self: Index, linkage: Linkage, builder: *Builder) void {
2266 if (builder.useLibLlvm()) self.toLlvm(builder).setLinkage(linkage.toLlvm());
2267 self.ptr(builder).linkage = linkage;2187 self.ptr(builder).linkage = linkage;
2268 self.updateDsoLocal(builder);2188 self.updateDsoLocal(builder);
2269 }2189 }
22702190
2271 pub fn setVisibility(self: Index, visibility: Visibility, builder: *Builder) void {2191 pub fn setVisibility(self: Index, visibility: Visibility, builder: *Builder) void {
2272 if (builder.useLibLlvm()) self.toLlvm(builder).setVisibility(visibility.toLlvm());
2273 self.ptr(builder).visibility = visibility;2192 self.ptr(builder).visibility = visibility;
2274 self.updateDsoLocal(builder);2193 self.updateDsoLocal(builder);
2275 }2194 }
22762195
2277 pub fn setDllStorageClass(self: Index, class: DllStorageClass, builder: *Builder) void {2196 pub fn setDllStorageClass(self: Index, class: DllStorageClass, builder: *Builder) void {
2278 if (builder.useLibLlvm()) self.toLlvm(builder).setDLLStorageClass(class.toLlvm());
2279 self.ptr(builder).dll_storage_class = class;2197 self.ptr(builder).dll_storage_class = class;
2280 }2198 }
22812199
2282 pub fn setUnnamedAddr(self: Index, unnamed_addr: UnnamedAddr, builder: *Builder) void {2200 pub fn setUnnamedAddr(self: Index, unnamed_addr: UnnamedAddr, builder: *Builder) void {
2283 if (builder.useLibLlvm()) self.toLlvm(builder).setUnnamedAddr(
2284 llvm.Bool.fromBool(unnamed_addr != .default),
2285 );
2286 self.ptr(builder).unnamed_addr = unnamed_addr;2201 self.ptr(builder).unnamed_addr = unnamed_addr;
2287 }2202 }
22882203
2289 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
2290 assert(builder.useLibLlvm());
2291 return builder.llvm.globals.items[@intFromEnum(self.unwrap(builder))];
2292 }
2293
2294 const FormatData = struct {2204 const FormatData = struct {
2295 global: Index,2205 global: Index,
2296 builder: *const Builder,2206 builder: *const Builder,
...@@ -2321,13 +2231,10 @@ pub const Global = struct {...@@ -2321,13 +2231,10 @@ pub const Global = struct {
23212231
2322 pub fn replace(self: Index, other: Index, builder: *Builder) Allocator.Error!void {2232 pub fn replace(self: Index, other: Index, builder: *Builder) Allocator.Error!void {
2323 try builder.ensureUnusedGlobalCapacity(.empty);2233 try builder.ensureUnusedGlobalCapacity(.empty);
2324 if (builder.useLibLlvm())
2325 try builder.llvm.replacements.ensureUnusedCapacity(builder.gpa, 1);
2326 self.replaceAssumeCapacity(other, builder);2234 self.replaceAssumeCapacity(other, builder);
2327 }2235 }
23282236
2329 pub fn delete(self: Index, builder: *Builder) void {2237 pub fn delete(self: Index, builder: *Builder) void {
2330 if (builder.useLibLlvm()) self.toLlvm(builder).eraseGlobalValue();
2331 self.ptr(builder).kind = .{ .replaced = .none };2238 self.ptr(builder).kind = .{ .replaced = .none };
2332 }2239 }
23332240
...@@ -2355,12 +2262,8 @@ pub const Global = struct {...@@ -2355,12 +2262,8 @@ pub const Global = struct {
2355 const old_name = self.name(builder);2262 const old_name = self.name(builder);
2356 if (new_name == old_name) return;2263 if (new_name == old_name) return;
2357 const index = @intFromEnum(self.unwrap(builder));2264 const index = @intFromEnum(self.unwrap(builder));
2358 if (builder.useLibLlvm())
2359 builder.llvm.globals.appendAssumeCapacity(builder.llvm.globals.items[index]);
2360 _ = builder.addGlobalAssumeCapacity(new_name, builder.globals.values()[index]);2265 _ = builder.addGlobalAssumeCapacity(new_name, builder.globals.values()[index]);
2361 if (builder.useLibLlvm()) _ = builder.llvm.globals.pop();
2362 builder.globals.swapRemoveAt(index);2266 builder.globals.swapRemoveAt(index);
2363 self.updateName(builder);
2364 if (!old_name.isAnon()) return;2267 if (!old_name.isAnon()) return;
2365 builder.next_unnamed_global = @enumFromInt(@intFromEnum(builder.next_unnamed_global) - 1);2268 builder.next_unnamed_global = @enumFromInt(@intFromEnum(builder.next_unnamed_global) - 1);
2366 if (builder.next_unnamed_global == old_name) return;2269 if (builder.next_unnamed_global == old_name) return;
...@@ -2373,23 +2276,10 @@ pub const Global = struct {...@@ -2373,23 +2276,10 @@ pub const Global = struct {
2373 self.renameAssumeCapacity(other_name, builder);2276 self.renameAssumeCapacity(other_name, builder);
2374 }2277 }
23752278
2376 fn updateName(self: Index, builder: *const Builder) void {
2377 if (!builder.useLibLlvm()) return;
2378 const index = @intFromEnum(self.unwrap(builder));
2379 const name_slice = self.name(builder).slice(builder) orelse "";
2380 builder.llvm.globals.items[index].setValueName(name_slice.ptr, name_slice.len);
2381 }
2382
2383 fn replaceAssumeCapacity(self: Index, other: Index, builder: *Builder) void {2279 fn replaceAssumeCapacity(self: Index, other: Index, builder: *Builder) void {
2384 if (self.eql(other, builder)) return;2280 if (self.eql(other, builder)) return;
2385 builder.next_replaced_global = @enumFromInt(@intFromEnum(builder.next_replaced_global) - 1);2281 builder.next_replaced_global = @enumFromInt(@intFromEnum(builder.next_replaced_global) - 1);
2386 self.renameAssumeCapacity(builder.next_replaced_global, builder);2282 self.renameAssumeCapacity(builder.next_replaced_global, builder);
2387 if (builder.useLibLlvm()) {
2388 const self_llvm = self.toLlvm(builder);
2389 self_llvm.replaceAllUsesWith(other.toLlvm(builder));
2390 self_llvm.removeGlobalValue();
2391 builder.llvm.replacements.putAssumeCapacityNoClobber(self_llvm, other);
2392 }
2393 self.ptr(builder).kind = .{ .replaced = other.unwrap(builder) };2283 self.ptr(builder).kind = .{ .replaced = other.unwrap(builder) };
2394 }2284 }
23952285
...@@ -2446,13 +2336,8 @@ pub const Alias = struct {...@@ -2446,13 +2336,8 @@ pub const Alias = struct {
2446 }2336 }
24472337
2448 pub fn setAliasee(self: Index, aliasee: Constant, builder: *Builder) void {2338 pub fn setAliasee(self: Index, aliasee: Constant, builder: *Builder) void {
2449 if (builder.useLibLlvm()) self.toLlvm(builder).setAliasee(aliasee.toLlvm(builder));
2450 self.ptr(builder).aliasee = aliasee;2339 self.ptr(builder).aliasee = aliasee;
2451 }2340 }
2452
2453 fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
2454 return self.ptrConst(builder).global.toLlvm(builder);
2455 }
2456 };2341 };
2457};2342};
24582343
...@@ -2505,14 +2390,10 @@ pub const Variable = struct {...@@ -2505,14 +2390,10 @@ pub const Variable = struct {
2505 }2390 }
25062391
2507 pub fn setThreadLocal(self: Index, thread_local: ThreadLocal, builder: *Builder) void {2392 pub fn setThreadLocal(self: Index, thread_local: ThreadLocal, builder: *Builder) void {
2508 if (builder.useLibLlvm()) self.toLlvm(builder).setThreadLocalMode(thread_local.toLlvm());
2509 self.ptr(builder).thread_local = thread_local;2393 self.ptr(builder).thread_local = thread_local;
2510 }2394 }
25112395
2512 pub fn setMutability(self: Index, mutability: Mutability, builder: *Builder) void {2396 pub fn setMutability(self: Index, mutability: Mutability, builder: *Builder) void {
2513 if (builder.useLibLlvm()) self.toLlvm(builder).setGlobalConstant(
2514 llvm.Bool.fromBool(mutability == .constant),
2515 );
2516 self.ptr(builder).mutability = mutability;2397 self.ptr(builder).mutability = mutability;
2517 }2398 }
25182399
...@@ -2525,68 +2406,22 @@ pub const Variable = struct {...@@ -2525,68 +2406,22 @@ pub const Variable = struct {
2525 const variable = self.ptrConst(builder);2406 const variable = self.ptrConst(builder);
2526 const global = variable.global.ptr(builder);2407 const global = variable.global.ptr(builder);
2527 const initializer_type = initializer.typeOf(builder);2408 const initializer_type = initializer.typeOf(builder);
2528 if (builder.useLibLlvm() and global.type != initializer_type) {
2529 try builder.llvm.replacements.ensureUnusedCapacity(builder.gpa, 1);
2530 // LLVM does not allow us to change the type of globals. So we must
2531 // create a new global with the correct type, copy all its attributes,
2532 // and then update all references to point to the new global,
2533 // delete the original, and rename the new one to the old one's name.
2534 // This is necessary because LLVM does not support const bitcasting
2535 // a struct with padding bytes, which is needed to lower a const union value
2536 // to LLVM, when a field other than the most-aligned is active. Instead,
2537 // we must lower to an unnamed struct, and pointer cast at usage sites
2538 // of the global. Such an unnamed struct is the cause of the global type
2539 // mismatch, because we don't have the LLVM type until the *value* is created,
2540 // whereas the global needs to be created based on the type alone, because
2541 // lowering the value may reference the global as a pointer.
2542 // Related: https://github.com/ziglang/zig/issues/13265
2543 const old_global = &builder.llvm.globals.items[@intFromEnum(variable.global)];
2544 const new_global = builder.llvm.module.?.addGlobalInAddressSpace(
2545 initializer_type.toLlvm(builder),
2546 "",
2547 @intFromEnum(global.addr_space),
2548 );
2549 new_global.setLinkage(global.linkage.toLlvm());
2550 new_global.setUnnamedAddr(llvm.Bool.fromBool(global.unnamed_addr != .default));
2551 new_global.setAlignment(@intCast(variable.alignment.toByteUnits() orelse 0));
2552 if (variable.section != .none)
2553 new_global.setSection(variable.section.slice(builder).?);
2554 old_global.*.replaceAllUsesWith(new_global);
2555 builder.llvm.replacements.putAssumeCapacityNoClobber(old_global.*, variable.global);
2556 new_global.takeName(old_global.*);
2557 old_global.*.removeGlobalValue();
2558 old_global.* = new_global;
2559 self.ptr(builder).mutability = .global;
2560 }
2561 global.type = initializer_type;2409 global.type = initializer_type;
2562 }2410 }
2563 if (builder.useLibLlvm()) self.toLlvm(builder).setInitializer(switch (initializer) {
2564 .no_init => null,
2565 else => initializer.toLlvm(builder),
2566 });
2567 self.ptr(builder).init = initializer;2411 self.ptr(builder).init = initializer;
2568 }2412 }
25692413
2570 pub fn setSection(self: Index, section: String, builder: *Builder) void {2414 pub fn setSection(self: Index, section: String, builder: *Builder) void {
2571 if (builder.useLibLlvm()) self.toLlvm(builder).setSection(section.slice(builder).?);
2572 self.ptr(builder).section = section;2415 self.ptr(builder).section = section;
2573 }2416 }
25742417
2575 pub fn setAlignment(self: Index, alignment: Alignment, builder: *Builder) void {2418 pub fn setAlignment(self: Index, alignment: Alignment, builder: *Builder) void {
2576 if (builder.useLibLlvm())
2577 self.toLlvm(builder).setAlignment(@intCast(alignment.toByteUnits() orelse 0));
2578 self.ptr(builder).alignment = alignment;2419 self.ptr(builder).alignment = alignment;
2579 }2420 }
25802421
2581 pub fn getAlignment(self: Index, builder: *Builder) Alignment {2422 pub fn getAlignment(self: Index, builder: *Builder) Alignment {
2582 if (builder.useLibLlvm())
2583 return Alignment.fromByteUnits(self.toLlvm(builder).getAlignment());
2584 return self.ptr(builder).alignment;2423 return self.ptr(builder).alignment;
2585 }2424 }
2586
2587 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
2588 return self.ptrConst(builder).global.toLlvm(builder);
2589 }
2590 };2425 };
2591};2426};
25922427
...@@ -3980,7 +3815,6 @@ pub const Function = struct {...@@ -3980,7 +3815,6 @@ pub const Function = struct {
3980 }3815 }
39813816
3982 pub fn setCallConv(self: Index, call_conv: CallConv, builder: *Builder) void {3817 pub fn setCallConv(self: Index, call_conv: CallConv, builder: *Builder) void {
3983 if (builder.useLibLlvm()) self.toLlvm(builder).setFunctionCallConv(call_conv.toLlvm());
3984 self.ptr(builder).call_conv = call_conv;3818 self.ptr(builder).call_conv = call_conv;
3985 }3819 }
39863820
...@@ -3989,95 +3823,16 @@ pub const Function = struct {...@@ -3989,95 +3823,16 @@ pub const Function = struct {
3989 new_function_attributes: FunctionAttributes,3823 new_function_attributes: FunctionAttributes,
3990 builder: *Builder,3824 builder: *Builder,
3991 ) void {3825 ) void {
3992 if (builder.useLibLlvm()) {
3993 const llvm_function = self.toLlvm(builder);
3994 const old_function_attributes = self.ptrConst(builder).attributes;
3995 for (0..@max(
3996 old_function_attributes.slice(builder).len,
3997 new_function_attributes.slice(builder).len,
3998 )) |function_attribute_index| {
3999 const llvm_attribute_index =
4000 @as(llvm.AttributeIndex, @intCast(function_attribute_index)) -% 1;
4001 const old_attributes_slice =
4002 old_function_attributes.get(function_attribute_index, builder).slice(builder);
4003 const new_attributes_slice =
4004 new_function_attributes.get(function_attribute_index, builder).slice(builder);
4005 var old_attribute_index: usize = 0;
4006 var new_attribute_index: usize = 0;
4007 while (true) {
4008 const old_attribute_kind = if (old_attribute_index < old_attributes_slice.len)
4009 old_attributes_slice[old_attribute_index].getKind(builder)
4010 else
4011 .none;
4012 const new_attribute_kind = if (new_attribute_index < new_attributes_slice.len)
4013 new_attributes_slice[new_attribute_index].getKind(builder)
4014 else
4015 .none;
4016 switch (std.math.order(
4017 @intFromEnum(old_attribute_kind),
4018 @intFromEnum(new_attribute_kind),
4019 )) {
4020 .lt => {
4021 // Removed
4022 if (old_attribute_kind.toString()) |attribute_name| {
4023 const attribute_name_slice = attribute_name.slice(builder).?;
4024 llvm_function.removeStringAttributeAtIndex(
4025 llvm_attribute_index,
4026 attribute_name_slice.ptr,
4027 @intCast(attribute_name_slice.len),
4028 );
4029 } else {
4030 const llvm_kind_id = old_attribute_kind.toLlvm(builder).*;
4031 assert(llvm_kind_id != 0);
4032 llvm_function.removeEnumAttributeAtIndex(
4033 llvm_attribute_index,
4034 llvm_kind_id,
4035 );
4036 }
4037 old_attribute_index += 1;
4038 continue;
4039 },
4040 .eq => {
4041 // Iteration finished
4042 if (old_attribute_kind == .none) break;
4043 // No change
4044 if (old_attributes_slice[old_attribute_index] ==
4045 new_attributes_slice[new_attribute_index])
4046 {
4047 old_attribute_index += 1;
4048 new_attribute_index += 1;
4049 continue;
4050 }
4051 old_attribute_index += 1;
4052 },
4053 .gt => {},
4054 }
4055 // New or changed
4056 llvm_function.addAttributeAtIndex(
4057 llvm_attribute_index,
4058 new_attributes_slice[new_attribute_index].toLlvm(builder),
4059 );
4060 new_attribute_index += 1;
4061 }
4062 }
4063 }
4064 self.ptr(builder).attributes = new_function_attributes;3826 self.ptr(builder).attributes = new_function_attributes;
4065 }3827 }
40663828
4067 pub fn setSection(self: Index, section: String, builder: *Builder) void {3829 pub fn setSection(self: Index, section: String, builder: *Builder) void {
4068 if (builder.useLibLlvm()) self.toLlvm(builder).setSection(section.slice(builder).?);
4069 self.ptr(builder).section = section;3830 self.ptr(builder).section = section;
4070 }3831 }
40713832
4072 pub fn setAlignment(self: Index, alignment: Alignment, builder: *Builder) void {3833 pub fn setAlignment(self: Index, alignment: Alignment, builder: *Builder) void {
4073 if (builder.useLibLlvm())
4074 self.toLlvm(builder).setAlignment(@intCast(alignment.toByteUnits() orelse 0));
4075 self.ptr(builder).alignment = alignment;3834 self.ptr(builder).alignment = alignment;
4076 }3835 }
4077
4078 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
4079 return self.ptrConst(builder).global.toLlvm(builder);
4080 }
4081 };3836 };
40823837
4083 pub const Block = struct {3838 pub const Block = struct {
...@@ -4827,13 +4582,6 @@ pub const Function = struct {...@@ -4827,13 +4582,6 @@ pub const Function = struct {
4827 return .{ .data = .{ .instruction = self, .function = function, .builder = builder } };4582 return .{ .data = .{ .instruction = self, .function = function, .builder = builder } };
4828 }4583 }
48294584
4830 fn toLlvm(self: Instruction.Index, wip: *const WipFunction) *llvm.Value {
4831 assert(wip.builder.useLibLlvm());
4832 const llvm_value = wip.llvm.instructions.items[@intFromEnum(self)];
4833 const global = wip.builder.llvm.replacements.get(llvm_value) orelse return llvm_value;
4834 return global.toLlvm(wip.builder);
4835 }
4836
4837 fn llvmName(self: Instruction.Index, wip: *const WipFunction) [:0]const u8 {4585 fn llvmName(self: Instruction.Index, wip: *const WipFunction) [:0]const u8 {
4838 return if (wip.builder.strip)4586 return if (wip.builder.strip)
4839 ""4587 ""
...@@ -4949,27 +4697,6 @@ pub const Function = struct {...@@ -4949,27 +4697,6 @@ pub const Function = struct {
4949 fmax = 13,4697 fmax = 13,
4950 fmin = 14,4698 fmin = 14,
4951 none = std.math.maxInt(u5),4699 none = std.math.maxInt(u5),
4952
4953 fn toLlvm(self: Operation) llvm.AtomicRMWBinOp {
4954 return switch (self) {
4955 .xchg => .Xchg,
4956 .add => .Add,
4957 .sub => .Sub,
4958 .@"and" => .And,
4959 .nand => .Nand,
4960 .@"or" => .Or,
4961 .xor => .Xor,
4962 .max => .Max,
4963 .min => .Min,
4964 .umax => .UMax,
4965 .umin => .UMin,
4966 .fadd => .FAdd,
4967 .fsub => .FSub,
4968 .fmax => .FMax,
4969 .fmin => .FMin,
4970 .none => unreachable,
4971 };
4972 }
4973 };4700 };
4974 };4701 };
49754702
...@@ -5116,11 +4843,6 @@ pub const DebugLocation = struct {...@@ -5116,11 +4843,6 @@ pub const DebugLocation = struct {
5116pub const WipFunction = struct {4843pub const WipFunction = struct {
5117 builder: *Builder,4844 builder: *Builder,
5118 function: Function.Index,4845 function: Function.Index,
5119 llvm: if (build_options.have_llvm) struct {
5120 builder: *llvm.Builder,
5121 blocks: std.ArrayListUnmanaged(*llvm.BasicBlock),
5122 instructions: std.ArrayListUnmanaged(*llvm.Value),
5123 } else void,
5124 last_debug_location: ?DebugLocation,4846 last_debug_location: ?DebugLocation,
5125 current_debug_location: ?DebugLocation,4847 current_debug_location: ?DebugLocation,
5126 cursor: Cursor,4848 cursor: Cursor,
...@@ -5154,30 +4876,15 @@ pub const WipFunction = struct {...@@ -5154,30 +4876,15 @@ pub const WipFunction = struct {
5154 pub fn toInst(self: Index, function: *const Function) Instruction.Index {4876 pub fn toInst(self: Index, function: *const Function) Instruction.Index {
5155 return function.blocks[@intFromEnum(self)].instruction;4877 return function.blocks[@intFromEnum(self)].instruction;
5156 }4878 }
5157
5158 pub fn toLlvm(self: Index, wip: *const WipFunction) *llvm.BasicBlock {
5159 assert(wip.builder.useLibLlvm());
5160 return wip.llvm.blocks.items[@intFromEnum(self)];
5161 }
5162 };4879 };
5163 };4880 };
51644881
5165 pub const Instruction = Function.Instruction;4882 pub const Instruction = Function.Instruction;
51664883
5167 pub fn init(builder: *Builder, function: Function.Index) Allocator.Error!WipFunction {4884 pub fn init(builder: *Builder, function: Function.Index) Allocator.Error!WipFunction {
5168 if (builder.useLibLlvm()) {
5169 const llvm_function = function.toLlvm(builder);
5170 while (llvm_function.getFirstBasicBlock()) |bb| bb.deleteBasicBlock();
5171 }
5172
5173 var self = WipFunction{4885 var self = WipFunction{
5174 .builder = builder,4886 .builder = builder,
5175 .function = function,4887 .function = function,
5176 .llvm = if (builder.useLibLlvm()) .{
5177 .builder = builder.llvm.context.createBuilder(),
5178 .blocks = .{},
5179 .instructions = .{},
5180 } else undefined,
5181 .cursor = undefined,4888 .cursor = undefined,
5182 .blocks = .{},4889 .blocks = .{},
5183 .instructions = .{},4890 .instructions = .{},
...@@ -5196,16 +4903,11 @@ pub const WipFunction = struct {...@@ -5196,16 +4903,11 @@ pub const WipFunction = struct {
5196 if (!self.builder.strip) {4903 if (!self.builder.strip) {
5197 try self.names.ensureUnusedCapacity(self.builder.gpa, params_len);4904 try self.names.ensureUnusedCapacity(self.builder.gpa, params_len);
5198 }4905 }
5199 if (self.builder.useLibLlvm())
5200 try self.llvm.instructions.ensureUnusedCapacity(self.builder.gpa, params_len);
5201 for (0..params_len) |param_index| {4906 for (0..params_len) |param_index| {
5202 self.instructions.appendAssumeCapacity(.{ .tag = .arg, .data = @intCast(param_index) });4907 self.instructions.appendAssumeCapacity(.{ .tag = .arg, .data = @intCast(param_index) });
5203 if (!self.builder.strip) {4908 if (!self.builder.strip) {
5204 self.names.appendAssumeCapacity(.empty); // TODO: param names4909 self.names.appendAssumeCapacity(.empty); // TODO: param names
5205 }4910 }
5206 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5207 function.toLlvm(self.builder).getParam(@intCast(param_index)),
5208 );
5209 }4911 }
52104912
5211 return self;4913 return self;
...@@ -5222,7 +4924,6 @@ pub const WipFunction = struct {...@@ -5222,7 +4924,6 @@ pub const WipFunction = struct {
52224924
5223 pub fn block(self: *WipFunction, incoming: u32, name: []const u8) Allocator.Error!Block.Index {4925 pub fn block(self: *WipFunction, incoming: u32, name: []const u8) Allocator.Error!Block.Index {
5224 try self.blocks.ensureUnusedCapacity(self.builder.gpa, 1);4926 try self.blocks.ensureUnusedCapacity(self.builder.gpa, 1);
5225 if (self.builder.useLibLlvm()) try self.llvm.blocks.ensureUnusedCapacity(self.builder.gpa, 1);
52264927
5227 const index: Block.Index = @enumFromInt(self.blocks.items.len);4928 const index: Block.Index = @enumFromInt(self.blocks.items.len);
5228 const final_name = if (self.builder.strip) .empty else try self.builder.string(name);4929 const final_name = if (self.builder.strip) .empty else try self.builder.string(name);
...@@ -5231,41 +4932,24 @@ pub const WipFunction = struct {...@@ -5231,41 +4932,24 @@ pub const WipFunction = struct {
5231 .incoming = incoming,4932 .incoming = incoming,
5232 .instructions = .{},4933 .instructions = .{},
5233 });4934 });
5234 if (self.builder.useLibLlvm()) self.llvm.blocks.appendAssumeCapacity(
5235 self.builder.llvm.context.appendBasicBlock(
5236 self.function.toLlvm(self.builder),
5237 final_name.slice(self.builder).?,
5238 ),
5239 );
5240 return index;4935 return index;
5241 }4936 }
52424937
5243 pub fn ret(self: *WipFunction, val: Value) Allocator.Error!Instruction.Index {4938 pub fn ret(self: *WipFunction, val: Value) Allocator.Error!Instruction.Index {
5244 assert(val.typeOfWip(self) == self.function.typeOf(self.builder).functionReturn(self.builder));4939 assert(val.typeOfWip(self) == self.function.typeOf(self.builder).functionReturn(self.builder));
5245 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);4940 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);
5246 const instruction = try self.addInst(null, .{ .tag = .ret, .data = @intFromEnum(val) });4941 return try self.addInst(null, .{ .tag = .ret, .data = @intFromEnum(val) });
5247 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5248 self.llvm.builder.buildRet(val.toLlvm(self)),
5249 );
5250 return instruction;
5251 }4942 }
52524943
5253 pub fn retVoid(self: *WipFunction) Allocator.Error!Instruction.Index {4944 pub fn retVoid(self: *WipFunction) Allocator.Error!Instruction.Index {
5254 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);4945 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);
5255 const instruction = try self.addInst(null, .{ .tag = .@"ret void", .data = undefined });4946 return try self.addInst(null, .{ .tag = .@"ret void", .data = undefined });
5256 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5257 self.llvm.builder.buildRetVoid(),
5258 );
5259 return instruction;
5260 }4947 }
52614948
5262 pub fn br(self: *WipFunction, dest: Block.Index) Allocator.Error!Instruction.Index {4949 pub fn br(self: *WipFunction, dest: Block.Index) Allocator.Error!Instruction.Index {
5263 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);4950 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);
5264 const instruction = try self.addInst(null, .{ .tag = .br, .data = @intFromEnum(dest) });4951 const instruction = try self.addInst(null, .{ .tag = .br, .data = @intFromEnum(dest) });
5265 dest.ptr(self).branches += 1;4952 dest.ptr(self).branches += 1;
5266 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5267 self.llvm.builder.buildBr(dest.toLlvm(self)),
5268 );
5269 return instruction;4953 return instruction;
5270 }4954 }
52714955
...@@ -5287,9 +4971,6 @@ pub const WipFunction = struct {...@@ -5287,9 +4971,6 @@ pub const WipFunction = struct {
5287 });4971 });
5288 then.ptr(self).branches += 1;4972 then.ptr(self).branches += 1;
5289 @"else".ptr(self).branches += 1;4973 @"else".ptr(self).branches += 1;
5290 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5291 self.llvm.builder.buildCondBr(cond.toLlvm(self), then.toLlvm(self), @"else".toLlvm(self)),
5292 );
5293 return instruction;4974 return instruction;
5294 }4975 }
52954976
...@@ -5310,8 +4991,6 @@ pub const WipFunction = struct {...@@ -5310,8 +4991,6 @@ pub const WipFunction = struct {
5310 extra.trail.nextMut(extra.data.cases_len, Block.Index, wip)[self.index] = dest;4991 extra.trail.nextMut(extra.data.cases_len, Block.Index, wip)[self.index] = dest;
5311 self.index += 1;4992 self.index += 1;
5312 dest.ptr(wip).branches += 1;4993 dest.ptr(wip).branches += 1;
5313 if (wip.builder.useLibLlvm())
5314 self.instruction.toLlvm(wip).addCase(val.toLlvm(wip.builder), dest.toLlvm(wip));
5315 }4994 }
53164995
5317 pub fn finish(self: WipSwitch, wip: *WipFunction) void {4996 pub fn finish(self: WipSwitch, wip: *WipFunction) void {
...@@ -5338,18 +5017,12 @@ pub const WipFunction = struct {...@@ -5338,18 +5017,12 @@ pub const WipFunction = struct {
5338 });5017 });
5339 _ = self.extra.addManyAsSliceAssumeCapacity(cases_len * 2);5018 _ = self.extra.addManyAsSliceAssumeCapacity(cases_len * 2);
5340 default.ptr(self).branches += 1;5019 default.ptr(self).branches += 1;
5341 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5342 self.llvm.builder.buildSwitch(val.toLlvm(self), default.toLlvm(self), @intCast(cases_len)),
5343 );
5344 return .{ .index = 0, .instruction = instruction };5020 return .{ .index = 0, .instruction = instruction };
5345 }5021 }
53465022
5347 pub fn @"unreachable"(self: *WipFunction) Allocator.Error!Instruction.Index {5023 pub fn @"unreachable"(self: *WipFunction) Allocator.Error!Instruction.Index {
5348 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);5024 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);
5349 const instruction = try self.addInst(null, .{ .tag = .@"unreachable", .data = undefined });5025 const instruction = try self.addInst(null, .{ .tag = .@"unreachable", .data = undefined });
5350 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5351 self.llvm.builder.buildUnreachable(),
5352 );
5353 return instruction;5026 return instruction;
5354 }5027 }
53555028
...@@ -5367,17 +5040,6 @@ pub const WipFunction = struct {...@@ -5367,17 +5040,6 @@ pub const WipFunction = struct {
5367 }5040 }
5368 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);5041 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);
5369 const instruction = try self.addInst(name, .{ .tag = tag, .data = @intFromEnum(val) });5042 const instruction = try self.addInst(name, .{ .tag = tag, .data = @intFromEnum(val) });
5370 if (self.builder.useLibLlvm()) {
5371 switch (tag) {
5372 .fneg => self.llvm.builder.setFastMath(false),
5373 .@"fneg fast" => self.llvm.builder.setFastMath(true),
5374 else => unreachable,
5375 }
5376 self.llvm.instructions.appendAssumeCapacity(switch (tag) {
5377 .fneg, .@"fneg fast" => &llvm.Builder.buildFNeg,
5378 else => unreachable,
5379 }(self.llvm.builder, val.toLlvm(self), instruction.llvmName(self)));
5380 }
5381 return instruction.toValue();5043 return instruction.toValue();
5382 }5044 }
53835045
...@@ -5445,56 +5107,6 @@ pub const WipFunction = struct {...@@ -5445,56 +5107,6 @@ pub const WipFunction = struct {
5445 .tag = tag,5107 .tag = tag,
5446 .data = self.addExtraAssumeCapacity(Instruction.Binary{ .lhs = lhs, .rhs = rhs }),5108 .data = self.addExtraAssumeCapacity(Instruction.Binary{ .lhs = lhs, .rhs = rhs }),
5447 });5109 });
5448 if (self.builder.useLibLlvm()) {
5449 switch (tag) {
5450 .fadd,
5451 .fdiv,
5452 .fmul,
5453 .frem,
5454 .fsub,
5455 => self.llvm.builder.setFastMath(false),
5456 .@"fadd fast",
5457 .@"fdiv fast",
5458 .@"fmul fast",
5459 .@"frem fast",
5460 .@"fsub fast",
5461 => self.llvm.builder.setFastMath(true),
5462 else => {},
5463 }
5464 self.llvm.instructions.appendAssumeCapacity(switch (tag) {
5465 .add => &llvm.Builder.buildAdd,
5466 .@"add nsw" => &llvm.Builder.buildNSWAdd,
5467 .@"add nuw" => &llvm.Builder.buildNUWAdd,
5468 .@"and" => &llvm.Builder.buildAnd,
5469 .ashr => &llvm.Builder.buildAShr,
5470 .@"ashr exact" => &llvm.Builder.buildAShrExact,
5471 .fadd, .@"fadd fast" => &llvm.Builder.buildFAdd,
5472 .fdiv, .@"fdiv fast" => &llvm.Builder.buildFDiv,
5473 .fmul, .@"fmul fast" => &llvm.Builder.buildFMul,
5474 .frem, .@"frem fast" => &llvm.Builder.buildFRem,
5475 .fsub, .@"fsub fast" => &llvm.Builder.buildFSub,
5476 .lshr => &llvm.Builder.buildLShr,
5477 .@"lshr exact" => &llvm.Builder.buildLShrExact,
5478 .mul => &llvm.Builder.buildMul,
5479 .@"mul nsw" => &llvm.Builder.buildNSWMul,
5480 .@"mul nuw" => &llvm.Builder.buildNUWMul,
5481 .@"or" => &llvm.Builder.buildOr,
5482 .sdiv => &llvm.Builder.buildSDiv,
5483 .@"sdiv exact" => &llvm.Builder.buildExactSDiv,
5484 .shl => &llvm.Builder.buildShl,
5485 .@"shl nsw" => &llvm.Builder.buildNSWShl,
5486 .@"shl nuw" => &llvm.Builder.buildNUWShl,
5487 .srem => &llvm.Builder.buildSRem,
5488 .sub => &llvm.Builder.buildSub,
5489 .@"sub nsw" => &llvm.Builder.buildNSWSub,
5490 .@"sub nuw" => &llvm.Builder.buildNUWSub,
5491 .udiv => &llvm.Builder.buildUDiv,
5492 .@"udiv exact" => &llvm.Builder.buildExactUDiv,
5493 .urem => &llvm.Builder.buildURem,
5494 .xor => &llvm.Builder.buildXor,
5495 else => unreachable,
5496 }(self.llvm.builder, lhs.toLlvm(self), rhs.toLlvm(self), instruction.llvmName(self)));
5497 }
5498 return instruction.toValue();5110 return instruction.toValue();
5499 }5111 }
55005112
...@@ -5514,13 +5126,6 @@ pub const WipFunction = struct {...@@ -5514,13 +5126,6 @@ pub const WipFunction = struct {
5514 .index = index,5126 .index = index,
5515 }),5127 }),
5516 });5128 });
5517 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5518 self.llvm.builder.buildExtractElement(
5519 val.toLlvm(self),
5520 index.toLlvm(self),
5521 instruction.llvmName(self),
5522 ),
5523 );
5524 return instruction.toValue();5129 return instruction.toValue();
5525 }5130 }
55265131
...@@ -5542,14 +5147,6 @@ pub const WipFunction = struct {...@@ -5542,14 +5147,6 @@ pub const WipFunction = struct {
5542 .index = index,5147 .index = index,
5543 }),5148 }),
5544 });5149 });
5545 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5546 self.llvm.builder.buildInsertElement(
5547 val.toLlvm(self),
5548 elem.toLlvm(self),
5549 index.toLlvm(self),
5550 instruction.llvmName(self),
5551 ),
5552 );
5553 return instruction.toValue();5150 return instruction.toValue();
5554 }5151 }
55555152
...@@ -5572,14 +5169,6 @@ pub const WipFunction = struct {...@@ -5572,14 +5169,6 @@ pub const WipFunction = struct {
5572 .mask = mask,5169 .mask = mask,
5573 }),5170 }),
5574 });5171 });
5575 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5576 self.llvm.builder.buildShuffleVector(
5577 lhs.toLlvm(self),
5578 rhs.toLlvm(self),
5579 mask.toLlvm(self),
5580 instruction.llvmName(self),
5581 ),
5582 );
5583 return instruction.toValue();5172 return instruction.toValue();
5584 }5173 }
55855174
...@@ -5615,13 +5204,6 @@ pub const WipFunction = struct {...@@ -5615,13 +5204,6 @@ pub const WipFunction = struct {
5615 }),5204 }),
5616 });5205 });
5617 self.extra.appendSliceAssumeCapacity(indices);5206 self.extra.appendSliceAssumeCapacity(indices);
5618 if (self.builder.useLibLlvm()) {
5619 const llvm_name = instruction.llvmName(self);
5620 var cur = val.toLlvm(self);
5621 for (indices) |index|
5622 cur = self.llvm.builder.buildExtractValue(cur, @intCast(index), llvm_name);
5623 self.llvm.instructions.appendAssumeCapacity(cur);
5624 }
5625 return instruction.toValue();5207 return instruction.toValue();
5626 }5208 }
56275209
...@@ -5644,35 +5226,6 @@ pub const WipFunction = struct {...@@ -5644,35 +5226,6 @@ pub const WipFunction = struct {
5644 }),5226 }),
5645 });5227 });
5646 self.extra.appendSliceAssumeCapacity(indices);5228 self.extra.appendSliceAssumeCapacity(indices);
5647 if (self.builder.useLibLlvm()) {
5648 const ExpectedContents = [expected_gep_indices_len]*llvm.Value;
5649 var stack align(@alignOf(ExpectedContents)) =
5650 std.heap.stackFallback(@sizeOf(ExpectedContents), self.builder.gpa);
5651 const allocator = stack.get();
5652
5653 const llvm_name = instruction.llvmName(self);
5654 const llvm_vals = try allocator.alloc(*llvm.Value, indices.len);
5655 defer allocator.free(llvm_vals);
5656 llvm_vals[0] = val.toLlvm(self);
5657 for (llvm_vals[1..], llvm_vals[0 .. llvm_vals.len - 1], indices[0 .. indices.len - 1]) |
5658 *cur_val,
5659 prev_val,
5660 index,
5661 | cur_val.* = self.llvm.builder.buildExtractValue(prev_val, @intCast(index), llvm_name);
5662
5663 var depth: usize = llvm_vals.len;
5664 var cur = elem.toLlvm(self);
5665 while (depth > 0) {
5666 depth -= 1;
5667 cur = self.llvm.builder.buildInsertValue(
5668 llvm_vals[depth],
5669 cur,
5670 @intCast(indices[depth]),
5671 llvm_name,
5672 );
5673 }
5674 self.llvm.instructions.appendAssumeCapacity(cur);
5675 }
5676 return instruction.toValue();5229 return instruction.toValue();
5677 }5230 }
56785231
...@@ -5712,15 +5265,6 @@ pub const WipFunction = struct {...@@ -5712,15 +5265,6 @@ pub const WipFunction = struct {
5712 .info = .{ .alignment = alignment, .addr_space = addr_space },5265 .info = .{ .alignment = alignment, .addr_space = addr_space },
5713 }),5266 }),
5714 });5267 });
5715 if (self.builder.useLibLlvm()) {
5716 const llvm_instruction = self.llvm.builder.buildAllocaInAddressSpace(
5717 ty.toLlvm(self.builder),
5718 @intFromEnum(addr_space),
5719 instruction.llvmName(self),
5720 );
5721 if (alignment.toByteUnits()) |bytes| llvm_instruction.setAlignment(@intCast(bytes));
5722 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);
5723 }
5724 return instruction.toValue();5268 return instruction.toValue();
5725 }5269 }
57265270
...@@ -5766,17 +5310,6 @@ pub const WipFunction = struct {...@@ -5766,17 +5310,6 @@ pub const WipFunction = struct {
5766 .ptr = ptr,5310 .ptr = ptr,
5767 }),5311 }),
5768 });5312 });
5769 if (self.builder.useLibLlvm()) {
5770 const llvm_instruction = self.llvm.builder.buildLoad(
5771 ty.toLlvm(self.builder),
5772 ptr.toLlvm(self),
5773 instruction.llvmName(self),
5774 );
5775 if (access_kind == .@"volatile") llvm_instruction.setVolatile(.True);
5776 if (ordering != .none) llvm_instruction.setOrdering(ordering.toLlvm());
5777 if (alignment.toByteUnits()) |bytes| llvm_instruction.setAlignment(@intCast(bytes));
5778 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);
5779 }
5780 return instruction.toValue();5313 return instruction.toValue();
5781 }5314 }
57825315
...@@ -5820,13 +5353,6 @@ pub const WipFunction = struct {...@@ -5820,13 +5353,6 @@ pub const WipFunction = struct {
5820 .ptr = ptr,5353 .ptr = ptr,
5821 }),5354 }),
5822 });5355 });
5823 if (self.builder.useLibLlvm()) {
5824 const llvm_instruction = self.llvm.builder.buildStore(val.toLlvm(self), ptr.toLlvm(self));
5825 if (access_kind == .@"volatile") llvm_instruction.setVolatile(.True);
5826 if (ordering != .none) llvm_instruction.setOrdering(ordering.toLlvm());
5827 if (alignment.toByteUnits()) |bytes| llvm_instruction.setAlignment(@intCast(bytes));
5828 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);
5829 }
5830 return instruction;5356 return instruction;
5831 }5357 }
58325358
...@@ -5844,13 +5370,6 @@ pub const WipFunction = struct {...@@ -5844,13 +5370,6 @@ pub const WipFunction = struct {
5844 .success_ordering = ordering,5370 .success_ordering = ordering,
5845 }),5371 }),
5846 });5372 });
5847 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5848 self.llvm.builder.buildFence(
5849 ordering.toLlvm(),
5850 llvm.Bool.fromBool(sync_scope == .singlethread),
5851 "",
5852 ),
5853 );
5854 return instruction;5373 return instruction;
5855 }5374 }
58565375
...@@ -5893,25 +5412,6 @@ pub const WipFunction = struct {...@@ -5893,25 +5412,6 @@ pub const WipFunction = struct {
5893 .new = new,5412 .new = new,
5894 }),5413 }),
5895 });5414 });
5896 if (self.builder.useLibLlvm()) {
5897 const llvm_instruction = self.llvm.builder.buildAtomicCmpXchg(
5898 ptr.toLlvm(self),
5899 cmp.toLlvm(self),
5900 new.toLlvm(self),
5901 success_ordering.toLlvm(),
5902 failure_ordering.toLlvm(),
5903 llvm.Bool.fromBool(sync_scope == .singlethread),
5904 );
5905 if (kind == .weak) llvm_instruction.setWeak(.True);
5906 if (access_kind == .@"volatile") llvm_instruction.setVolatile(.True);
5907 if (alignment.toByteUnits()) |bytes| llvm_instruction.setAlignment(@intCast(bytes));
5908 const llvm_name = instruction.llvmName(self);
5909 if (llvm_name.len > 0) llvm_instruction.setValueName(
5910 llvm_name.ptr,
5911 @intCast(llvm_name.len),
5912 );
5913 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);
5914 }
5915 return instruction.toValue();5415 return instruction.toValue();
5916 }5416 }
59175417
...@@ -5944,23 +5444,6 @@ pub const WipFunction = struct {...@@ -5944,23 +5444,6 @@ pub const WipFunction = struct {
5944 .val = val,5444 .val = val,
5945 }),5445 }),
5946 });5446 });
5947 if (self.builder.useLibLlvm()) {
5948 const llvm_instruction = self.llvm.builder.buildAtomicRmw(
5949 operation.toLlvm(),
5950 ptr.toLlvm(self),
5951 val.toLlvm(self),
5952 ordering.toLlvm(),
5953 llvm.Bool.fromBool(sync_scope == .singlethread),
5954 );
5955 if (access_kind == .@"volatile") llvm_instruction.setVolatile(.True);
5956 if (alignment.toByteUnits()) |bytes| llvm_instruction.setAlignment(@intCast(bytes));
5957 const llvm_name = instruction.llvmName(self);
5958 if (llvm_name.len > 0) llvm_instruction.setValueName(
5959 llvm_name.ptr,
5960 @intCast(llvm_name.len),
5961 );
5962 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);
5963 }
5964 return instruction.toValue();5447 return instruction.toValue();
5965 }5448 }
59665449
...@@ -6020,28 +5503,6 @@ pub const WipFunction = struct {...@@ -6020,28 +5503,6 @@ pub const WipFunction = struct {
6020 }),5503 }),
6021 });5504 });
6022 self.extra.appendSliceAssumeCapacity(@ptrCast(indices));5505 self.extra.appendSliceAssumeCapacity(@ptrCast(indices));
6023 if (self.builder.useLibLlvm()) {
6024 const ExpectedContents = [expected_gep_indices_len]*llvm.Value;
6025 var stack align(@alignOf(ExpectedContents)) =
6026 std.heap.stackFallback(@sizeOf(ExpectedContents), self.builder.gpa);
6027 const allocator = stack.get();
6028
6029 const llvm_indices = try allocator.alloc(*llvm.Value, indices.len);
6030 defer allocator.free(llvm_indices);
6031 for (llvm_indices, indices) |*llvm_index, index| llvm_index.* = index.toLlvm(self);
6032
6033 self.llvm.instructions.appendAssumeCapacity(switch (kind) {
6034 .normal => &llvm.Builder.buildGEP,
6035 .inbounds => &llvm.Builder.buildInBoundsGEP,
6036 }(
6037 self.llvm.builder,
6038 ty.toLlvm(self.builder),
6039 base.toLlvm(self),
6040 llvm_indices.ptr,
6041 @intCast(llvm_indices.len),
6042 instruction.llvmName(self),
6043 ));
6044 }
6045 return instruction.toValue();5506 return instruction.toValue();
6046 }5507 }
60475508
...@@ -6103,22 +5564,6 @@ pub const WipFunction = struct {...@@ -6103,22 +5564,6 @@ pub const WipFunction = struct {
6103 .type = ty,5564 .type = ty,
6104 }),5565 }),
6105 });5566 });
6106 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(switch (tag) {
6107 .addrspacecast => &llvm.Builder.buildAddrSpaceCast,
6108 .bitcast => &llvm.Builder.buildBitCast,
6109 .fpext => &llvm.Builder.buildFPExt,
6110 .fptosi => &llvm.Builder.buildFPToSI,
6111 .fptoui => &llvm.Builder.buildFPToUI,
6112 .fptrunc => &llvm.Builder.buildFPTrunc,
6113 .inttoptr => &llvm.Builder.buildIntToPtr,
6114 .ptrtoint => &llvm.Builder.buildPtrToInt,
6115 .sext => &llvm.Builder.buildSExt,
6116 .sitofp => &llvm.Builder.buildSIToFP,
6117 .trunc => &llvm.Builder.buildTrunc,
6118 .uitofp => &llvm.Builder.buildUIToFP,
6119 .zext => &llvm.Builder.buildZExt,
6120 else => unreachable,
6121 }(self.llvm.builder, val.toLlvm(self), ty.toLlvm(self.builder), instruction.llvmName(self)));
6122 return instruction.toValue();5567 return instruction.toValue();
6123 }5568 }
61245569
...@@ -6131,7 +5576,7 @@ pub const WipFunction = struct {...@@ -6131,7 +5576,7 @@ pub const WipFunction = struct {
6131 ) Allocator.Error!Value {5576 ) Allocator.Error!Value {
6132 return self.cmpTag(switch (cond) {5577 return self.cmpTag(switch (cond) {
6133 inline else => |tag| @field(Instruction.Tag, "icmp " ++ @tagName(tag)),5578 inline else => |tag| @field(Instruction.Tag, "icmp " ++ @tagName(tag)),
6134 }, @intFromEnum(cond), lhs, rhs, name);5579 }, lhs, rhs, name);
6135 }5580 }
61365581
6137 pub fn fcmp(5582 pub fn fcmp(
...@@ -6149,7 +5594,7 @@ pub const WipFunction = struct {...@@ -6149,7 +5594,7 @@ pub const WipFunction = struct {
6149 .fast => "fast ",5594 .fast => "fast ",
6150 } ++ @tagName(cond_tag)),5595 } ++ @tagName(cond_tag)),
6151 },5596 },
6152 }, @intFromEnum(cond), lhs, rhs, name);5597 }, lhs, rhs, name);
6153 }5598 }
61545599
6155 pub const WipPhi = struct {5600 pub const WipPhi = struct {
...@@ -6173,26 +5618,6 @@ pub const WipFunction = struct {...@@ -6173,26 +5618,6 @@ pub const WipFunction = struct {
6173 for (vals) |val| assert(val.typeOfWip(wip) == extra.data.type);5618 for (vals) |val| assert(val.typeOfWip(wip) == extra.data.type);
6174 @memcpy(extra.trail.nextMut(incoming_len, Value, wip), vals);5619 @memcpy(extra.trail.nextMut(incoming_len, Value, wip), vals);
6175 @memcpy(extra.trail.nextMut(incoming_len, Block.Index, wip), blocks);5620 @memcpy(extra.trail.nextMut(incoming_len, Block.Index, wip), blocks);
6176 if (wip.builder.useLibLlvm()) {
6177 const ExpectedContents = extern struct {
6178 values: [expected_incoming_len]*llvm.Value,
6179 blocks: [expected_incoming_len]*llvm.BasicBlock,
6180 };
6181 var stack align(@alignOf(ExpectedContents)) =
6182 std.heap.stackFallback(@sizeOf(ExpectedContents), wip.builder.gpa);
6183 const allocator = stack.get();
6184
6185 const llvm_vals = try allocator.alloc(*llvm.Value, incoming_len);
6186 defer allocator.free(llvm_vals);
6187 const llvm_blocks = try allocator.alloc(*llvm.BasicBlock, incoming_len);
6188 defer allocator.free(llvm_blocks);
6189
6190 for (llvm_vals, vals) |*llvm_val, incoming_val| llvm_val.* = incoming_val.toLlvm(wip);
6191 for (llvm_blocks, blocks) |*llvm_block, incoming_block|
6192 llvm_block.* = incoming_block.toLlvm(wip);
6193 self.instruction.toLlvm(wip)
6194 .addIncoming(llvm_vals.ptr, llvm_blocks.ptr, @intCast(incoming_len));
6195 }
6196 }5621 }
6197 };5622 };
61985623
...@@ -6258,53 +5683,6 @@ pub const WipFunction = struct {...@@ -6258,53 +5683,6 @@ pub const WipFunction = struct {
6258 }),5683 }),
6259 });5684 });
6260 self.extra.appendSliceAssumeCapacity(@ptrCast(args));5685 self.extra.appendSliceAssumeCapacity(@ptrCast(args));
6261 if (self.builder.useLibLlvm()) {
6262 const ExpectedContents = [expected_args_len]*llvm.Value;
6263 var stack align(@alignOf(ExpectedContents)) =
6264 std.heap.stackFallback(@sizeOf(ExpectedContents), self.builder.gpa);
6265 const allocator = stack.get();
6266
6267 const llvm_args = try allocator.alloc(*llvm.Value, args.len);
6268 defer allocator.free(llvm_args);
6269 for (llvm_args, args) |*llvm_arg, arg_val| llvm_arg.* = arg_val.toLlvm(self);
6270
6271 switch (kind) {
6272 .normal,
6273 .musttail,
6274 .notail,
6275 .tail,
6276 => self.llvm.builder.setFastMath(false),
6277 .fast,
6278 .musttail_fast,
6279 .notail_fast,
6280 .tail_fast,
6281 => self.llvm.builder.setFastMath(true),
6282 }
6283 const llvm_instruction = self.llvm.builder.buildCall(
6284 ty.toLlvm(self.builder),
6285 callee.toLlvm(self),
6286 llvm_args.ptr,
6287 @intCast(llvm_args.len),
6288 switch (ret_ty) {
6289 .void => "",
6290 else => instruction.llvmName(self),
6291 },
6292 );
6293 llvm_instruction.setInstructionCallConv(call_conv.toLlvm());
6294 llvm_instruction.setTailCallKind(switch (kind) {
6295 .normal, .fast => .None,
6296 .musttail, .musttail_fast => .MustTail,
6297 .notail, .notail_fast => .NoTail,
6298 .tail, .tail_fast => .Tail,
6299 });
6300 for (0.., function_attributes.slice(self.builder)) |index, attributes| {
6301 for (attributes.slice(self.builder)) |attribute| llvm_instruction.addCallSiteAttribute(
6302 @as(llvm.AttributeIndex, @intCast(index)) -% 1,
6303 attribute.toLlvm(self.builder),
6304 );
6305 }
6306 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);
6307 }
6308 return instruction.toValue();5686 return instruction.toValue();
6309 }5687 }
63105688
...@@ -6405,13 +5783,6 @@ pub const WipFunction = struct {...@@ -6405,13 +5783,6 @@ pub const WipFunction = struct {
6405 .type = ty,5783 .type = ty,
6406 }),5784 }),
6407 });5785 });
6408 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
6409 self.llvm.builder.buildVAArg(
6410 list.toLlvm(self),
6411 ty.toLlvm(self.builder),
6412 instruction.llvmName(self),
6413 ),
6414 );
6415 return instruction.toValue();5786 return instruction.toValue();
6416 }5787 }
64175788
...@@ -6923,18 +6294,12 @@ pub const WipFunction = struct {...@@ -6923,18 +6294,12 @@ pub const WipFunction = struct {
6923 self.instructions.deinit(self.builder.gpa);6294 self.instructions.deinit(self.builder.gpa);
6924 for (self.blocks.items) |*b| b.instructions.deinit(self.builder.gpa);6295 for (self.blocks.items) |*b| b.instructions.deinit(self.builder.gpa);
6925 self.blocks.deinit(self.builder.gpa);6296 self.blocks.deinit(self.builder.gpa);
6926 if (self.builder.useLibLlvm()) {
6927 self.llvm.instructions.deinit(self.builder.gpa);
6928 self.llvm.blocks.deinit(self.builder.gpa);
6929 self.llvm.builder.dispose();
6930 }
6931 self.* = undefined;6297 self.* = undefined;
6932 }6298 }
69336299
6934 fn cmpTag(6300 fn cmpTag(
6935 self: *WipFunction,6301 self: *WipFunction,
6936 tag: Instruction.Tag,6302 tag: Instruction.Tag,
6937 cond: u32,
6938 lhs: Value,6303 lhs: Value,
6939 rhs: Value,6304 rhs: Value,
6940 name: []const u8,6305 name: []const u8,
...@@ -6994,113 +6359,6 @@ pub const WipFunction = struct {...@@ -6994,113 +6359,6 @@ pub const WipFunction = struct {
6994 .rhs = rhs,6359 .rhs = rhs,
6995 }),6360 }),
6996 });6361 });
6997 if (self.builder.useLibLlvm()) {
6998 switch (tag) {
6999 .@"fcmp false",
7000 .@"fcmp oeq",
7001 .@"fcmp oge",
7002 .@"fcmp ogt",
7003 .@"fcmp ole",
7004 .@"fcmp olt",
7005 .@"fcmp one",
7006 .@"fcmp ord",
7007 .@"fcmp true",
7008 .@"fcmp ueq",
7009 .@"fcmp uge",
7010 .@"fcmp ugt",
7011 .@"fcmp ule",
7012 .@"fcmp ult",
7013 .@"fcmp une",
7014 .@"fcmp uno",
7015 => self.llvm.builder.setFastMath(false),
7016 .@"fcmp fast false",
7017 .@"fcmp fast oeq",
7018 .@"fcmp fast oge",
7019 .@"fcmp fast ogt",
7020 .@"fcmp fast ole",
7021 .@"fcmp fast olt",
7022 .@"fcmp fast one",
7023 .@"fcmp fast ord",
7024 .@"fcmp fast true",
7025 .@"fcmp fast ueq",
7026 .@"fcmp fast uge",
7027 .@"fcmp fast ugt",
7028 .@"fcmp fast ule",
7029 .@"fcmp fast ult",
7030 .@"fcmp fast une",
7031 .@"fcmp fast uno",
7032 => self.llvm.builder.setFastMath(true),
7033 .@"icmp eq",
7034 .@"icmp ne",
7035 .@"icmp sge",
7036 .@"icmp sgt",
7037 .@"icmp sle",
7038 .@"icmp slt",
7039 .@"icmp uge",
7040 .@"icmp ugt",
7041 .@"icmp ule",
7042 .@"icmp ult",
7043 => {},
7044 else => unreachable,
7045 }
7046 self.llvm.instructions.appendAssumeCapacity(switch (tag) {
7047 .@"fcmp false",
7048 .@"fcmp fast false",
7049 .@"fcmp fast oeq",
7050 .@"fcmp fast oge",
7051 .@"fcmp fast ogt",
7052 .@"fcmp fast ole",
7053 .@"fcmp fast olt",
7054 .@"fcmp fast one",
7055 .@"fcmp fast ord",
7056 .@"fcmp fast true",
7057 .@"fcmp fast ueq",
7058 .@"fcmp fast uge",
7059 .@"fcmp fast ugt",
7060 .@"fcmp fast ule",
7061 .@"fcmp fast ult",
7062 .@"fcmp fast une",
7063 .@"fcmp fast uno",
7064 .@"fcmp oeq",
7065 .@"fcmp oge",
7066 .@"fcmp ogt",
7067 .@"fcmp ole",
7068 .@"fcmp olt",
7069 .@"fcmp one",
7070 .@"fcmp ord",
7071 .@"fcmp true",
7072 .@"fcmp ueq",
7073 .@"fcmp uge",
7074 .@"fcmp ugt",
7075 .@"fcmp ule",
7076 .@"fcmp ult",
7077 .@"fcmp une",
7078 .@"fcmp uno",
7079 => self.llvm.builder.buildFCmp(
7080 @enumFromInt(cond),
7081 lhs.toLlvm(self),
7082 rhs.toLlvm(self),
7083 instruction.llvmName(self),
7084 ),
7085 .@"icmp eq",
7086 .@"icmp ne",
7087 .@"icmp sge",
7088 .@"icmp sgt",
7089 .@"icmp sle",
7090 .@"icmp slt",
7091 .@"icmp uge",
7092 .@"icmp ugt",
7093 .@"icmp ule",
7094 .@"icmp ult",
7095 => self.llvm.builder.buildICmp(
7096 @enumFromInt(cond),
7097 lhs.toLlvm(self),
7098 rhs.toLlvm(self),
7099 instruction.llvmName(self),
7100 ),
7101 else => unreachable,
7102 });
7103 }
7104 return instruction.toValue();6362 return instruction.toValue();
7105 }6363 }
71066364
...@@ -7122,16 +6380,6 @@ pub const WipFunction = struct {...@@ -7122,16 +6380,6 @@ pub const WipFunction = struct {
7122 .data = self.addExtraAssumeCapacity(Instruction.Phi{ .type = ty }),6380 .data = self.addExtraAssumeCapacity(Instruction.Phi{ .type = ty }),
7123 });6381 });
7124 _ = self.extra.addManyAsSliceAssumeCapacity(incoming * 2);6382 _ = self.extra.addManyAsSliceAssumeCapacity(incoming * 2);
7125 if (self.builder.useLibLlvm()) {
7126 switch (tag) {
7127 .phi => self.llvm.builder.setFastMath(false),
7128 .@"phi fast" => self.llvm.builder.setFastMath(true),
7129 else => unreachable,
7130 }
7131 self.llvm.instructions.appendAssumeCapacity(
7132 self.llvm.builder.buildPhi(ty.toLlvm(self.builder), instruction.llvmName(self)),
7133 );
7134 }
7135 return .{ .block = self.cursor.block, .instruction = instruction };6383 return .{ .block = self.cursor.block, .instruction = instruction };
7136 }6384 }
71376385
...@@ -7159,19 +6407,6 @@ pub const WipFunction = struct {...@@ -7159,19 +6407,6 @@ pub const WipFunction = struct {
7159 .rhs = rhs,6407 .rhs = rhs,
7160 }),6408 }),
7161 });6409 });
7162 if (self.builder.useLibLlvm()) {
7163 switch (tag) {
7164 .select => self.llvm.builder.setFastMath(false),
7165 .@"select fast" => self.llvm.builder.setFastMath(true),
7166 else => unreachable,
7167 }
7168 self.llvm.instructions.appendAssumeCapacity(self.llvm.builder.buildSelect(
7169 cond.toLlvm(self),
7170 lhs.toLlvm(self),
7171 rhs.toLlvm(self),
7172 instruction.llvmName(self),
7173 ));
7174 }
7175 return instruction.toValue();6410 return instruction.toValue();
7176 }6411 }
71776412
...@@ -7205,23 +6440,11 @@ pub const WipFunction = struct {...@@ -7205,23 +6440,11 @@ pub const WipFunction = struct {
7205 }6440 }
7206 }6441 }
7207 try block_instructions.ensureUnusedCapacity(self.builder.gpa, 1);6442 try block_instructions.ensureUnusedCapacity(self.builder.gpa, 1);
7208 if (self.builder.useLibLlvm())
7209 try self.llvm.instructions.ensureUnusedCapacity(self.builder.gpa, 1);
7210 const final_name = if (name) |n|6443 const final_name = if (name) |n|
7211 if (self.builder.strip) .empty else try self.builder.string(n)6444 if (self.builder.strip) .empty else try self.builder.string(n)
7212 else6445 else
7213 .none;6446 .none;
72146447
7215 if (self.builder.useLibLlvm()) self.llvm.builder.positionBuilder(
7216 self.cursor.block.toLlvm(self),
7217 for (block_instructions.items[self.cursor.instruction..]) |instruction_index| {
7218 const llvm_instruction =
7219 self.llvm.instructions.items[@intFromEnum(instruction_index)];
7220 // TODO: remove when constant propagation is implemented
7221 if (!llvm_instruction.isConstant().toBool()) break llvm_instruction;
7222 } else null,
7223 );
7224
7225 const index: Instruction.Index = @enumFromInt(self.instructions.len);6448 const index: Instruction.Index = @enumFromInt(self.instructions.len);
7226 self.instructions.appendAssumeCapacity(instruction);6449 self.instructions.appendAssumeCapacity(instruction);
7227 if (!self.builder.strip) {6450 if (!self.builder.strip) {
...@@ -7333,24 +6556,6 @@ pub const FloatCondition = enum(u4) {...@@ -7333,24 +6556,6 @@ pub const FloatCondition = enum(u4) {
7333 ult = 12,6556 ult = 12,
7334 ule = 13,6557 ule = 13,
7335 une = 14,6558 une = 14,
7336
7337 fn toLlvm(self: FloatCondition) llvm.RealPredicate {
7338 return switch (self) {
7339 .oeq => .OEQ,
7340 .ogt => .OGT,
7341 .oge => .OGE,
7342 .olt => .OLT,
7343 .ole => .OLE,
7344 .one => .ONE,
7345 .ord => .ORD,
7346 .uno => .UNO,
7347 .ueq => .UEQ,
7348 .ugt => .UGT,
7349 .uge => .UGE,
7350 .ult => .ULT,
7351 .uno => .UNE,
7352 };
7353 }
7354};6559};
73556560
7356pub const IntegerCondition = enum(u6) {6561pub const IntegerCondition = enum(u6) {
...@@ -7364,20 +6569,6 @@ pub const IntegerCondition = enum(u6) {...@@ -7364,20 +6569,6 @@ pub const IntegerCondition = enum(u6) {
7364 sge = 39,6569 sge = 39,
7365 slt = 40,6570 slt = 40,
7366 sle = 41,6571 sle = 41,
7367
7368 fn toLlvm(self: IntegerCondition) llvm.IntPredicate {
7369 return switch (self) {
7370 .eq => .EQ,
7371 .ne => .NE,
7372 .ugt => .UGT,
7373 .uge => .UGE,
7374 .ult => .ULT,
7375 .sgt => .SGT,
7376 .sge => .SGE,
7377 .slt => .SLT,
7378 .sle => .SLE,
7379 };
7380 }
7381};6572};
73826573
7383pub const MemoryAccessKind = enum(u1) {6574pub const MemoryAccessKind = enum(u1) {
...@@ -7427,18 +6618,6 @@ pub const AtomicOrdering = enum(u3) {...@@ -7427,18 +6618,6 @@ pub const AtomicOrdering = enum(u3) {
7427 ) @TypeOf(writer).Error!void {6618 ) @TypeOf(writer).Error!void {
7428 if (self != .none) try writer.print("{s}{s}", .{ prefix, @tagName(self) });6619 if (self != .none) try writer.print("{s}{s}", .{ prefix, @tagName(self) });
7429 }6620 }
7430
7431 fn toLlvm(self: AtomicOrdering) llvm.AtomicOrdering {
7432 return switch (self) {
7433 .none => .NotAtomic,
7434 .unordered => .Unordered,
7435 .monotonic => .Monotonic,
7436 .acquire => .Acquire,
7437 .release => .Release,
7438 .acq_rel => .AcquireRelease,
7439 .seq_cst => .SequentiallyConsistent,
7440 };
7441 }
7442};6621};
74436622
7444const MemoryAccessInfo = packed struct(u32) {6623const MemoryAccessInfo = packed struct(u32) {
...@@ -8259,16 +7438,6 @@ pub const Constant = enum(u32) {...@@ -8259,16 +7438,6 @@ pub const Constant = enum(u32) {
8259 pub fn fmt(self: Constant, builder: *Builder) std.fmt.Formatter(format) {7438 pub fn fmt(self: Constant, builder: *Builder) std.fmt.Formatter(format) {
8260 return .{ .data = .{ .constant = self, .builder = builder } };7439 return .{ .data = .{ .constant = self, .builder = builder } };
8261 }7440 }
8262
8263 pub fn toLlvm(self: Constant, builder: *const Builder) *llvm.Value {
8264 assert(builder.useLibLlvm());
8265 const llvm_value = switch (self.unwrap()) {
8266 .constant => |constant| builder.llvm.constants.items[constant],
8267 .global => |global| return global.toLlvm(builder),
8268 };
8269 const global = builder.llvm.replacements.get(llvm_value) orelse return llvm_value;
8270 return global.toLlvm(builder);
8271 }
8272};7441};
82737442
8274pub const Value = enum(u32) {7443pub const Value = enum(u32) {
...@@ -8343,14 +7512,6 @@ pub const Value = enum(u32) {...@@ -8343,14 +7512,6 @@ pub const Value = enum(u32) {
8343 pub fn fmt(self: Value, function: Function.Index, builder: *Builder) std.fmt.Formatter(format) {7512 pub fn fmt(self: Value, function: Function.Index, builder: *Builder) std.fmt.Formatter(format) {
8344 return .{ .data = .{ .value = self, .function = function, .builder = builder } };7513 return .{ .data = .{ .value = self, .function = function, .builder = builder } };
8345 }7514 }
8346
8347 pub fn toLlvm(self: Value, wip: *const WipFunction) *llvm.Value {
8348 return switch (self.unwrap()) {
8349 .instruction => |instruction| instruction.toLlvm(wip),
8350 .constant => |constant| constant.toLlvm(wip.builder),
8351 .metadata => unreachable,
8352 };
8353 }
8354};7515};
83557516
8356pub const MetadataString = enum(u32) {7517pub const MetadataString = enum(u32) {
...@@ -8589,11 +7750,8 @@ pub const InitError = error{...@@ -8589,11 +7750,8 @@ pub const InitError = error{
8589pub fn init(options: Options) InitError!Builder {7750pub fn init(options: Options) InitError!Builder {
8590 var self = Builder{7751 var self = Builder{
8591 .gpa = options.allocator,7752 .gpa = options.allocator,
8592 .use_lib_llvm = options.use_lib_llvm,
8593 .strip = options.strip,7753 .strip = options.strip,
85947754
8595 .llvm = undefined,
8596
8597 .source_filename = .none,7755 .source_filename = .none,
8598 .data_layout = .none,7756 .data_layout = .none,
8599 .target_triple = .none,7757 .target_triple = .none,
...@@ -8638,70 +7796,26 @@ pub fn init(options: Options) InitError!Builder {...@@ -8638,70 +7796,26 @@ pub fn init(options: Options) InitError!Builder {
8638 .metadata_forward_references = .{},7796 .metadata_forward_references = .{},
8639 .metadata_named = .{},7797 .metadata_named = .{},
8640 };7798 };
8641 if (self.useLibLlvm()) self.llvm = .{
8642 .context = llvm.Context.create(),
8643 .module = null,
8644 .target = null,
8645 .di_builder = null,
8646 .di_compile_unit = null,
8647 .attribute_kind_ids = null,
8648 .attributes = .{},
8649 .types = .{},
8650 .globals = .{},
8651 .constants = .{},
8652 .replacements = .{},
8653 };
8654 errdefer self.deinit();7799 errdefer self.deinit();
86557800
8656 try self.string_indices.append(self.gpa, 0);7801 try self.string_indices.append(self.gpa, 0);
8657 assert(try self.string("") == .empty);7802 assert(try self.string("") == .empty);
86587803
8659 if (options.name.len > 0) self.source_filename = try self.string(options.name);7804 if (options.name.len > 0) self.source_filename = try self.string(options.name);
8660 if (self.useLibLlvm()) {
8661 initializeLLVMTarget(options.target.cpu.arch);
8662 self.llvm.module = llvm.Module.createWithName(
8663 (self.source_filename.slice(&self) orelse ""),
8664 self.llvm.context,
8665 );
8666 }
86677805
8668 if (options.triple.len > 0) {7806 if (options.triple.len > 0) {
8669 self.target_triple = try self.string(options.triple);7807 self.target_triple = try self.string(options.triple);
8670
8671 if (self.useLibLlvm()) {
8672 var error_message: [*:0]const u8 = undefined;
8673 var target: *llvm.Target = undefined;
8674 if (llvm.Target.getFromTriple(
8675 self.target_triple.slice(&self).?,
8676 &target,
8677 &error_message,
8678 ).toBool()) {
8679 defer llvm.disposeMessage(error_message);
8680
8681 log.err("LLVM failed to parse '{s}': {s}", .{
8682 self.target_triple.slice(&self).?,
8683 error_message,
8684 });
8685 return InitError.InvalidLlvmTriple;
8686 }
8687 self.llvm.target = target;
8688 self.llvm.module.?.setTarget(self.target_triple.slice(&self).?);
8689 }
8690 }7808 }
86917809
8692 {7810 {
8693 const static_len = @typeInfo(Type).Enum.fields.len - 1;7811 const static_len = @typeInfo(Type).Enum.fields.len - 1;
8694 try self.type_map.ensureTotalCapacity(self.gpa, static_len);7812 try self.type_map.ensureTotalCapacity(self.gpa, static_len);
8695 try self.type_items.ensureTotalCapacity(self.gpa, static_len);7813 try self.type_items.ensureTotalCapacity(self.gpa, static_len);
8696 if (self.useLibLlvm()) try self.llvm.types.ensureTotalCapacity(self.gpa, static_len);
8697 inline for (@typeInfo(Type.Simple).Enum.fields) |simple_field| {7814 inline for (@typeInfo(Type.Simple).Enum.fields) |simple_field| {
8698 const result = self.getOrPutTypeNoExtraAssumeCapacity(7815 const result = self.getOrPutTypeNoExtraAssumeCapacity(
8699 .{ .tag = .simple, .data = simple_field.value },7816 .{ .tag = .simple, .data = simple_field.value },
8700 );7817 );
8701 assert(result.new and result.type == @field(Type, simple_field.name));7818 assert(result.new and result.type == @field(Type, simple_field.name));
8702 if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
8703 @field(llvm.Context, simple_field.name ++ "Type")(self.llvm.context),
8704 );
8705 }7819 }
8706 inline for (.{ 1, 8, 16, 29, 32, 64, 80, 128 }) |bits|7820 inline for (.{ 1, 8, 16, 29, 32, 64, 80, 128 }) |bits|
8707 assert(self.intTypeAssumeCapacity(bits) ==7821 assert(self.intTypeAssumeCapacity(bits) ==
...@@ -8714,10 +7828,6 @@ pub fn init(options: Options) InitError!Builder {...@@ -8714,10 +7828,6 @@ pub fn init(options: Options) InitError!Builder {
8714 }7828 }
87157829
8716 {7830 {
8717 if (self.useLibLlvm()) {
8718 self.llvm.attribute_kind_ids = try self.gpa.create([Attribute.Kind.len]c_uint);
8719 @memset(self.llvm.attribute_kind_ids.?, 0);
8720 }
8721 try self.attributes_indices.append(self.gpa, 0);7831 try self.attributes_indices.append(self.gpa, 0);
8722 assert(try self.attrs(&.{}) == .none);7832 assert(try self.attrs(&.{}) == .none);
8723 assert(try self.fnAttrs(&.{}) == .none);7833 assert(try self.fnAttrs(&.{}) == .none);
...@@ -8732,20 +7842,6 @@ pub fn init(options: Options) InitError!Builder {...@@ -8732,20 +7842,6 @@ pub fn init(options: Options) InitError!Builder {
8732}7842}
87337843
8734pub fn deinit(self: *Builder) void {7844pub fn deinit(self: *Builder) void {
8735 if (self.useLibLlvm()) {
8736 var replacement_it = self.llvm.replacements.keyIterator();
8737 while (replacement_it.next()) |replacement| replacement.*.deleteGlobalValue();
8738 self.llvm.replacements.deinit(self.gpa);
8739 self.llvm.constants.deinit(self.gpa);
8740 self.llvm.globals.deinit(self.gpa);
8741 self.llvm.types.deinit(self.gpa);
8742 self.llvm.attributes.deinit(self.gpa);
8743 if (self.llvm.attribute_kind_ids) |attribute_kind_ids| self.gpa.destroy(attribute_kind_ids);
8744 if (self.llvm.di_builder) |di_builder| di_builder.dispose();
8745 if (self.llvm.module) |module| module.dispose();
8746 self.llvm.context.dispose();
8747 }
8748
8749 self.module_asm.deinit(self.gpa);7845 self.module_asm.deinit(self.gpa);
87507846
8751 self.string_map.deinit(self.gpa);7847 self.string_map.deinit(self.gpa);
...@@ -8788,198 +7884,6 @@ pub fn deinit(self: *Builder) void {...@@ -8788,198 +7884,6 @@ pub fn deinit(self: *Builder) void {
8788 self.* = undefined;7884 self.* = undefined;
8789}7885}
87907886
8791pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
8792 switch (arch) {
8793 .aarch64, .aarch64_be, .aarch64_32 => {
8794 llvm.LLVMInitializeAArch64Target();
8795 llvm.LLVMInitializeAArch64TargetInfo();
8796 llvm.LLVMInitializeAArch64TargetMC();
8797 llvm.LLVMInitializeAArch64AsmPrinter();
8798 llvm.LLVMInitializeAArch64AsmParser();
8799 },
8800 .amdgcn => {
8801 llvm.LLVMInitializeAMDGPUTarget();
8802 llvm.LLVMInitializeAMDGPUTargetInfo();
8803 llvm.LLVMInitializeAMDGPUTargetMC();
8804 llvm.LLVMInitializeAMDGPUAsmPrinter();
8805 llvm.LLVMInitializeAMDGPUAsmParser();
8806 },
8807 .thumb, .thumbeb, .arm, .armeb => {
8808 llvm.LLVMInitializeARMTarget();
8809 llvm.LLVMInitializeARMTargetInfo();
8810 llvm.LLVMInitializeARMTargetMC();
8811 llvm.LLVMInitializeARMAsmPrinter();
8812 llvm.LLVMInitializeARMAsmParser();
8813 },
8814 .avr => {
8815 llvm.LLVMInitializeAVRTarget();
8816 llvm.LLVMInitializeAVRTargetInfo();
8817 llvm.LLVMInitializeAVRTargetMC();
8818 llvm.LLVMInitializeAVRAsmPrinter();
8819 llvm.LLVMInitializeAVRAsmParser();
8820 },
8821 .bpfel, .bpfeb => {
8822 llvm.LLVMInitializeBPFTarget();
8823 llvm.LLVMInitializeBPFTargetInfo();
8824 llvm.LLVMInitializeBPFTargetMC();
8825 llvm.LLVMInitializeBPFAsmPrinter();
8826 llvm.LLVMInitializeBPFAsmParser();
8827 },
8828 .hexagon => {
8829 llvm.LLVMInitializeHexagonTarget();
8830 llvm.LLVMInitializeHexagonTargetInfo();
8831 llvm.LLVMInitializeHexagonTargetMC();
8832 llvm.LLVMInitializeHexagonAsmPrinter();
8833 llvm.LLVMInitializeHexagonAsmParser();
8834 },
8835 .lanai => {
8836 llvm.LLVMInitializeLanaiTarget();
8837 llvm.LLVMInitializeLanaiTargetInfo();
8838 llvm.LLVMInitializeLanaiTargetMC();
8839 llvm.LLVMInitializeLanaiAsmPrinter();
8840 llvm.LLVMInitializeLanaiAsmParser();
8841 },
8842 .mips, .mipsel, .mips64, .mips64el => {
8843 llvm.LLVMInitializeMipsTarget();
8844 llvm.LLVMInitializeMipsTargetInfo();
8845 llvm.LLVMInitializeMipsTargetMC();
8846 llvm.LLVMInitializeMipsAsmPrinter();
8847 llvm.LLVMInitializeMipsAsmParser();
8848 },
8849 .msp430 => {
8850 llvm.LLVMInitializeMSP430Target();
8851 llvm.LLVMInitializeMSP430TargetInfo();
8852 llvm.LLVMInitializeMSP430TargetMC();
8853 llvm.LLVMInitializeMSP430AsmPrinter();
8854 llvm.LLVMInitializeMSP430AsmParser();
8855 },
8856 .nvptx, .nvptx64 => {
8857 llvm.LLVMInitializeNVPTXTarget();
8858 llvm.LLVMInitializeNVPTXTargetInfo();
8859 llvm.LLVMInitializeNVPTXTargetMC();
8860 llvm.LLVMInitializeNVPTXAsmPrinter();
8861 // There is no LLVMInitializeNVPTXAsmParser function available.
8862 },
8863 .powerpc, .powerpcle, .powerpc64, .powerpc64le => {
8864 llvm.LLVMInitializePowerPCTarget();
8865 llvm.LLVMInitializePowerPCTargetInfo();
8866 llvm.LLVMInitializePowerPCTargetMC();
8867 llvm.LLVMInitializePowerPCAsmPrinter();
8868 llvm.LLVMInitializePowerPCAsmParser();
8869 },
8870 .riscv32, .riscv64 => {
8871 llvm.LLVMInitializeRISCVTarget();
8872 llvm.LLVMInitializeRISCVTargetInfo();
8873 llvm.LLVMInitializeRISCVTargetMC();
8874 llvm.LLVMInitializeRISCVAsmPrinter();
8875 llvm.LLVMInitializeRISCVAsmParser();
8876 },
8877 .sparc, .sparc64, .sparcel => {
8878 llvm.LLVMInitializeSparcTarget();
8879 llvm.LLVMInitializeSparcTargetInfo();
8880 llvm.LLVMInitializeSparcTargetMC();
8881 llvm.LLVMInitializeSparcAsmPrinter();
8882 llvm.LLVMInitializeSparcAsmParser();
8883 },
8884 .s390x => {
8885 llvm.LLVMInitializeSystemZTarget();
8886 llvm.LLVMInitializeSystemZTargetInfo();
8887 llvm.LLVMInitializeSystemZTargetMC();
8888 llvm.LLVMInitializeSystemZAsmPrinter();
8889 llvm.LLVMInitializeSystemZAsmParser();
8890 },
8891 .wasm32, .wasm64 => {
8892 llvm.LLVMInitializeWebAssemblyTarget();
8893 llvm.LLVMInitializeWebAssemblyTargetInfo();
8894 llvm.LLVMInitializeWebAssemblyTargetMC();
8895 llvm.LLVMInitializeWebAssemblyAsmPrinter();
8896 llvm.LLVMInitializeWebAssemblyAsmParser();
8897 },
8898 .x86, .x86_64 => {
8899 llvm.LLVMInitializeX86Target();
8900 llvm.LLVMInitializeX86TargetInfo();
8901 llvm.LLVMInitializeX86TargetMC();
8902 llvm.LLVMInitializeX86AsmPrinter();
8903 llvm.LLVMInitializeX86AsmParser();
8904 },
8905 .xtensa => {
8906 if (build_options.llvm_has_xtensa) {
8907 llvm.LLVMInitializeXtensaTarget();
8908 llvm.LLVMInitializeXtensaTargetInfo();
8909 llvm.LLVMInitializeXtensaTargetMC();
8910 // There is no LLVMInitializeXtensaAsmPrinter function.
8911 llvm.LLVMInitializeXtensaAsmParser();
8912 }
8913 },
8914 .xcore => {
8915 llvm.LLVMInitializeXCoreTarget();
8916 llvm.LLVMInitializeXCoreTargetInfo();
8917 llvm.LLVMInitializeXCoreTargetMC();
8918 llvm.LLVMInitializeXCoreAsmPrinter();
8919 // There is no LLVMInitializeXCoreAsmParser function.
8920 },
8921 .m68k => {
8922 if (build_options.llvm_has_m68k) {
8923 llvm.LLVMInitializeM68kTarget();
8924 llvm.LLVMInitializeM68kTargetInfo();
8925 llvm.LLVMInitializeM68kTargetMC();
8926 llvm.LLVMInitializeM68kAsmPrinter();
8927 llvm.LLVMInitializeM68kAsmParser();
8928 }
8929 },
8930 .csky => {
8931 if (build_options.llvm_has_csky) {
8932 llvm.LLVMInitializeCSKYTarget();
8933 llvm.LLVMInitializeCSKYTargetInfo();
8934 llvm.LLVMInitializeCSKYTargetMC();
8935 // There is no LLVMInitializeCSKYAsmPrinter function.
8936 llvm.LLVMInitializeCSKYAsmParser();
8937 }
8938 },
8939 .ve => {
8940 llvm.LLVMInitializeVETarget();
8941 llvm.LLVMInitializeVETargetInfo();
8942 llvm.LLVMInitializeVETargetMC();
8943 llvm.LLVMInitializeVEAsmPrinter();
8944 llvm.LLVMInitializeVEAsmParser();
8945 },
8946 .arc => {
8947 if (build_options.llvm_has_arc) {
8948 llvm.LLVMInitializeARCTarget();
8949 llvm.LLVMInitializeARCTargetInfo();
8950 llvm.LLVMInitializeARCTargetMC();
8951 llvm.LLVMInitializeARCAsmPrinter();
8952 // There is no LLVMInitializeARCAsmParser function.
8953 }
8954 },
8955
8956 // LLVM backends that have no initialization functions.
8957 .tce,
8958 .tcele,
8959 .r600,
8960 .le32,
8961 .le64,
8962 .amdil,
8963 .amdil64,
8964 .hsail,
8965 .hsail64,
8966 .shave,
8967 .spir,
8968 .spir64,
8969 .kalimba,
8970 .renderscript32,
8971 .renderscript64,
8972 .dxil,
8973 .loongarch32,
8974 .loongarch64,
8975 => {},
8976
8977 .spu_2 => unreachable, // LLVM does not support this backend
8978 .spirv32 => unreachable, // LLVM does not support this backend
8979 .spirv64 => unreachable, // LLVM does not support this backend
8980 }
8981}
8982
8983pub fn setModuleAsm(self: *Builder) std.ArrayListUnmanaged(u8).Writer {7887pub fn setModuleAsm(self: *Builder) std.ArrayListUnmanaged(u8).Writer {
8984 self.module_asm.clearRetainingCapacity();7888 self.module_asm.clearRetainingCapacity();
8985 return self.appendModuleAsm();7889 return self.appendModuleAsm();
...@@ -8992,8 +7896,6 @@ pub fn appendModuleAsm(self: *Builder) std.ArrayListUnmanaged(u8).Writer {...@@ -8992,8 +7896,6 @@ pub fn appendModuleAsm(self: *Builder) std.ArrayListUnmanaged(u8).Writer {
8992pub fn finishModuleAsm(self: *Builder) Allocator.Error!void {7896pub fn finishModuleAsm(self: *Builder) Allocator.Error!void {
8993 if (self.module_asm.getLastOrNull()) |last| if (last != '\n')7897 if (self.module_asm.getLastOrNull()) |last| if (last != '\n')
8994 try self.module_asm.append(self.gpa, '\n');7898 try self.module_asm.append(self.gpa, '\n');
8995 if (self.useLibLlvm())
8996 self.llvm.module.?.setModuleInlineAsm(self.module_asm.items.ptr, self.module_asm.items.len);
8997}7899}
89987900
8999pub fn string(self: *Builder, bytes: []const u8) Allocator.Error!String {7901pub fn string(self: *Builder, bytes: []const u8) Allocator.Error!String {
...@@ -9109,94 +8011,13 @@ pub fn namedTypeSetBody(...@@ -9109,94 +8011,13 @@ pub fn namedTypeSetBody(
9109 const named_item = self.type_items.items[@intFromEnum(named_type)];8011 const named_item = self.type_items.items[@intFromEnum(named_type)];
9110 self.type_extra.items[named_item.data + std.meta.fieldIndex(Type.NamedStructure, "body").?] =8012 self.type_extra.items[named_item.data + std.meta.fieldIndex(Type.NamedStructure, "body").?] =
9111 @intFromEnum(body_type);8013 @intFromEnum(body_type);
9112 if (self.useLibLlvm()) {
9113 const body_item = self.type_items.items[@intFromEnum(body_type)];
9114 var body_extra = self.typeExtraDataTrail(Type.Structure, body_item.data);
9115 const body_fields = body_extra.trail.next(body_extra.data.fields_len, Type, self);
9116 const llvm_fields = try self.gpa.alloc(*llvm.Type, body_fields.len);
9117 defer self.gpa.free(llvm_fields);
9118 for (llvm_fields, body_fields) |*llvm_field, body_field| llvm_field.* = body_field.toLlvm(self);
9119 self.llvm.types.items[@intFromEnum(named_type)].structSetBody(
9120 llvm_fields.ptr,
9121 @intCast(llvm_fields.len),
9122 switch (body_item.tag) {
9123 .structure => .False,
9124 .packed_structure => .True,
9125 else => unreachable,
9126 },
9127 );
9128 }
9129}8014}
91308015
9131pub fn attr(self: *Builder, attribute: Attribute) Allocator.Error!Attribute.Index {8016pub fn attr(self: *Builder, attribute: Attribute) Allocator.Error!Attribute.Index {
9132 try self.attributes.ensureUnusedCapacity(self.gpa, 1);8017 try self.attributes.ensureUnusedCapacity(self.gpa, 1);
9133 if (self.useLibLlvm()) try self.llvm.attributes.ensureUnusedCapacity(self.gpa, 1);
91348018
9135 const gop = self.attributes.getOrPutAssumeCapacity(attribute.toStorage());8019 const gop = self.attributes.getOrPutAssumeCapacity(attribute.toStorage());
9136 if (!gop.found_existing) {8020 if (!gop.found_existing) gop.value_ptr.* = {};
9137 gop.value_ptr.* = {};
9138 if (self.useLibLlvm()) self.llvm.attributes.appendAssumeCapacity(switch (attribute) {
9139 else => llvm_attr: {
9140 const llvm_kind_id = attribute.getKind().toLlvm(self);
9141 if (llvm_kind_id.* == 0) {
9142 const name = @tagName(attribute);
9143 llvm_kind_id.* = llvm.getEnumAttributeKindForName(name.ptr, name.len);
9144 assert(llvm_kind_id.* != 0);
9145 }
9146 break :llvm_attr switch (attribute) {
9147 else => switch (attribute) {
9148 inline else => |value| self.llvm.context.createEnumAttribute(
9149 llvm_kind_id.*,
9150 switch (@TypeOf(value)) {
9151 void => 0,
9152 u32 => value,
9153 Attribute.FpClass,
9154 Attribute.AllocKind,
9155 Attribute.Memory,
9156 => @as(u32, @bitCast(value)),
9157 Alignment => value.toByteUnits() orelse 0,
9158 Attribute.AllocSize,
9159 Attribute.VScaleRange,
9160 => @bitCast(value.toLlvm()),
9161 Attribute.UwTable => @intFromEnum(value),
9162 else => @compileError(
9163 "bad payload type: " ++ @typeName(@TypeOf(value)),
9164 ),
9165 },
9166 ),
9167 .byval,
9168 .byref,
9169 .preallocated,
9170 .inalloca,
9171 .sret,
9172 .elementtype,
9173 .string,
9174 .none,
9175 => unreachable,
9176 },
9177 .byval,
9178 .byref,
9179 .preallocated,
9180 .inalloca,
9181 .sret,
9182 .elementtype,
9183 => |ty| self.llvm.context.createTypeAttribute(llvm_kind_id.*, ty.toLlvm(self)),
9184 .string, .none => unreachable,
9185 };
9186 },
9187 .string => |string_attr| llvm_attr: {
9188 const kind = string_attr.kind.slice(self).?;
9189 const value = string_attr.value.slice(self).?;
9190 break :llvm_attr self.llvm.context.createStringAttribute(
9191 kind.ptr,
9192 @intCast(kind.len),
9193 value.ptr,
9194 @intCast(value.len),
9195 );
9196 },
9197 .none => unreachable,
9198 });
9199 }
9200 return @enumFromInt(gop.index);8021 return @enumFromInt(gop.index);
9201}8022}
92028023
...@@ -9246,7 +8067,6 @@ pub fn addGlobalAssumeCapacity(self: *Builder, name: String, global: Global) Glo...@@ -9246,7 +8067,6 @@ pub fn addGlobalAssumeCapacity(self: *Builder, name: String, global: Global) Glo
9246 global_gop.value_ptr.* = global;8067 global_gop.value_ptr.* = global;
9247 const global_index: Global.Index = @enumFromInt(global_gop.index);8068 const global_index: Global.Index = @enumFromInt(global_gop.index);
9248 global_index.updateDsoLocal(self);8069 global_index.updateDsoLocal(self);
9249 global_index.updateName(self);
9250 return global_index;8070 return global_index;
9251 }8071 }
92528072
...@@ -9282,12 +8102,6 @@ pub fn addAliasAssumeCapacity(...@@ -9282,12 +8102,6 @@ pub fn addAliasAssumeCapacity(
9282 addr_space: AddrSpace,8102 addr_space: AddrSpace,
9283 aliasee: Constant,8103 aliasee: Constant,
9284) Alias.Index {8104) Alias.Index {
9285 if (self.useLibLlvm()) self.llvm.globals.appendAssumeCapacity(self.llvm.module.?.addAlias(
9286 ty.toLlvm(self),
9287 @intFromEnum(addr_space),
9288 aliasee.toLlvm(self),
9289 name.slice(self).?,
9290 ));
9291 const alias_index: Alias.Index = @enumFromInt(self.aliases.items.len);8105 const alias_index: Alias.Index = @enumFromInt(self.aliases.items.len);
9292 self.aliases.appendAssumeCapacity(.{ .global = self.addGlobalAssumeCapacity(name, .{8106 self.aliases.appendAssumeCapacity(.{ .global = self.addGlobalAssumeCapacity(name, .{
9293 .addr_space = addr_space,8107 .addr_space = addr_space,
...@@ -9316,13 +8130,6 @@ pub fn addVariableAssumeCapacity(...@@ -9316,13 +8130,6 @@ pub fn addVariableAssumeCapacity(
9316 name: String,8130 name: String,
9317 addr_space: AddrSpace,8131 addr_space: AddrSpace,
9318) Variable.Index {8132) Variable.Index {
9319 if (self.useLibLlvm()) self.llvm.globals.appendAssumeCapacity(
9320 self.llvm.module.?.addGlobalInAddressSpace(
9321 ty.toLlvm(self),
9322 name.slice(self).?,
9323 @intFromEnum(addr_space),
9324 ),
9325 );
9326 const variable_index: Variable.Index = @enumFromInt(self.variables.items.len);8133 const variable_index: Variable.Index = @enumFromInt(self.variables.items.len);
9327 self.variables.appendAssumeCapacity(.{ .global = self.addGlobalAssumeCapacity(name, .{8134 self.variables.appendAssumeCapacity(.{ .global = self.addGlobalAssumeCapacity(name, .{
9328 .addr_space = addr_space,8135 .addr_space = addr_space,
...@@ -9352,13 +8159,6 @@ pub fn addFunctionAssumeCapacity(...@@ -9352,13 +8159,6 @@ pub fn addFunctionAssumeCapacity(
9352 addr_space: AddrSpace,8159 addr_space: AddrSpace,
9353) Function.Index {8160) Function.Index {
9354 assert(ty.isFunction(self));8161 assert(ty.isFunction(self));
9355 if (self.useLibLlvm()) self.llvm.globals.appendAssumeCapacity(
9356 self.llvm.module.?.addFunctionInAddressSpace(
9357 name.slice(self).?,
9358 ty.toLlvm(self),
9359 @intFromEnum(addr_space),
9360 ),
9361 );
9362 const function_index: Function.Index = @enumFromInt(self.functions.items.len);8162 const function_index: Function.Index = @enumFromInt(self.functions.items.len);
9363 self.functions.appendAssumeCapacity(.{ .global = self.addGlobalAssumeCapacity(name, .{8163 self.functions.appendAssumeCapacity(.{ .global = self.addGlobalAssumeCapacity(name, .{
9364 .addr_space = addr_space,8164 .addr_space = addr_space,
...@@ -9486,7 +8286,6 @@ pub fn bigIntConst(self: *Builder, ty: Type, value: std.math.big.int.Const) Allo...@@ -9486,7 +8286,6 @@ pub fn bigIntConst(self: *Builder, ty: Type, value: std.math.big.int.Const) Allo
9486 try self.constant_map.ensureUnusedCapacity(self.gpa, 1);8286 try self.constant_map.ensureUnusedCapacity(self.gpa, 1);
9487 try self.constant_items.ensureUnusedCapacity(self.gpa, 1);8287 try self.constant_items.ensureUnusedCapacity(self.gpa, 1);
9488 try self.constant_limbs.ensureUnusedCapacity(self.gpa, Constant.Integer.limbs + value.limbs.len);8288 try self.constant_limbs.ensureUnusedCapacity(self.gpa, Constant.Integer.limbs + value.limbs.len);
9489 if (self.useLibLlvm()) try self.llvm.constants.ensureUnusedCapacity(self.gpa, 1);
9490 return self.bigIntConstAssumeCapacity(ty, value);8289 return self.bigIntConstAssumeCapacity(ty, value);
9491}8290}
94928291
...@@ -9904,72 +8703,20 @@ pub fn asmValue(...@@ -9904,72 +8703,20 @@ pub fn asmValue(
9904 return (try self.asmConst(ty, info, assembly, constraints)).toValue();8703 return (try self.asmConst(ty, info, assembly, constraints)).toValue();
9905}8704}
99068705
9907pub fn verify(self: *Builder) error{}!bool {
9908 if (self.useLibLlvm()) {
9909 var error_message: [*:0]const u8 = undefined;
9910 // verifyModule always allocs the error_message even if there is no error
9911 defer llvm.disposeMessage(error_message);
9912
9913 if (self.llvm.module.?.verify(.ReturnStatus, &error_message).toBool()) {
9914 log.err("failed verification of LLVM module:\n{s}\n", .{error_message});
9915 return false;
9916 }
9917 }
9918 return true;
9919}
9920
9921pub fn writeBitcodeToFile(self: *Builder, path: []const u8) Allocator.Error!bool {
9922 const path_z = try self.gpa.dupeZ(u8, path);
9923 defer self.gpa.free(path_z);
9924 return self.writeBitcodeToFileZ(path_z);
9925}
9926
9927pub fn writeBitcodeToFileZ(self: *Builder, path: [*:0]const u8) bool {
9928 if (self.useLibLlvm()) {
9929 const error_code = self.llvm.module.?.writeBitcodeToFile(path);
9930 if (error_code != 0) {
9931 log.err("failed dumping LLVM module to \"{s}\": {d}", .{ path, error_code });
9932 return false;
9933 }
9934 } else {
9935 log.err("writing bitcode without libllvm not implemented", .{});
9936 return false;
9937 }
9938 return true;
9939}
9940
9941pub fn dump(self: *Builder) void {8706pub fn dump(self: *Builder) void {
9942 if (self.useLibLlvm())8707 self.print(std.io.getStdErr().writer()) catch {};
9943 self.llvm.module.?.dump()
9944 else
9945 self.print(std.io.getStdErr().writer()) catch {};
9946}8708}
99478709
9948pub fn printToFile(self: *Builder, path: []const u8) Allocator.Error!bool {8710pub fn printToFile(self: *Builder, path: []const u8) Allocator.Error!bool {
9949 const path_z = try self.gpa.dupeZ(u8, path);8711 var file = std.fs.cwd().createFile(path, .{}) catch |err| {
9950 defer self.gpa.free(path_z);8712 log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) });
9951 return self.printToFileZ(path_z);8713 return false;
9952}8714 };
99538715 defer file.close();
9954pub fn printToFileZ(self: *Builder, path: [*:0]const u8) bool {8716 self.print(file.writer()) catch |err| {
9955 if (self.useLibLlvm()) {8717 log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) });
9956 var error_message: [*:0]const u8 = undefined;8718 return false;
9957 if (self.llvm.module.?.printModuleToFile(path, &error_message).toBool()) {8719 };
9958 defer llvm.disposeMessage(error_message);
9959 log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, error_message });
9960 return false;
9961 }
9962 } else {
9963 var file = std.fs.cwd().createFileZ(path, .{}) catch |err| {
9964 log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) });
9965 return false;
9966 };
9967 defer file.close();
9968 self.print(file.writer()) catch |err| {
9969 log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) });
9970 return false;
9971 };
9972 }
9973 return true;8720 return true;
9974}8721}
99758722
...@@ -10579,10 +9326,6 @@ pub fn printUnbuffered(...@@ -10579,10 +9326,6 @@ pub fn printUnbuffered(
10579 }9326 }
10580}9327}
105819328
10582pub inline fn useLibLlvm(self: *const Builder) bool {
10583 return build_options.have_llvm and self.use_lib_llvm;
10584}
10585
10586const NoExtra = struct {};9329const NoExtra = struct {};
105879330
10588fn isValidIdentifier(id: []const u8) bool {9331fn isValidIdentifier(id: []const u8) bool {
...@@ -10614,7 +9357,6 @@ fn printEscapedString(...@@ -10614,7 +9357,6 @@ fn printEscapedString(
10614}9357}
106159358
10616fn ensureUnusedGlobalCapacity(self: *Builder, name: String) Allocator.Error!void {9359fn ensureUnusedGlobalCapacity(self: *Builder, name: String) Allocator.Error!void {
10617 if (self.useLibLlvm()) try self.llvm.globals.ensureUnusedCapacity(self.gpa, 1);
10618 try self.string_map.ensureUnusedCapacity(self.gpa, 1);9360 try self.string_map.ensureUnusedCapacity(self.gpa, 1);
10619 if (name.slice(self)) |id| {9361 if (name.slice(self)) |id| {
10620 const count: usize = comptime std.fmt.count("{d}" ++ .{0}, .{std.math.maxInt(u32)});9362 const count: usize = comptime std.fmt.count("{d}" ++ .{0}, .{std.math.maxInt(u32)});
...@@ -10667,20 +9409,6 @@ fn fnTypeAssumeCapacity(...@@ -10667,20 +9409,6 @@ fn fnTypeAssumeCapacity(
10667 }),9409 }),
10668 });9410 });
10669 self.type_extra.appendSliceAssumeCapacity(@ptrCast(params));9411 self.type_extra.appendSliceAssumeCapacity(@ptrCast(params));
10670 if (self.useLibLlvm()) {
10671 const llvm_params = try self.gpa.alloc(*llvm.Type, params.len);
10672 defer self.gpa.free(llvm_params);
10673 for (llvm_params, params) |*llvm_param, param| llvm_param.* = param.toLlvm(self);
10674 self.llvm.types.appendAssumeCapacity(llvm.functionType(
10675 ret.toLlvm(self),
10676 llvm_params.ptr,
10677 @intCast(llvm_params.len),
10678 switch (kind) {
10679 .normal => .False,
10680 .vararg => .True,
10681 },
10682 ));
10683 }
10684 }9412 }
10685 return @enumFromInt(gop.index);9413 return @enumFromInt(gop.index);
10686}9414}
...@@ -10688,8 +9416,6 @@ fn fnTypeAssumeCapacity(...@@ -10688,8 +9416,6 @@ fn fnTypeAssumeCapacity(
10688fn intTypeAssumeCapacity(self: *Builder, bits: u24) Type {9416fn intTypeAssumeCapacity(self: *Builder, bits: u24) Type {
10689 assert(bits > 0);9417 assert(bits > 0);
10690 const result = self.getOrPutTypeNoExtraAssumeCapacity(.{ .tag = .integer, .data = bits });9418 const result = self.getOrPutTypeNoExtraAssumeCapacity(.{ .tag = .integer, .data = bits });
10691 if (self.useLibLlvm() and result.new)
10692 self.llvm.types.appendAssumeCapacity(self.llvm.context.intType(bits));
10693 return result.type;9419 return result.type;
10694}9420}
106959421
...@@ -10697,8 +9423,6 @@ fn ptrTypeAssumeCapacity(self: *Builder, addr_space: AddrSpace) Type {...@@ -10697,8 +9423,6 @@ fn ptrTypeAssumeCapacity(self: *Builder, addr_space: AddrSpace) Type {
10697 const result = self.getOrPutTypeNoExtraAssumeCapacity(9423 const result = self.getOrPutTypeNoExtraAssumeCapacity(
10698 .{ .tag = .pointer, .data = @intFromEnum(addr_space) },9424 .{ .tag = .pointer, .data = @intFromEnum(addr_space) },
10699 );9425 );
10700 if (self.useLibLlvm() and result.new)
10701 self.llvm.types.appendAssumeCapacity(self.llvm.context.pointerType(@intFromEnum(addr_space)));
10702 return result.type;9426 return result.type;
10703}9427}
107049428
...@@ -10736,10 +9460,6 @@ fn vectorTypeAssumeCapacity(...@@ -10736,10 +9460,6 @@ fn vectorTypeAssumeCapacity(
10736 .tag = tag,9460 .tag = tag,
10737 .data = self.addTypeExtraAssumeCapacity(data),9461 .data = self.addTypeExtraAssumeCapacity(data),
10738 });9462 });
10739 if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(switch (kind) {
10740 .normal => &llvm.Type.vectorType,
10741 .scalable => &llvm.Type.scalableVectorType,
10742 }(child.toLlvm(self), @intCast(len)));
10743 }9463 }
10744 return @enumFromInt(gop.index);9464 return @enumFromInt(gop.index);
10745}9465}
...@@ -10769,9 +9489,6 @@ fn arrayTypeAssumeCapacity(self: *Builder, len: u64, child: Type) Type {...@@ -10769,9 +9489,6 @@ fn arrayTypeAssumeCapacity(self: *Builder, len: u64, child: Type) Type {
10769 .tag = .small_array,9489 .tag = .small_array,
10770 .data = self.addTypeExtraAssumeCapacity(data),9490 .data = self.addTypeExtraAssumeCapacity(data),
10771 });9491 });
10772 if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
10773 child.toLlvm(self).arrayType2(len),
10774 );
10775 }9492 }
10776 return @enumFromInt(gop.index);9493 return @enumFromInt(gop.index);
10777 } else {9494 } else {
...@@ -10802,9 +9519,6 @@ fn arrayTypeAssumeCapacity(self: *Builder, len: u64, child: Type) Type {...@@ -10802,9 +9519,6 @@ fn arrayTypeAssumeCapacity(self: *Builder, len: u64, child: Type) Type {
10802 .tag = .array,9519 .tag = .array,
10803 .data = self.addTypeExtraAssumeCapacity(data),9520 .data = self.addTypeExtraAssumeCapacity(data),
10804 });9521 });
10805 if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
10806 child.toLlvm(self).arrayType2(len),
10807 );
10808 }9522 }
10809 return @enumFromInt(gop.index);9523 return @enumFromInt(gop.index);
10810 }9524 }
...@@ -10846,25 +9560,6 @@ fn structTypeAssumeCapacity(...@@ -10846,25 +9560,6 @@ fn structTypeAssumeCapacity(
10846 }),9560 }),
10847 });9561 });
10848 self.type_extra.appendSliceAssumeCapacity(@ptrCast(fields));9562 self.type_extra.appendSliceAssumeCapacity(@ptrCast(fields));
10849 if (self.useLibLlvm()) {
10850 const ExpectedContents = [expected_fields_len]*llvm.Type;
10851 var stack align(@alignOf(ExpectedContents)) =
10852 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
10853 const allocator = stack.get();
10854
10855 const llvm_fields = try allocator.alloc(*llvm.Type, fields.len);
10856 defer allocator.free(llvm_fields);
10857 for (llvm_fields, fields) |*llvm_field, field| llvm_field.* = field.toLlvm(self);
10858
10859 self.llvm.types.appendAssumeCapacity(self.llvm.context.structType(
10860 llvm_fields.ptr,
10861 @intCast(llvm_fields.len),
10862 switch (kind) {
10863 .normal => .False,
10864 .@"packed" => .True,
10865 },
10866 ));
10867 }
10868 }9563 }
10869 return @enumFromInt(gop.index);9564 return @enumFromInt(gop.index);
10870}9565}
...@@ -10906,9 +9601,6 @@ fn opaqueTypeAssumeCapacity(self: *Builder, name: String) Type {...@@ -10906,9 +9601,6 @@ fn opaqueTypeAssumeCapacity(self: *Builder, name: String) Type {
10906 });9601 });
10907 const result: Type = @enumFromInt(gop.index);9602 const result: Type = @enumFromInt(gop.index);
10908 type_gop.value_ptr.* = result;9603 type_gop.value_ptr.* = result;
10909 if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
10910 self.llvm.context.structCreateNamed(id.slice(self) orelse ""),
10911 );
10912 return result;9604 return result;
10913 }9605 }
109149606
...@@ -10931,7 +9623,6 @@ fn ensureUnusedTypeCapacity(...@@ -10931,7 +9623,6 @@ fn ensureUnusedTypeCapacity(
10931 self.gpa,9623 self.gpa,
10932 count * (@typeInfo(Extra).Struct.fields.len + trail_len),9624 count * (@typeInfo(Extra).Struct.fields.len + trail_len),
10933 );9625 );
10934 if (self.useLibLlvm()) try self.llvm.types.ensureUnusedCapacity(self.gpa, count);
10935}9626}
109369627
10937fn getOrPutTypeNoExtraAssumeCapacity(self: *Builder, item: Type.Item) struct { new: bool, type: Type } {9628fn getOrPutTypeNoExtraAssumeCapacity(self: *Builder, item: Type.Item) struct { new: bool, type: Type } {
...@@ -11108,44 +9799,6 @@ fn bigIntConstAssumeCapacity(...@@ -11108,44 +9799,6 @@ fn bigIntConstAssumeCapacity(
11108 @ptrCast(self.constant_limbs.addManyAsArrayAssumeCapacity(Constant.Integer.limbs));9799 @ptrCast(self.constant_limbs.addManyAsArrayAssumeCapacity(Constant.Integer.limbs));
11109 extra.* = .{ .type = ty, .limbs_len = @intCast(canonical_value.limbs.len) };9800 extra.* = .{ .type = ty, .limbs_len = @intCast(canonical_value.limbs.len) };
11110 self.constant_limbs.appendSliceAssumeCapacity(canonical_value.limbs);9801 self.constant_limbs.appendSliceAssumeCapacity(canonical_value.limbs);
11111 if (self.useLibLlvm()) {
11112 const llvm_type = ty.toLlvm(self);
11113 if (canonical_value.to(c_longlong)) |small| {
11114 self.llvm.constants.appendAssumeCapacity(llvm_type.constInt(@bitCast(small), .True));
11115 } else |_| if (canonical_value.to(c_ulonglong)) |small| {
11116 self.llvm.constants.appendAssumeCapacity(llvm_type.constInt(small, .False));
11117 } else |_| {
11118 const llvm_limbs = try allocator.alloc(u64, std.math.divCeil(
11119 usize,
11120 if (canonical_value.positive) canonical_value.bitCountAbs() else bits,
11121 @bitSizeOf(u64),
11122 ) catch unreachable);
11123 defer allocator.free(llvm_limbs);
11124 var limb_index: usize = 0;
11125 var borrow: std.math.big.Limb = 0;
11126 for (llvm_limbs) |*result_limb| {
11127 var llvm_limb: u64 = 0;
11128 inline for (0..Constant.Integer.limbs) |shift| {
11129 const limb = if (limb_index < canonical_value.limbs.len)
11130 canonical_value.limbs[limb_index]
11131 else
11132 0;
11133 limb_index += 1;
11134 llvm_limb |= @as(u64, limb) << shift * @bitSizeOf(std.math.big.Limb);
11135 }
11136 if (!canonical_value.positive) {
11137 const overflow = @subWithOverflow(borrow, llvm_limb);
11138 llvm_limb = overflow[0];
11139 borrow -%= overflow[1];
11140 assert(borrow == 0 or borrow == std.math.maxInt(std.math.big.Limb));
11141 }
11142 result_limb.* = llvm_limb;
11143 }
11144 self.llvm.constants.appendAssumeCapacity(
11145 llvm_type.constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), llvm_limbs.ptr),
11146 );
11147 }
11148 }
11149 }9802 }
11150 return @enumFromInt(gop.index);9803 return @enumFromInt(gop.index);
11151}9804}
...@@ -11154,13 +9807,6 @@ fn halfConstAssumeCapacity(self: *Builder, val: f16) Constant {...@@ -11154,13 +9807,6 @@ fn halfConstAssumeCapacity(self: *Builder, val: f16) Constant {
11154 const result = self.getOrPutConstantNoExtraAssumeCapacity(9807 const result = self.getOrPutConstantNoExtraAssumeCapacity(
11155 .{ .tag = .half, .data = @as(u16, @bitCast(val)) },9808 .{ .tag = .half, .data = @as(u16, @bitCast(val)) },
11156 );9809 );
11157 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
11158 if (std.math.isSignalNan(val))
11159 Type.i16.toLlvm(self).constInt(@as(u16, @bitCast(val)), .False)
11160 .constBitCast(Type.half.toLlvm(self))
11161 else
11162 Type.half.toLlvm(self).constReal(val),
11163 );
11164 return result.constant;9810 return result.constant;
11165}9811}
111669812
...@@ -11169,16 +9815,6 @@ fn bfloatConstAssumeCapacity(self: *Builder, val: f32) Constant {...@@ -11169,16 +9815,6 @@ fn bfloatConstAssumeCapacity(self: *Builder, val: f32) Constant {
11169 const result = self.getOrPutConstantNoExtraAssumeCapacity(9815 const result = self.getOrPutConstantNoExtraAssumeCapacity(
11170 .{ .tag = .bfloat, .data = @bitCast(val) },9816 .{ .tag = .bfloat, .data = @bitCast(val) },
11171 );9817 );
11172 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
11173 if (std.math.isSignalNan(val))
11174 Type.i16.toLlvm(self).constInt(@as(u32, @bitCast(val)) >> 16, .False)
11175 .constBitCast(Type.bfloat.toLlvm(self))
11176 else
11177 Type.bfloat.toLlvm(self).constReal(val),
11178 );
11179
11180 if (self.useLibLlvm() and result.new)
11181 self.llvm.constants.appendAssumeCapacity(Type.bfloat.toLlvm(self).constReal(val));
11182 return result.constant;9818 return result.constant;
11183}9819}
111849820
...@@ -11186,13 +9822,6 @@ fn floatConstAssumeCapacity(self: *Builder, val: f32) Constant {...@@ -11186,13 +9822,6 @@ fn floatConstAssumeCapacity(self: *Builder, val: f32) Constant {
11186 const result = self.getOrPutConstantNoExtraAssumeCapacity(9822 const result = self.getOrPutConstantNoExtraAssumeCapacity(
11187 .{ .tag = .float, .data = @bitCast(val) },9823 .{ .tag = .float, .data = @bitCast(val) },
11188 );9824 );
11189 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
11190 if (std.math.isSignalNan(val))
11191 Type.i32.toLlvm(self).constInt(@as(u32, @bitCast(val)), .False)
11192 .constBitCast(Type.float.toLlvm(self))
11193 else
11194 Type.float.toLlvm(self).constReal(val),
11195 );
11196 return result.constant;9825 return result.constant;
11197}9826}
111989827
...@@ -11223,13 +9852,6 @@ fn doubleConstAssumeCapacity(self: *Builder, val: f64) Constant {...@@ -11223,13 +9852,6 @@ fn doubleConstAssumeCapacity(self: *Builder, val: f64) Constant {
11223 .hi = @intCast(@as(u64, @bitCast(val)) >> 32),9852 .hi = @intCast(@as(u64, @bitCast(val)) >> 32),
11224 }),9853 }),
11225 });9854 });
11226 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
11227 if (std.math.isSignalNan(val))
11228 Type.i64.toLlvm(self).constInt(@as(u64, @bitCast(val)), .False)
11229 .constBitCast(Type.double.toLlvm(self))
11230 else
11231 Type.double.toLlvm(self).constReal(val),
11232 );
11233 }9855 }
11234 return @enumFromInt(gop.index);9856 return @enumFromInt(gop.index);
11235}9857}
...@@ -11264,17 +9886,6 @@ fn fp128ConstAssumeCapacity(self: *Builder, val: f128) Constant {...@@ -11264,17 +9886,6 @@ fn fp128ConstAssumeCapacity(self: *Builder, val: f128) Constant {
11264 .hi_hi = @intCast(@as(u128, @bitCast(val)) >> 96),9886 .hi_hi = @intCast(@as(u128, @bitCast(val)) >> 96),
11265 }),9887 }),
11266 });9888 });
11267 if (self.useLibLlvm()) {
11268 const llvm_limbs = [_]u64{
11269 @truncate(@as(u128, @bitCast(val))),
11270 @intCast(@as(u128, @bitCast(val)) >> 64),
11271 };
11272 self.llvm.constants.appendAssumeCapacity(
11273 Type.i128.toLlvm(self)
11274 .constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), &llvm_limbs)
11275 .constBitCast(Type.fp128.toLlvm(self)),
11276 );
11277 }
11278 }9889 }
11279 return @enumFromInt(gop.index);9890 return @enumFromInt(gop.index);
11280}9891}
...@@ -11308,17 +9919,6 @@ fn x86_fp80ConstAssumeCapacity(self: *Builder, val: f80) Constant {...@@ -11308,17 +9919,6 @@ fn x86_fp80ConstAssumeCapacity(self: *Builder, val: f80) Constant {
11308 .hi = @intCast(@as(u80, @bitCast(val)) >> 64),9919 .hi = @intCast(@as(u80, @bitCast(val)) >> 64),
11309 }),9920 }),
11310 });9921 });
11311 if (self.useLibLlvm()) {
11312 const llvm_limbs = [_]u64{
11313 @truncate(@as(u80, @bitCast(val))),
11314 @intCast(@as(u80, @bitCast(val)) >> 64),
11315 };
11316 self.llvm.constants.appendAssumeCapacity(
11317 Type.i80.toLlvm(self)
11318 .constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), &llvm_limbs)
11319 .constBitCast(Type.x86_fp80.toLlvm(self)),
11320 );
11321 }
11322 }9922 }
11323 return @enumFromInt(gop.index);9923 return @enumFromInt(gop.index);
11324}9924}
...@@ -11353,14 +9953,6 @@ fn ppc_fp128ConstAssumeCapacity(self: *Builder, val: [2]f64) Constant {...@@ -11353,14 +9953,6 @@ fn ppc_fp128ConstAssumeCapacity(self: *Builder, val: [2]f64) Constant {
11353 .hi_hi = @intCast(@as(u64, @bitCast(val[1])) >> 32),9953 .hi_hi = @intCast(@as(u64, @bitCast(val[1])) >> 32),
11354 }),9954 }),
11355 });9955 });
11356 if (self.useLibLlvm()) {
11357 const llvm_limbs: [2]u64 = @bitCast(val);
11358 self.llvm.constants.appendAssumeCapacity(
11359 Type.i128.toLlvm(self)
11360 .constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), &llvm_limbs)
11361 .constBitCast(Type.ppc_fp128.toLlvm(self)),
11362 );
11363 }
11364 }9956 }
11365 return @enumFromInt(gop.index);9957 return @enumFromInt(gop.index);
11366}9958}
...@@ -11370,8 +9962,6 @@ fn nullConstAssumeCapacity(self: *Builder, ty: Type) Constant {...@@ -11370,8 +9962,6 @@ fn nullConstAssumeCapacity(self: *Builder, ty: Type) Constant {
11370 const result = self.getOrPutConstantNoExtraAssumeCapacity(9962 const result = self.getOrPutConstantNoExtraAssumeCapacity(
11371 .{ .tag = .null, .data = @intFromEnum(ty) },9963 .{ .tag = .null, .data = @intFromEnum(ty) },
11372 );9964 );
11373 if (self.useLibLlvm() and result.new)
11374 self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).constNull());
11375 return result.constant;9965 return result.constant;
11376}9966}
113779967
...@@ -11380,8 +9970,6 @@ fn noneConstAssumeCapacity(self: *Builder, ty: Type) Constant {...@@ -11380,8 +9970,6 @@ fn noneConstAssumeCapacity(self: *Builder, ty: Type) Constant {
11380 const result = self.getOrPutConstantNoExtraAssumeCapacity(9970 const result = self.getOrPutConstantNoExtraAssumeCapacity(
11381 .{ .tag = .none, .data = @intFromEnum(ty) },9971 .{ .tag = .none, .data = @intFromEnum(ty) },
11382 );9972 );
11383 if (self.useLibLlvm() and result.new)
11384 self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).constNull());
11385 return result.constant;9973 return result.constant;
11386}9974}
113879975
...@@ -11416,20 +10004,6 @@ fn structConstAssumeCapacity(...@@ -11416,20 +10004,6 @@ fn structConstAssumeCapacity(
11416 else => unreachable,10004 else => unreachable,
11417 };10005 };
11418 const result = self.getOrPutConstantAggregateAssumeCapacity(tag, ty, vals);10006 const result = self.getOrPutConstantAggregateAssumeCapacity(tag, ty, vals);
11419 if (self.useLibLlvm() and result.new) {
11420 const ExpectedContents = [expected_fields_len]*llvm.Value;
11421 var stack align(@alignOf(ExpectedContents)) =
11422 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
11423 const allocator = stack.get();
11424
11425 const llvm_vals = try allocator.alloc(*llvm.Value, vals.len);
11426 defer allocator.free(llvm_vals);
11427 for (llvm_vals, vals) |*llvm_val, val| llvm_val.* = val.toLlvm(self);
11428
11429 self.llvm.constants.appendAssumeCapacity(
11430 ty.toLlvm(self).constNamedStruct(llvm_vals.ptr, @intCast(llvm_vals.len)),
11431 );
11432 }
11433 return result.constant;10007 return result.constant;
11434}10008}
1143510009
...@@ -11458,20 +10032,6 @@ fn arrayConstAssumeCapacity(...@@ -11458,20 +10032,6 @@ fn arrayConstAssumeCapacity(
11458 } else return self.zeroInitConstAssumeCapacity(ty);10032 } else return self.zeroInitConstAssumeCapacity(ty);
1145910033
11460 const result = self.getOrPutConstantAggregateAssumeCapacity(.array, ty, vals);10034 const result = self.getOrPutConstantAggregateAssumeCapacity(.array, ty, vals);
11461 if (self.useLibLlvm() and result.new) {
11462 const ExpectedContents = [expected_fields_len]*llvm.Value;
11463 var stack align(@alignOf(ExpectedContents)) =
11464 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
11465 const allocator = stack.get();
11466
11467 const llvm_vals = try allocator.alloc(*llvm.Value, vals.len);
11468 defer allocator.free(llvm_vals);
11469 for (llvm_vals, vals) |*llvm_val, val| llvm_val.* = val.toLlvm(self);
11470
11471 self.llvm.constants.appendAssumeCapacity(
11472 type_extra.child.toLlvm(self).constArray2(llvm_vals.ptr, llvm_vals.len),
11473 );
11474 }
11475 return result.constant;10035 return result.constant;
11476}10036}
1147710037
...@@ -11482,9 +10042,6 @@ fn stringConstAssumeCapacity(self: *Builder, val: String) Constant {...@@ -11482,9 +10042,6 @@ fn stringConstAssumeCapacity(self: *Builder, val: String) Constant {
11482 const result = self.getOrPutConstantNoExtraAssumeCapacity(10042 const result = self.getOrPutConstantNoExtraAssumeCapacity(
11483 .{ .tag = .string, .data = @intFromEnum(val) },10043 .{ .tag = .string, .data = @intFromEnum(val) },
11484 );10044 );
11485 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
11486 self.llvm.context.constString(slice.ptr, @intCast(slice.len), .True),
11487 );
11488 return result.constant;10045 return result.constant;
11489}10046}
1149010047
...@@ -11495,9 +10052,6 @@ fn stringNullConstAssumeCapacity(self: *Builder, val: String) Constant {...@@ -11495,9 +10052,6 @@ fn stringNullConstAssumeCapacity(self: *Builder, val: String) Constant {
11495 const result = self.getOrPutConstantNoExtraAssumeCapacity(10052 const result = self.getOrPutConstantNoExtraAssumeCapacity(
11496 .{ .tag = .string_null, .data = @intFromEnum(val) },10053 .{ .tag = .string_null, .data = @intFromEnum(val) },
11497 );10054 );
11498 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
11499 self.llvm.context.constString(slice.ptr, @intCast(slice.len + 1), .True),
11500 );
11501 return result.constant;10055 return result.constant;
11502}10056}
1150310057
...@@ -11518,20 +10072,6 @@ fn vectorConstAssumeCapacity(...@@ -11518,20 +10072,6 @@ fn vectorConstAssumeCapacity(
11518 } else return self.zeroInitConstAssumeCapacity(ty);10072 } else return self.zeroInitConstAssumeCapacity(ty);
1151910073
11520 const result = self.getOrPutConstantAggregateAssumeCapacity(.vector, ty, vals);10074 const result = self.getOrPutConstantAggregateAssumeCapacity(.vector, ty, vals);
11521 if (self.useLibLlvm() and result.new) {
11522 const ExpectedContents = [expected_fields_len]*llvm.Value;
11523 var stack align(@alignOf(ExpectedContents)) =
11524 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
11525 const allocator = stack.get();
11526
11527 const llvm_vals = try allocator.alloc(*llvm.Value, vals.len);
11528 defer allocator.free(llvm_vals);
11529 for (llvm_vals, vals) |*llvm_val, val| llvm_val.* = val.toLlvm(self);
11530
11531 self.llvm.constants.appendAssumeCapacity(
11532 llvm.constVector(llvm_vals.ptr, @intCast(llvm_vals.len)),
11533 );
11534 }
11535 return result.constant;10075 return result.constant;
11536}10076}
1153710077
...@@ -11569,20 +10109,6 @@ fn splatConstAssumeCapacity(...@@ -11569,20 +10109,6 @@ fn splatConstAssumeCapacity(
11569 .tag = .splat,10109 .tag = .splat,
11570 .data = self.addConstantExtraAssumeCapacity(data),10110 .data = self.addConstantExtraAssumeCapacity(data),
11571 });10111 });
11572 if (self.useLibLlvm()) {
11573 const ExpectedContents = [expected_fields_len]*llvm.Value;
11574 var stack align(@alignOf(ExpectedContents)) =
11575 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
11576 const allocator = stack.get();
11577
11578 const llvm_vals = try allocator.alloc(*llvm.Value, ty.vectorLen(self));
11579 defer allocator.free(llvm_vals);
11580 @memset(llvm_vals, val.toLlvm(self));
11581
11582 self.llvm.constants.appendAssumeCapacity(
11583 llvm.constVector(llvm_vals.ptr, @intCast(llvm_vals.len)),
11584 );
11585 }
11586 }10112 }
11587 return @enumFromInt(gop.index);10113 return @enumFromInt(gop.index);
11588}10114}
...@@ -11624,8 +10150,6 @@ fn zeroInitConstAssumeCapacity(self: *Builder, ty: Type) Constant {...@@ -11624,8 +10150,6 @@ fn zeroInitConstAssumeCapacity(self: *Builder, ty: Type) Constant {
11624 const result = self.getOrPutConstantNoExtraAssumeCapacity(10150 const result = self.getOrPutConstantNoExtraAssumeCapacity(
11625 .{ .tag = .zeroinitializer, .data = @intFromEnum(ty) },10151 .{ .tag = .zeroinitializer, .data = @intFromEnum(ty) },
11626 );10152 );
11627 if (self.useLibLlvm() and result.new)
11628 self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).constNull());
11629 return result.constant;10153 return result.constant;
11630}10154}
1163110155
...@@ -11641,8 +10165,6 @@ fn undefConstAssumeCapacity(self: *Builder, ty: Type) Constant {...@@ -11641,8 +10165,6 @@ fn undefConstAssumeCapacity(self: *Builder, ty: Type) Constant {
11641 const result = self.getOrPutConstantNoExtraAssumeCapacity(10165 const result = self.getOrPutConstantNoExtraAssumeCapacity(
11642 .{ .tag = .undef, .data = @intFromEnum(ty) },10166 .{ .tag = .undef, .data = @intFromEnum(ty) },
11643 );10167 );
11644 if (self.useLibLlvm() and result.new)
11645 self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).getUndef());
11646 return result.constant;10168 return result.constant;
11647}10169}
1164810170
...@@ -11658,8 +10180,6 @@ fn poisonConstAssumeCapacity(self: *Builder, ty: Type) Constant {...@@ -11658,8 +10180,6 @@ fn poisonConstAssumeCapacity(self: *Builder, ty: Type) Constant {
11658 const result = self.getOrPutConstantNoExtraAssumeCapacity(10180 const result = self.getOrPutConstantNoExtraAssumeCapacity(
11659 .{ .tag = .poison, .data = @intFromEnum(ty) },10181 .{ .tag = .poison, .data = @intFromEnum(ty) },
11660 );10182 );
11661 if (self.useLibLlvm() and result.new)
11662 self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).getPoison());
11663 return result.constant;10183 return result.constant;
11664}10184}
1166510185
...@@ -11692,9 +10212,6 @@ fn blockAddrConstAssumeCapacity(...@@ -11692,9 +10212,6 @@ fn blockAddrConstAssumeCapacity(
11692 .tag = .blockaddress,10212 .tag = .blockaddress,
11693 .data = self.addConstantExtraAssumeCapacity(data),10213 .data = self.addConstantExtraAssumeCapacity(data),
11694 });10214 });
11695 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
11696 function.toLlvm(self).blockAddress(block.toValue(self, function).toLlvm(self, function)),
11697 );
11698 }10215 }
11699 return @enumFromInt(gop.index);10216 return @enumFromInt(gop.index);
11700}10217}
...@@ -11703,7 +10220,6 @@ fn dsoLocalEquivalentConstAssumeCapacity(self: *Builder, function: Function.Inde...@@ -11703,7 +10220,6 @@ fn dsoLocalEquivalentConstAssumeCapacity(self: *Builder, function: Function.Inde
11703 const result = self.getOrPutConstantNoExtraAssumeCapacity(10220 const result = self.getOrPutConstantNoExtraAssumeCapacity(
11704 .{ .tag = .dso_local_equivalent, .data = @intFromEnum(function) },10221 .{ .tag = .dso_local_equivalent, .data = @intFromEnum(function) },
11705 );10222 );
11706 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(undefined);
11707 return result.constant;10223 return result.constant;
11708}10224}
1170910225
...@@ -11711,7 +10227,6 @@ fn noCfiConstAssumeCapacity(self: *Builder, function: Function.Index) Constant {...@@ -11711,7 +10227,6 @@ fn noCfiConstAssumeCapacity(self: *Builder, function: Function.Index) Constant {
11711 const result = self.getOrPutConstantNoExtraAssumeCapacity(10227 const result = self.getOrPutConstantNoExtraAssumeCapacity(
11712 .{ .tag = .no_cfi, .data = @intFromEnum(function) },10228 .{ .tag = .no_cfi, .data = @intFromEnum(function) },
11713 );10229 );
11714 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(undefined);
11715 return result.constant;10230 return result.constant;
11716}10231}
1171710232
...@@ -11801,22 +10316,6 @@ fn castConstAssumeCapacity(self: *Builder, tag: Constant.Tag, val: Constant, ty:...@@ -11801,22 +10316,6 @@ fn castConstAssumeCapacity(self: *Builder, tag: Constant.Tag, val: Constant, ty:
11801 .tag = tag,10316 .tag = tag,
11802 .data = self.addConstantExtraAssumeCapacity(data.cast),10317 .data = self.addConstantExtraAssumeCapacity(data.cast),
11803 });10318 });
11804 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(switch (tag) {
11805 .trunc => &llvm.Value.constTrunc,
11806 .zext => &llvm.Value.constZExt,
11807 .sext => &llvm.Value.constSExt,
11808 .fptrunc => &llvm.Value.constFPTrunc,
11809 .fpext => &llvm.Value.constFPExt,
11810 .fptoui => &llvm.Value.constFPToUI,
11811 .fptosi => &llvm.Value.constFPToSI,
11812 .uitofp => &llvm.Value.constUIToFP,
11813 .sitofp => &llvm.Value.constSIToFP,
11814 .ptrtoint => &llvm.Value.constPtrToInt,
11815 .inttoptr => &llvm.Value.constIntToPtr,
11816 .bitcast => &llvm.Value.constBitCast,
11817 .addrspacecast => &llvm.Value.constAddrSpaceCast,
11818 else => unreachable,
11819 }(val.toLlvm(self), ty.toLlvm(self)));
11820 }10319 }
11821 return @enumFromInt(gop.index);10320 return @enumFromInt(gop.index);
11822}10321}
...@@ -11909,21 +10408,6 @@ fn gepConstAssumeCapacity(...@@ -11909,21 +10408,6 @@ fn gepConstAssumeCapacity(
11909 }),10408 }),
11910 });10409 });
11911 self.constant_extra.appendSliceAssumeCapacity(@ptrCast(indices));10410 self.constant_extra.appendSliceAssumeCapacity(@ptrCast(indices));
11912 if (self.useLibLlvm()) {
11913 const ExpectedContents = [expected_gep_indices_len]*llvm.Value;
11914 var stack align(@alignOf(ExpectedContents)) =
11915 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
11916 const allocator = stack.get();
11917
11918 const llvm_indices = try allocator.alloc(*llvm.Value, indices.len);
11919 defer allocator.free(llvm_indices);
11920 for (llvm_indices, indices) |*llvm_index, index| llvm_index.* = index.toLlvm(self);
11921
11922 self.llvm.constants.appendAssumeCapacity(switch (kind) {
11923 .normal => &llvm.Type.constGEP,
11924 .inbounds => &llvm.Type.constInBoundsGEP,
11925 }(ty.toLlvm(self), base.toLlvm(self), llvm_indices.ptr, @intCast(llvm_indices.len)));
11926 }
11927 }10411 }
11928 return @enumFromInt(gop.index);10412 return @enumFromInt(gop.index);
11929}10413}
...@@ -11958,9 +10442,6 @@ fn icmpConstAssumeCapacity(...@@ -11958,9 +10442,6 @@ fn icmpConstAssumeCapacity(
11958 .tag = .icmp,10442 .tag = .icmp,
11959 .data = self.addConstantExtraAssumeCapacity(data),10443 .data = self.addConstantExtraAssumeCapacity(data),
11960 });10444 });
11961 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
11962 llvm.constICmp(cond.toLlvm(), lhs.toLlvm(self), rhs.toLlvm(self)),
11963 );
11964 }10445 }
11965 return @enumFromInt(gop.index);10446 return @enumFromInt(gop.index);
11966}10447}
...@@ -11995,9 +10476,6 @@ fn fcmpConstAssumeCapacity(...@@ -11995,9 +10476,6 @@ fn fcmpConstAssumeCapacity(
11995 .tag = .fcmp,10476 .tag = .fcmp,
11996 .data = self.addConstantExtraAssumeCapacity(data),10477 .data = self.addConstantExtraAssumeCapacity(data),
11997 });10478 });
11998 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
11999 llvm.constFCmp(cond.toLlvm(), lhs.toLlvm(self), rhs.toLlvm(self)),
12000 );
12001 }10479 }
12002 return @enumFromInt(gop.index);10480 return @enumFromInt(gop.index);
12003}10481}
...@@ -12031,9 +10509,6 @@ fn extractElementConstAssumeCapacity(...@@ -12031,9 +10509,6 @@ fn extractElementConstAssumeCapacity(
12031 .tag = .extractelement,10509 .tag = .extractelement,
12032 .data = self.addConstantExtraAssumeCapacity(data),10510 .data = self.addConstantExtraAssumeCapacity(data),
12033 });10511 });
12034 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
12035 val.toLlvm(self).constExtractElement(index.toLlvm(self)),
12036 );
12037 }10512 }
12038 return @enumFromInt(gop.index);10513 return @enumFromInt(gop.index);
12039}10514}
...@@ -12068,9 +10543,6 @@ fn insertElementConstAssumeCapacity(...@@ -12068,9 +10543,6 @@ fn insertElementConstAssumeCapacity(
12068 .tag = .insertelement,10543 .tag = .insertelement,
12069 .data = self.addConstantExtraAssumeCapacity(data),10544 .data = self.addConstantExtraAssumeCapacity(data),
12070 });10545 });
12071 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
12072 val.toLlvm(self).constInsertElement(elem.toLlvm(self), index.toLlvm(self)),
12073 );
12074 }10546 }
12075 return @enumFromInt(gop.index);10547 return @enumFromInt(gop.index);
12076}10548}
...@@ -12109,9 +10581,6 @@ fn shuffleVectorConstAssumeCapacity(...@@ -12109,9 +10581,6 @@ fn shuffleVectorConstAssumeCapacity(
12109 .tag = .shufflevector,10581 .tag = .shufflevector,
12110 .data = self.addConstantExtraAssumeCapacity(data),10582 .data = self.addConstantExtraAssumeCapacity(data),
12111 });10583 });
12112 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
12113 lhs.toLlvm(self).constShuffleVector(rhs.toLlvm(self), mask.toLlvm(self)),
12114 );
12115 }10584 }
12116 return @enumFromInt(gop.index);10585 return @enumFromInt(gop.index);
12117}10586}
...@@ -12166,18 +10635,6 @@ fn binConstAssumeCapacity(...@@ -12166,18 +10635,6 @@ fn binConstAssumeCapacity(
12166 .tag = tag,10635 .tag = tag,
12167 .data = self.addConstantExtraAssumeCapacity(data.extra),10636 .data = self.addConstantExtraAssumeCapacity(data.extra),
12168 });10637 });
12169 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(switch (tag) {
12170 .add => &llvm.Value.constAdd,
12171 .sub => &llvm.Value.constSub,
12172 .mul => &llvm.Value.constMul,
12173 .shl => &llvm.Value.constShl,
12174 .lshr => &llvm.Value.constLShr,
12175 .ashr => &llvm.Value.constAShr,
12176 .@"and" => &llvm.Value.constAnd,
12177 .@"or" => &llvm.Value.constOr,
12178 .xor => &llvm.Value.constXor,
12179 else => unreachable,
12180 }(lhs.toLlvm(self), rhs.toLlvm(self)));
12181 }10638 }
12182 return @enumFromInt(gop.index);10639 return @enumFromInt(gop.index);
12183}10640}
...@@ -12220,21 +10677,6 @@ fn asmConstAssumeCapacity(...@@ -12220,21 +10677,6 @@ fn asmConstAssumeCapacity(
12220 .tag = data.tag,10677 .tag = data.tag,
12221 .data = self.addConstantExtraAssumeCapacity(data.extra),10678 .data = self.addConstantExtraAssumeCapacity(data.extra),
12222 });10679 });
12223 if (self.useLibLlvm()) {
12224 const assembly_slice = assembly.slice(self).?;
12225 const constraints_slice = constraints.slice(self).?;
12226 self.llvm.constants.appendAssumeCapacity(llvm.getInlineAsm(
12227 ty.toLlvm(self),
12228 assembly_slice.ptr,
12229 assembly_slice.len,
12230 constraints_slice.ptr,
12231 constraints_slice.len,
12232 llvm.Bool.fromBool(info.sideeffect),
12233 llvm.Bool.fromBool(info.alignstack),
12234 if (info.inteldialect) .Intel else .ATT,
12235 llvm.Bool.fromBool(info.unwind),
12236 ));
12237 }
12238 }10680 }
12239 return @enumFromInt(gop.index);10681 return @enumFromInt(gop.index);
12240}10682}
...@@ -12251,7 +10693,6 @@ fn ensureUnusedConstantCapacity(...@@ -12251,7 +10693,6 @@ fn ensureUnusedConstantCapacity(
12251 self.gpa,10693 self.gpa,
12252 count * (@typeInfo(Extra).Struct.fields.len + trail_len),10694 count * (@typeInfo(Extra).Struct.fields.len + trail_len),
12253 );10695 );
12254 if (self.useLibLlvm()) try self.llvm.constants.ensureUnusedCapacity(self.gpa, count);
12255}10696}
1225610697
12257fn getOrPutConstantNoExtraAssumeCapacity(10698fn getOrPutConstantNoExtraAssumeCapacity(
...@@ -15513,10 +13954,6 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co...@@ -15513,10 +13954,6 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
15513const assert = std.debug.assert;13954const assert = std.debug.assert;
15514const build_options = @import("build_options");13955const build_options = @import("build_options");
15515const builtin = @import("builtin");13956const builtin = @import("builtin");
15516const llvm = if (build_options.have_llvm)
15517 @import("bindings.zig")
15518else
15519 @compileError("LLVM unavailable");
15520const log = std.log.scoped(.llvm);13957const log = std.log.scoped(.llvm);
15521const std = @import("std");13958const std = @import("std");
1552213959
src/link.zig+1-2
...@@ -839,10 +839,9 @@ pub const File = struct {...@@ -839,10 +839,9 @@ pub const File = struct {
839 }839 }
840840
841 const llvm_bindings = @import("codegen/llvm/bindings.zig");841 const llvm_bindings = @import("codegen/llvm/bindings.zig");
842 const Builder = @import("codegen/llvm/Builder.zig");
843 const llvm = @import("codegen/llvm.zig");842 const llvm = @import("codegen/llvm.zig");
844 const target = comp.root_mod.resolved_target.result;843 const target = comp.root_mod.resolved_target.result;
845 Builder.initializeLLVMTarget(target.cpu.arch);844 llvm.initializeLLVMTarget(target.cpu.arch);
846 const os_tag = llvm.targetOs(target.os.tag);845 const os_tag = llvm.targetOs(target.os.tag);
847 const bad = llvm_bindings.WriteArchive(full_out_path_z, object_files.items.ptr, object_files.items.len, os_tag);846 const bad = llvm_bindings.WriteArchive(full_out_path_z, object_files.items.ptr, object_files.items.len, os_tag);
848 if (bad) return error.UnableToWriteArchive;847 if (bad) return error.UnableToWriteArchive;