| ... | @@ -1,21 +1,6 @@ | ... | @@ -1,21 +1,6 @@ |
| 1 | gpa: Allocator, | 1 | gpa: Allocator, |
| 2 | use_lib_llvm: bool, | | |
| 3 | strip: bool, | 2 | strip: bool, |
| 4 | | 3 | |
| 5 | llvm: 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 | | | |
| 19 | source_filename: String, | 4 | source_filename: String, |
| 20 | data_layout: String, | 5 | data_layout: String, |
| 21 | target_triple: String, | 6 | target_triple: String, |
| ... | @@ -73,7 +58,6 @@ pub const expected_intrinsic_name_len = 64; | ... | @@ -73,7 +58,6 @@ pub const expected_intrinsic_name_len = 64; |
| 73 | | 58 | |
| 74 | pub const Options = struct { | 59 | pub 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 | } |
| 664 | | 647 | |
| ... | @@ -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 | } |
| 847 | | 830 | |
| 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 | }; |
| 1340 | | 1313 | |
| 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 | }; |
| 1462 | | 1430 | |
| 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 | }; |
| 1835 | | 1787 | |
| 1836 | pub const Preemption = enum { | 1788 | pub 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 | }; |
| 1873 | | 1817 | |
| 1874 | pub const DllStorageClass = enum(u2) { | 1818 | pub 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 | }; |
| 1896 | | 1832 | |
| 1897 | pub const ThreadLocal = enum(u3) { | 1833 | pub 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 | }; |
| 1925 | | 1851 | |
| 1926 | pub const Mutability = enum { global, constant }; | 1852 | pub 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 | }; |
| 2198 | | 2119 | |
| 2199 | pub const Global = struct { | 2120 | pub const Global = struct { |
| ... | @@ -2263,34 +2184,23 @@ pub const Global = struct { | ... | @@ -2263,34 +2184,23 @@ pub const Global = struct { |
| 2263 | } | 2184 | } |
| 2264 | | 2185 | |
| 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 | } |
| 2270 | | 2190 | |
| 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 | } |
| 2276 | | 2195 | |
| 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 | } |
| 2281 | | 2199 | |
| 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 | } |
| 2288 | | 2203 | |
| 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 { |
| 2321 | | 2231 | |
| 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 | } |
| 2328 | | 2236 | |
| 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 | } |
| 2333 | | 2240 | |
| ... | @@ -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 | } |
| 2375 | | 2278 | |
| 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 | } |
| 2395 | | 2285 | |
| ... | @@ -2446,13 +2336,8 @@ pub const Alias = struct { | ... | @@ -2446,13 +2336,8 @@ pub const Alias = struct { |
| 2446 | } | 2336 | } |
| 2447 | | 2337 | |
| 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 | }; |
| 2458 | | 2343 | |
| ... | @@ -2505,14 +2390,10 @@ pub const Variable = struct { | ... | @@ -2505,14 +2390,10 @@ pub const Variable = struct { |
| 2505 | } | 2390 | } |
| 2506 | | 2391 | |
| 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 | } |
| 2511 | | 2395 | |
| 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 | } |
| 2518 | | 2399 | |
| ... | @@ -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 | } |
| 2569 | | 2413 | |
| 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 | } |
| 2574 | | 2417 | |
| 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 | } |
| 2580 | | 2421 | |
| 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 | }; |
| 2592 | | 2427 | |
| ... | @@ -3980,7 +3815,6 @@ pub const Function = struct { | ... | @@ -3980,7 +3815,6 @@ pub const Function = struct { |
| 3980 | } | 3815 | } |
| 3981 | | 3816 | |
| 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 | } |
| 3986 | | 3820 | |
| ... | @@ -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 | } |
| 4066 | | 3828 | |
| 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 | } |
| 4071 | | 3832 | |
| 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 | }; |
| 4082 | | 3837 | |
| 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 | } |
| 4829 | | 4584 | |
| 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 | }; |
| 4975 | | 4702 | |
| ... | @@ -5116,11 +4843,6 @@ pub const DebugLocation = struct { | ... | @@ -5116,11 +4843,6 @@ pub const DebugLocation = struct { |
| 5116 | pub const WipFunction = struct { | 4843 | pub 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 | }; |
| 5164 | | 4881 | |
| 5165 | pub const Instruction = Function.Instruction; | 4882 | pub const Instruction = Function.Instruction; |
| 5166 | | 4883 | |
| 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 names | 4909 | 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 | } |
| 5210 | | 4912 | |
| 5211 | return self; | 4913 | return self; |
| ... | @@ -5222,7 +4924,6 @@ pub const WipFunction = struct { | ... | @@ -5222,7 +4924,6 @@ pub const WipFunction = struct { |
| 5222 | | 4924 | |
| 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); | | |
| 5226 | | 4927 | |
| 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 | } |
| 5242 | | 4937 | |
| 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 | } |
| 5252 | | 4943 | |
| 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 | } |
| 5261 | | 4948 | |
| 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 | } |
| 5271 | | 4955 | |
| ... | @@ -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 | } |
| 5295 | | 4976 | |
| ... | @@ -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 | } |
| 5316 | | 4995 | |
| 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 | } |
| 5346 | | 5022 | |
| 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 | } |
| 5355 | | 5028 | |
| ... | @@ -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 | } |
| 5383 | | 5045 | |
| ... | @@ -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 | } |
| 5500 | | 5112 | |
| ... | @@ -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 | } |
| 5526 | | 5131 | |
| ... | @@ -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 | } |
| 5555 | | 5152 | |
| ... | @@ -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 | } |
| 5585 | | 5174 | |
| ... | @@ -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 | } |
| 5627 | | 5209 | |
| ... | @@ -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 | } |
| 5678 | | 5231 | |
| ... | @@ -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 | } |
| 5726 | | 5270 | |
| ... | @@ -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 | } |
| 5782 | | 5315 | |
| ... | @@ -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 | } |
| 5832 | | 5358 | |
| ... | @@ -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 | } |
| 5856 | | 5375 | |
| ... | @@ -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 | } |
| 5917 | | 5417 | |
| ... | @@ -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 | } |
| 5966 | | 5449 | |
| ... | @@ -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 | } |
| 6047 | | 5508 | |
| ... | @@ -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 | } |
| 6124 | | 5569 | |
| ... | @@ -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 | } |
| 6136 | | 5581 | |
| 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 | } |
| 6154 | | 5599 | |
| 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 | }; |
| 6198 | | 5623 | |
| ... | @@ -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 | } |
| 6310 | | 5688 | |
| ... | @@ -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 | } |
| 6417 | | 5788 | |
| ... | @@ -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 | } |
| 6933 | | 6299 | |
| 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 | } |
| 7106 | | 6364 | |
| ... | @@ -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 | } |
| 7137 | | 6385 | |
| ... | @@ -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 | } |
| 7177 | | 6412 | |
| ... | @@ -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 | else | 6445 | else |
| 7213 | .none; | 6446 | .none; |
| 7214 | | 6447 | |
| 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 | }; |
| 7355 | | 6560 | |
| 7356 | pub const IntegerCondition = enum(u6) { | 6561 | pub 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 | }; |
| 7382 | | 6573 | |
| 7383 | pub const MemoryAccessKind = enum(u1) { | 6574 | pub 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 | }; |
| 7443 | | 6622 | |
| 7444 | const MemoryAccessInfo = packed struct(u32) { | 6623 | const 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 | }; |
| 8273 | | 7442 | |
| 8274 | pub const Value = enum(u32) { | 7443 | pub 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 | }; |
| 8355 | | 7516 | |
| 8356 | pub const MetadataString = enum(u32) { | 7517 | pub const MetadataString = enum(u32) { |
| ... | @@ -8589,11 +7750,8 @@ pub const InitError = error{ | ... | @@ -8589,11 +7750,8 @@ pub const InitError = error{ |
| 8589 | pub fn init(options: Options) InitError!Builder { | 7750 | pub 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, |
| 8594 | | 7754 | |
| 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(); |
| 8655 | | 7800 | |
| 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); |
| 8658 | | 7803 | |
| 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 | } | | |
| 8667 | | 7805 | |
| 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 | } |
| 8691 | | 7809 | |
| 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 | } |
| 8715 | | 7829 | |
| 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 | } |
| 8733 | | 7843 | |
| 8734 | pub fn deinit(self: *Builder) void { | 7844 | pub 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); |
| 8750 | | 7846 | |
| 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 | } |
| 8790 | | 7886 | |
| 8791 | pub 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 | | | |
| 8983 | pub fn setModuleAsm(self: *Builder) std.ArrayListUnmanaged(u8).Writer { | 7887 | pub 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 { |
| 8992 | pub fn finishModuleAsm(self: *Builder) Allocator.Error!void { | 7896 | pub 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 | } |
| 8998 | | 7900 | |
| 8999 | pub fn string(self: *Builder, bytes: []const u8) Allocator.Error!String { | 7901 | pub 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 | } |
| 9130 | | 8015 | |
| 9131 | pub fn attr(self: *Builder, attribute: Attribute) Allocator.Error!Attribute.Index { | 8016 | pub 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); | | |
| 9134 | | 8018 | |
| 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 | } |
| 9202 | | 8023 | |
| ... | @@ -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 | } |
| 9252 | | 8072 | |
| ... | @@ -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 | } |
| 9492 | | 8291 | |
| ... | @@ -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 | } |
| 9906 | | 8705 | |
| 9907 | pub 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 | | | |
| 9921 | pub 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 | | | |
| 9927 | pub 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 | | | |
| 9941 | pub fn dump(self: *Builder) void { | 8706 | pub 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 | } |
| 9947 | | 8709 | |
| 9948 | pub fn printToFile(self: *Builder, path: []const u8) Allocator.Error!bool { | 8710 | pub 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 | }; |
| 9953 | | 8715 | defer file.close(); |
| 9954 | pub 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 | } |
| 9975 | | 8722 | |
| ... | @@ -10579,10 +9326,6 @@ pub fn printUnbuffered( | ... | @@ -10579,10 +9326,6 @@ pub fn printUnbuffered( |
| 10579 | } | 9326 | } |
| 10580 | } | 9327 | } |
| 10581 | | 9328 | |
| 10582 | pub inline fn useLibLlvm(self: *const Builder) bool { | | |
| 10583 | return build_options.have_llvm and self.use_lib_llvm; | | |
| 10584 | } | | |
| 10585 | | | |
| 10586 | const NoExtra = struct {}; | 9329 | const NoExtra = struct {}; |
| 10587 | | 9330 | |
| 10588 | fn isValidIdentifier(id: []const u8) bool { | 9331 | fn isValidIdentifier(id: []const u8) bool { |
| ... | @@ -10614,7 +9357,6 @@ fn printEscapedString( | ... | @@ -10614,7 +9357,6 @@ fn printEscapedString( |
| 10614 | } | 9357 | } |
| 10615 | | 9358 | |
| 10616 | fn ensureUnusedGlobalCapacity(self: *Builder, name: String) Allocator.Error!void { | 9359 | fn 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( |
| 10688 | fn intTypeAssumeCapacity(self: *Builder, bits: u24) Type { | 9416 | fn 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 | } |
| 10695 | | 9421 | |
| ... | @@ -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 | } |
| 10704 | | 9428 | |
| ... | @@ -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 | } |
| 10914 | | 9606 | |
| ... | @@ -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 | } |
| 10936 | | 9627 | |
| 10937 | fn getOrPutTypeNoExtraAssumeCapacity(self: *Builder, item: Type.Item) struct { new: bool, type: Type } { | 9628 | fn 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 | } |
| 11166 | | 9812 | |
| ... | @@ -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 | } |
| 11184 | | 9820 | |
| ... | @@ -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 | } |
| 11198 | | 9827 | |
| ... | @@ -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 | } |
| 11377 | | 9967 | |
| ... | @@ -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 | } |
| 11387 | | 9975 | |
| ... | @@ -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 | } |
| 11435 | | 10009 | |
| ... | @@ -11458,20 +10032,6 @@ fn arrayConstAssumeCapacity( | ... | @@ -11458,20 +10032,6 @@ fn arrayConstAssumeCapacity( |
| 11458 | } else return self.zeroInitConstAssumeCapacity(ty); | 10032 | } else return self.zeroInitConstAssumeCapacity(ty); |
| 11459 | | 10033 | |
| 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 | } |
| 11477 | | 10037 | |
| ... | @@ -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 | } |
| 11490 | | 10047 | |
| ... | @@ -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 | } |
| 11503 | | 10057 | |
| ... | @@ -11518,20 +10072,6 @@ fn vectorConstAssumeCapacity( | ... | @@ -11518,20 +10072,6 @@ fn vectorConstAssumeCapacity( |
| 11518 | } else return self.zeroInitConstAssumeCapacity(ty); | 10072 | } else return self.zeroInitConstAssumeCapacity(ty); |
| 11519 | | 10073 | |
| 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 | } |
| 11537 | | 10077 | |
| ... | @@ -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 | } |
| 11631 | | 10155 | |
| ... | @@ -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 | } |
| 11648 | | 10170 | |
| ... | @@ -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 | } |
| 11665 | | 10185 | |
| ... | @@ -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 | } |
| 11709 | | 10225 | |
| ... | @@ -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 | } |
| 11717 | | 10232 | |
| ... | @@ -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 | } |
| 12256 | | 10697 | |
| 12257 | fn getOrPutConstantNoExtraAssumeCapacity( | 10698 | fn 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 |
| 15513 | const assert = std.debug.assert; | 13954 | const assert = std.debug.assert; |
| 15514 | const build_options = @import("build_options"); | 13955 | const build_options = @import("build_options"); |
| 15515 | const builtin = @import("builtin"); | 13956 | const builtin = @import("builtin"); |
| 15516 | const llvm = if (build_options.have_llvm) | | |
| 15517 | @import("bindings.zig") | | |
| 15518 | else | | |
| 15519 | @compileError("LLVM unavailable"); | | |
| 15520 | const log = std.log.scoped(.llvm); | 13957 | const log = std.log.scoped(.llvm); |
| 15521 | const std = @import("std"); | 13958 | const std = @import("std"); |
| 15522 | | 13959 | |