| ... | ... | @@ -1,21 +1,6 @@ |
| 1 | 1 | gpa: Allocator, |
| 2 | | use_lib_llvm: bool, |
| 3 | 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 | 4 | source_filename: String, |
| 20 | 5 | data_layout: String, |
| 21 | 6 | target_triple: String, |
| ... | ... | @@ -73,7 +58,6 @@ pub const expected_intrinsic_name_len = 64; |
| 73 | 58 | |
| 74 | 59 | pub const Options = struct { |
| 75 | 60 | allocator: Allocator, |
| 76 | | use_lib_llvm: bool = false, |
| 77 | 61 | strip: bool = true, |
| 78 | 62 | name: []const u8 = &.{}, |
| 79 | 63 | target: std.Target = builtin.target, |
| ... | ... | @@ -658,7 +642,6 @@ pub const Type = enum(u32) { |
| 658 | 642 | var visited: IsSizedVisited = .{}; |
| 659 | 643 | defer visited.deinit(builder.gpa); |
| 660 | 644 | const result = try self.isSizedVisited(&visited, builder); |
| 661 | | if (builder.useLibLlvm()) assert(result == self.toLlvm(builder).isSized().toBool()); |
| 662 | 645 | return result; |
| 663 | 646 | } |
| 664 | 647 | |
| ... | ... | @@ -845,11 +828,6 @@ pub const Type = enum(u32) { |
| 845 | 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 | 831 | const IsSizedVisited = std.AutoHashMapUnmanaged(Type, void); |
| 854 | 832 | fn isSizedVisited( |
| 855 | 833 | self: Type, |
| ... | ... | @@ -1331,11 +1309,6 @@ pub const Attribute = union(Kind) { |
| 1331 | 1309 | fn toStorage(self: Index, builder: *const Builder) Storage { |
| 1332 | 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 | 1314 | pub const Kind = enum(u32) { |
| ... | ... | @@ -1453,11 +1426,6 @@ pub const Attribute = union(Kind) { |
| 1453 | 1426 | const str: String = @enumFromInt(@intFromEnum(self)); |
| 1454 | 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 | 1431 | pub const FpClass = packed struct(u32) { |
| ... | ... | @@ -1815,22 +1783,6 @@ pub const Linkage = enum(u4) { |
| 1815 | 1783 | ) @TypeOf(writer).Error!void { |
| 1816 | 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 | 1788 | pub const Preemption = enum { |
| ... | ... | @@ -1861,14 +1813,6 @@ pub const Visibility = enum(u2) { |
| 1861 | 1813 | ) @TypeOf(writer).Error!void { |
| 1862 | 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 | 1818 | pub const DllStorageClass = enum(u2) { |
| ... | ... | @@ -1884,14 +1828,6 @@ pub const DllStorageClass = enum(u2) { |
| 1884 | 1828 | ) @TypeOf(writer).Error!void { |
| 1885 | 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 | 1833 | pub const ThreadLocal = enum(u3) { |
| ... | ... | @@ -1911,16 +1847,6 @@ pub const ThreadLocal = enum(u3) { |
| 1911 | 1847 | try writer.print("{s}thread_local", .{prefix}); |
| 1912 | 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 | 1852 | pub const Mutability = enum { global, constant }; |
| ... | ... | @@ -2189,11 +2115,6 @@ pub const CallConv = enum(u10) { |
| 2189 | 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 | 2120 | pub const Global = struct { |
| ... | ... | @@ -2263,34 +2184,23 @@ pub const Global = struct { |
| 2263 | 2184 | } |
| 2264 | 2185 | |
| 2265 | 2186 | pub fn setLinkage(self: Index, linkage: Linkage, builder: *Builder) void { |
| 2266 | | if (builder.useLibLlvm()) self.toLlvm(builder).setLinkage(linkage.toLlvm()); |
| 2267 | 2187 | self.ptr(builder).linkage = linkage; |
| 2268 | 2188 | self.updateDsoLocal(builder); |
| 2269 | 2189 | } |
| 2270 | 2190 | |
| 2271 | 2191 | pub fn setVisibility(self: Index, visibility: Visibility, builder: *Builder) void { |
| 2272 | | if (builder.useLibLlvm()) self.toLlvm(builder).setVisibility(visibility.toLlvm()); |
| 2273 | 2192 | self.ptr(builder).visibility = visibility; |
| 2274 | 2193 | self.updateDsoLocal(builder); |
| 2275 | 2194 | } |
| 2276 | 2195 | |
| 2277 | 2196 | pub fn setDllStorageClass(self: Index, class: DllStorageClass, builder: *Builder) void { |
| 2278 | | if (builder.useLibLlvm()) self.toLlvm(builder).setDLLStorageClass(class.toLlvm()); |
| 2279 | 2197 | self.ptr(builder).dll_storage_class = class; |
| 2280 | 2198 | } |
| 2281 | 2199 | |
| 2282 | 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 | 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 | 2204 | const FormatData = struct { |
| 2295 | 2205 | global: Index, |
| 2296 | 2206 | builder: *const Builder, |
| ... | ... | @@ -2321,13 +2231,10 @@ pub const Global = struct { |
| 2321 | 2231 | |
| 2322 | 2232 | pub fn replace(self: Index, other: Index, builder: *Builder) Allocator.Error!void { |
| 2323 | 2233 | try builder.ensureUnusedGlobalCapacity(.empty); |
| 2324 | | if (builder.useLibLlvm()) |
| 2325 | | try builder.llvm.replacements.ensureUnusedCapacity(builder.gpa, 1); |
| 2326 | 2234 | self.replaceAssumeCapacity(other, builder); |
| 2327 | 2235 | } |
| 2328 | 2236 | |
| 2329 | 2237 | pub fn delete(self: Index, builder: *Builder) void { |
| 2330 | | if (builder.useLibLlvm()) self.toLlvm(builder).eraseGlobalValue(); |
| 2331 | 2238 | self.ptr(builder).kind = .{ .replaced = .none }; |
| 2332 | 2239 | } |
| 2333 | 2240 | |
| ... | ... | @@ -2355,12 +2262,8 @@ pub const Global = struct { |
| 2355 | 2262 | const old_name = self.name(builder); |
| 2356 | 2263 | if (new_name == old_name) return; |
| 2357 | 2264 | const index = @intFromEnum(self.unwrap(builder)); |
| 2358 | | if (builder.useLibLlvm()) |
| 2359 | | builder.llvm.globals.appendAssumeCapacity(builder.llvm.globals.items[index]); |
| 2360 | 2265 | _ = builder.addGlobalAssumeCapacity(new_name, builder.globals.values()[index]); |
| 2361 | | if (builder.useLibLlvm()) _ = builder.llvm.globals.pop(); |
| 2362 | 2266 | builder.globals.swapRemoveAt(index); |
| 2363 | | self.updateName(builder); |
| 2364 | 2267 | if (!old_name.isAnon()) return; |
| 2365 | 2268 | builder.next_unnamed_global = @enumFromInt(@intFromEnum(builder.next_unnamed_global) - 1); |
| 2366 | 2269 | if (builder.next_unnamed_global == old_name) return; |
| ... | ... | @@ -2373,23 +2276,10 @@ pub const Global = struct { |
| 2373 | 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 | 2279 | fn replaceAssumeCapacity(self: Index, other: Index, builder: *Builder) void { |
| 2384 | 2280 | if (self.eql(other, builder)) return; |
| 2385 | 2281 | builder.next_replaced_global = @enumFromInt(@intFromEnum(builder.next_replaced_global) - 1); |
| 2386 | 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 | 2283 | self.ptr(builder).kind = .{ .replaced = other.unwrap(builder) }; |
| 2394 | 2284 | } |
| 2395 | 2285 | |
| ... | ... | @@ -2446,13 +2336,8 @@ pub const Alias = struct { |
| 2446 | 2336 | } |
| 2447 | 2337 | |
| 2448 | 2338 | pub fn setAliasee(self: Index, aliasee: Constant, builder: *Builder) void { |
| 2449 | | if (builder.useLibLlvm()) self.toLlvm(builder).setAliasee(aliasee.toLlvm(builder)); |
| 2450 | 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 | 2390 | } |
| 2506 | 2391 | |
| 2507 | 2392 | pub fn setThreadLocal(self: Index, thread_local: ThreadLocal, builder: *Builder) void { |
| 2508 | | if (builder.useLibLlvm()) self.toLlvm(builder).setThreadLocalMode(thread_local.toLlvm()); |
| 2509 | 2393 | self.ptr(builder).thread_local = thread_local; |
| 2510 | 2394 | } |
| 2511 | 2395 | |
| 2512 | 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 | 2397 | self.ptr(builder).mutability = mutability; |
| 2517 | 2398 | } |
| 2518 | 2399 | |
| ... | ... | @@ -2525,68 +2406,22 @@ pub const Variable = struct { |
| 2525 | 2406 | const variable = self.ptrConst(builder); |
| 2526 | 2407 | const global = variable.global.ptr(builder); |
| 2527 | 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 | 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 | 2411 | self.ptr(builder).init = initializer; |
| 2568 | 2412 | } |
| 2569 | 2413 | |
| 2570 | 2414 | pub fn setSection(self: Index, section: String, builder: *Builder) void { |
| 2571 | | if (builder.useLibLlvm()) self.toLlvm(builder).setSection(section.slice(builder).?); |
| 2572 | 2415 | self.ptr(builder).section = section; |
| 2573 | 2416 | } |
| 2574 | 2417 | |
| 2575 | 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 | 2419 | self.ptr(builder).alignment = alignment; |
| 2579 | 2420 | } |
| 2580 | 2421 | |
| 2581 | 2422 | pub fn getAlignment(self: Index, builder: *Builder) Alignment { |
| 2582 | | if (builder.useLibLlvm()) |
| 2583 | | return Alignment.fromByteUnits(self.toLlvm(builder).getAlignment()); |
| 2584 | 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 | 3815 | } |
| 3981 | 3816 | |
| 3982 | 3817 | pub fn setCallConv(self: Index, call_conv: CallConv, builder: *Builder) void { |
| 3983 | | if (builder.useLibLlvm()) self.toLlvm(builder).setFunctionCallConv(call_conv.toLlvm()); |
| 3984 | 3818 | self.ptr(builder).call_conv = call_conv; |
| 3985 | 3819 | } |
| 3986 | 3820 | |
| ... | ... | @@ -3989,95 +3823,16 @@ pub const Function = struct { |
| 3989 | 3823 | new_function_attributes: FunctionAttributes, |
| 3990 | 3824 | builder: *Builder, |
| 3991 | 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 | 3826 | self.ptr(builder).attributes = new_function_attributes; |
| 4065 | 3827 | } |
| 4066 | 3828 | |
| 4067 | 3829 | pub fn setSection(self: Index, section: String, builder: *Builder) void { |
| 4068 | | if (builder.useLibLlvm()) self.toLlvm(builder).setSection(section.slice(builder).?); |
| 4069 | 3830 | self.ptr(builder).section = section; |
| 4070 | 3831 | } |
| 4071 | 3832 | |
| 4072 | 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 | 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 | 3838 | pub const Block = struct { |
| ... | ... | @@ -4827,13 +4582,6 @@ pub const Function = struct { |
| 4827 | 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 | 4585 | fn llvmName(self: Instruction.Index, wip: *const WipFunction) [:0]const u8 { |
| 4838 | 4586 | return if (wip.builder.strip) |
| 4839 | 4587 | "" |
| ... | ... | @@ -4949,27 +4697,6 @@ pub const Function = struct { |
| 4949 | 4697 | fmax = 13, |
| 4950 | 4698 | fmin = 14, |
| 4951 | 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 | 4843 | pub const WipFunction = struct { |
| 5117 | 4844 | builder: *Builder, |
| 5118 | 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 | 4846 | last_debug_location: ?DebugLocation, |
| 5125 | 4847 | current_debug_location: ?DebugLocation, |
| 5126 | 4848 | cursor: Cursor, |
| ... | ... | @@ -5154,30 +4876,15 @@ pub const WipFunction = struct { |
| 5154 | 4876 | pub fn toInst(self: Index, function: *const Function) Instruction.Index { |
| 5155 | 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 | 4882 | pub const Instruction = Function.Instruction; |
| 5166 | 4883 | |
| 5167 | 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 | 4885 | var self = WipFunction{ |
| 5174 | 4886 | .builder = builder, |
| 5175 | 4887 | .function = function, |
| 5176 | | .llvm = if (builder.useLibLlvm()) .{ |
| 5177 | | .builder = builder.llvm.context.createBuilder(), |
| 5178 | | .blocks = .{}, |
| 5179 | | .instructions = .{}, |
| 5180 | | } else undefined, |
| 5181 | 4888 | .cursor = undefined, |
| 5182 | 4889 | .blocks = .{}, |
| 5183 | 4890 | .instructions = .{}, |
| ... | ... | @@ -5196,16 +4903,11 @@ pub const WipFunction = struct { |
| 5196 | 4903 | if (!self.builder.strip) { |
| 5197 | 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 | 4906 | for (0..params_len) |param_index| { |
| 5202 | 4907 | self.instructions.appendAssumeCapacity(.{ .tag = .arg, .data = @intCast(param_index) }); |
| 5203 | 4908 | if (!self.builder.strip) { |
| 5204 | 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 | 4913 | return self; |
| ... | ... | @@ -5222,7 +4924,6 @@ pub const WipFunction = struct { |
| 5222 | 4924 | |
| 5223 | 4925 | pub fn block(self: *WipFunction, incoming: u32, name: []const u8) Allocator.Error!Block.Index { |
| 5224 | 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 | 4928 | const index: Block.Index = @enumFromInt(self.blocks.items.len); |
| 5228 | 4929 | const final_name = if (self.builder.strip) .empty else try self.builder.string(name); |
| ... | ... | @@ -5231,41 +4932,24 @@ pub const WipFunction = struct { |
| 5231 | 4932 | .incoming = incoming, |
| 5232 | 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 | 4935 | return index; |
| 5241 | 4936 | } |
| 5242 | 4937 | |
| 5243 | 4938 | pub fn ret(self: *WipFunction, val: Value) Allocator.Error!Instruction.Index { |
| 5244 | 4939 | assert(val.typeOfWip(self) == self.function.typeOf(self.builder).functionReturn(self.builder)); |
| 5245 | 4940 | try self.ensureUnusedExtraCapacity(1, NoExtra, 0); |
| 5246 | | const instruction = 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; |
| 4941 | return try self.addInst(null, .{ .tag = .ret, .data = @intFromEnum(val) }); |
| 5251 | 4942 | } |
| 5252 | 4943 | |
| 5253 | 4944 | pub fn retVoid(self: *WipFunction) Allocator.Error!Instruction.Index { |
| 5254 | 4945 | try self.ensureUnusedExtraCapacity(1, NoExtra, 0); |
| 5255 | | const instruction = 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; |
| 4946 | return try self.addInst(null, .{ .tag = .@"ret void", .data = undefined }); |
| 5260 | 4947 | } |
| 5261 | 4948 | |
| 5262 | 4949 | pub fn br(self: *WipFunction, dest: Block.Index) Allocator.Error!Instruction.Index { |
| 5263 | 4950 | try self.ensureUnusedExtraCapacity(1, NoExtra, 0); |
| 5264 | 4951 | const instruction = try self.addInst(null, .{ .tag = .br, .data = @intFromEnum(dest) }); |
| 5265 | 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 | 4953 | return instruction; |
| 5270 | 4954 | } |
| 5271 | 4955 | |
| ... | ... | @@ -5287,9 +4971,6 @@ pub const WipFunction = struct { |
| 5287 | 4971 | }); |
| 5288 | 4972 | then.ptr(self).branches += 1; |
| 5289 | 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 | 4974 | return instruction; |
| 5294 | 4975 | } |
| 5295 | 4976 | |
| ... | ... | @@ -5310,8 +4991,6 @@ pub const WipFunction = struct { |
| 5310 | 4991 | extra.trail.nextMut(extra.data.cases_len, Block.Index, wip)[self.index] = dest; |
| 5311 | 4992 | self.index += 1; |
| 5312 | 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 | 4996 | pub fn finish(self: WipSwitch, wip: *WipFunction) void { |
| ... | ... | @@ -5338,18 +5017,12 @@ pub const WipFunction = struct { |
| 5338 | 5017 | }); |
| 5339 | 5018 | _ = self.extra.addManyAsSliceAssumeCapacity(cases_len * 2); |
| 5340 | 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 | 5020 | return .{ .index = 0, .instruction = instruction }; |
| 5345 | 5021 | } |
| 5346 | 5022 | |
| 5347 | 5023 | pub fn @"unreachable"(self: *WipFunction) Allocator.Error!Instruction.Index { |
| 5348 | 5024 | try self.ensureUnusedExtraCapacity(1, NoExtra, 0); |
| 5349 | 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 | 5026 | return instruction; |
| 5354 | 5027 | } |
| 5355 | 5028 | |
| ... | ... | @@ -5367,17 +5040,6 @@ pub const WipFunction = struct { |
| 5367 | 5040 | } |
| 5368 | 5041 | try self.ensureUnusedExtraCapacity(1, NoExtra, 0); |
| 5369 | 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 | 5043 | return instruction.toValue(); |
| 5382 | 5044 | } |
| 5383 | 5045 | |
| ... | ... | @@ -5445,56 +5107,6 @@ pub const WipFunction = struct { |
| 5445 | 5107 | .tag = tag, |
| 5446 | 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 | 5110 | return instruction.toValue(); |
| 5499 | 5111 | } |
| 5500 | 5112 | |
| ... | ... | @@ -5514,13 +5126,6 @@ pub const WipFunction = struct { |
| 5514 | 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 | 5129 | return instruction.toValue(); |
| 5525 | 5130 | } |
| 5526 | 5131 | |
| ... | ... | @@ -5542,14 +5147,6 @@ pub const WipFunction = struct { |
| 5542 | 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 | 5150 | return instruction.toValue(); |
| 5554 | 5151 | } |
| 5555 | 5152 | |
| ... | ... | @@ -5572,14 +5169,6 @@ pub const WipFunction = struct { |
| 5572 | 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 | 5172 | return instruction.toValue(); |
| 5584 | 5173 | } |
| 5585 | 5174 | |
| ... | ... | @@ -5615,13 +5204,6 @@ pub const WipFunction = struct { |
| 5615 | 5204 | }), |
| 5616 | 5205 | }); |
| 5617 | 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 | 5207 | return instruction.toValue(); |
| 5626 | 5208 | } |
| 5627 | 5209 | |
| ... | ... | @@ -5644,35 +5226,6 @@ pub const WipFunction = struct { |
| 5644 | 5226 | }), |
| 5645 | 5227 | }); |
| 5646 | 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 | 5229 | return instruction.toValue(); |
| 5677 | 5230 | } |
| 5678 | 5231 | |
| ... | ... | @@ -5712,15 +5265,6 @@ pub const WipFunction = struct { |
| 5712 | 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 | 5268 | return instruction.toValue(); |
| 5725 | 5269 | } |
| 5726 | 5270 | |
| ... | ... | @@ -5766,17 +5310,6 @@ pub const WipFunction = struct { |
| 5766 | 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 | 5313 | return instruction.toValue(); |
| 5781 | 5314 | } |
| 5782 | 5315 | |
| ... | ... | @@ -5820,13 +5353,6 @@ pub const WipFunction = struct { |
| 5820 | 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 | 5356 | return instruction; |
| 5831 | 5357 | } |
| 5832 | 5358 | |
| ... | ... | @@ -5844,13 +5370,6 @@ pub const WipFunction = struct { |
| 5844 | 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 | 5373 | return instruction; |
| 5855 | 5374 | } |
| 5856 | 5375 | |
| ... | ... | @@ -5893,25 +5412,6 @@ pub const WipFunction = struct { |
| 5893 | 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 | 5415 | return instruction.toValue(); |
| 5916 | 5416 | } |
| 5917 | 5417 | |
| ... | ... | @@ -5944,23 +5444,6 @@ pub const WipFunction = struct { |
| 5944 | 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 | 5447 | return instruction.toValue(); |
| 5965 | 5448 | } |
| 5966 | 5449 | |
| ... | ... | @@ -6020,28 +5503,6 @@ pub const WipFunction = struct { |
| 6020 | 5503 | }), |
| 6021 | 5504 | }); |
| 6022 | 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 | 5506 | return instruction.toValue(); |
| 6046 | 5507 | } |
| 6047 | 5508 | |
| ... | ... | @@ -6103,22 +5564,6 @@ pub const WipFunction = struct { |
| 6103 | 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 | 5567 | return instruction.toValue(); |
| 6123 | 5568 | } |
| 6124 | 5569 | |
| ... | ... | @@ -6131,7 +5576,7 @@ pub const WipFunction = struct { |
| 6131 | 5576 | ) Allocator.Error!Value { |
| 6132 | 5577 | return self.cmpTag(switch (cond) { |
| 6133 | 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 | 5582 | pub fn fcmp( |
| ... | ... | @@ -6149,7 +5594,7 @@ pub const WipFunction = struct { |
| 6149 | 5594 | .fast => "fast ", |
| 6150 | 5595 | } ++ @tagName(cond_tag)), |
| 6151 | 5596 | }, |
| 6152 | | }, @intFromEnum(cond), lhs, rhs, name); |
| 5597 | }, lhs, rhs, name); |
| 6153 | 5598 | } |
| 6154 | 5599 | |
| 6155 | 5600 | pub const WipPhi = struct { |
| ... | ... | @@ -6173,26 +5618,6 @@ pub const WipFunction = struct { |
| 6173 | 5618 | for (vals) |val| assert(val.typeOfWip(wip) == extra.data.type); |
| 6174 | 5619 | @memcpy(extra.trail.nextMut(incoming_len, Value, wip), vals); |
| 6175 | 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 | 5683 | }), |
| 6259 | 5684 | }); |
| 6260 | 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 | 5686 | return instruction.toValue(); |
| 6309 | 5687 | } |
| 6310 | 5688 | |
| ... | ... | @@ -6405,13 +5783,6 @@ pub const WipFunction = struct { |
| 6405 | 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 | 5786 | return instruction.toValue(); |
| 6416 | 5787 | } |
| 6417 | 5788 | |
| ... | ... | @@ -6923,18 +6294,12 @@ pub const WipFunction = struct { |
| 6923 | 6294 | self.instructions.deinit(self.builder.gpa); |
| 6924 | 6295 | for (self.blocks.items) |*b| b.instructions.deinit(self.builder.gpa); |
| 6925 | 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 | 6297 | self.* = undefined; |
| 6932 | 6298 | } |
| 6933 | 6299 | |
| 6934 | 6300 | fn cmpTag( |
| 6935 | 6301 | self: *WipFunction, |
| 6936 | 6302 | tag: Instruction.Tag, |
| 6937 | | cond: u32, |
| 6938 | 6303 | lhs: Value, |
| 6939 | 6304 | rhs: Value, |
| 6940 | 6305 | name: []const u8, |
| ... | ... | @@ -6994,113 +6359,6 @@ pub const WipFunction = struct { |
| 6994 | 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 | 6362 | return instruction.toValue(); |
| 7105 | 6363 | } |
| 7106 | 6364 | |
| ... | ... | @@ -7122,16 +6380,6 @@ pub const WipFunction = struct { |
| 7122 | 6380 | .data = self.addExtraAssumeCapacity(Instruction.Phi{ .type = ty }), |
| 7123 | 6381 | }); |
| 7124 | 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 | 6383 | return .{ .block = self.cursor.block, .instruction = instruction }; |
| 7136 | 6384 | } |
| 7137 | 6385 | |
| ... | ... | @@ -7159,19 +6407,6 @@ pub const WipFunction = struct { |
| 7159 | 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 | 6410 | return instruction.toValue(); |
| 7176 | 6411 | } |
| 7177 | 6412 | |
| ... | ... | @@ -7205,23 +6440,11 @@ pub const WipFunction = struct { |
| 7205 | 6440 | } |
| 7206 | 6441 | } |
| 7207 | 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 | 6443 | const final_name = if (name) |n| |
| 7211 | 6444 | if (self.builder.strip) .empty else try self.builder.string(n) |
| 7212 | 6445 | else |
| 7213 | 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 | 6448 | const index: Instruction.Index = @enumFromInt(self.instructions.len); |
| 7226 | 6449 | self.instructions.appendAssumeCapacity(instruction); |
| 7227 | 6450 | if (!self.builder.strip) { |
| ... | ... | @@ -7333,24 +6556,6 @@ pub const FloatCondition = enum(u4) { |
| 7333 | 6556 | ult = 12, |
| 7334 | 6557 | ule = 13, |
| 7335 | 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 | 6561 | pub const IntegerCondition = enum(u6) { |
| ... | ... | @@ -7364,20 +6569,6 @@ pub const IntegerCondition = enum(u6) { |
| 7364 | 6569 | sge = 39, |
| 7365 | 6570 | slt = 40, |
| 7366 | 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 | 6574 | pub const MemoryAccessKind = enum(u1) { |
| ... | ... | @@ -7427,18 +6618,6 @@ pub const AtomicOrdering = enum(u3) { |
| 7427 | 6618 | ) @TypeOf(writer).Error!void { |
| 7428 | 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 | 6623 | const MemoryAccessInfo = packed struct(u32) { |
| ... | ... | @@ -8259,16 +7438,6 @@ pub const Constant = enum(u32) { |
| 8259 | 7438 | pub fn fmt(self: Constant, builder: *Builder) std.fmt.Formatter(format) { |
| 8260 | 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 | 7443 | pub const Value = enum(u32) { |
| ... | ... | @@ -8343,14 +7512,6 @@ pub const Value = enum(u32) { |
| 8343 | 7512 | pub fn fmt(self: Value, function: Function.Index, builder: *Builder) std.fmt.Formatter(format) { |
| 8344 | 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 | 7517 | pub const MetadataString = enum(u32) { |
| ... | ... | @@ -8589,11 +7750,8 @@ pub const InitError = error{ |
| 8589 | 7750 | pub fn init(options: Options) InitError!Builder { |
| 8590 | 7751 | var self = Builder{ |
| 8591 | 7752 | .gpa = options.allocator, |
| 8592 | | .use_lib_llvm = options.use_lib_llvm, |
| 8593 | 7753 | .strip = options.strip, |
| 8594 | 7754 | |
| 8595 | | .llvm = undefined, |
| 8596 | | |
| 8597 | 7755 | .source_filename = .none, |
| 8598 | 7756 | .data_layout = .none, |
| 8599 | 7757 | .target_triple = .none, |
| ... | ... | @@ -8638,70 +7796,26 @@ pub fn init(options: Options) InitError!Builder { |
| 8638 | 7796 | .metadata_forward_references = .{}, |
| 8639 | 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 | 7799 | errdefer self.deinit(); |
| 8655 | 7800 | |
| 8656 | 7801 | try self.string_indices.append(self.gpa, 0); |
| 8657 | 7802 | assert(try self.string("") == .empty); |
| 8658 | 7803 | |
| 8659 | 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 | 7806 | if (options.triple.len > 0) { |
| 8669 | 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 | 7811 | const static_len = @typeInfo(Type).Enum.fields.len - 1; |
| 8694 | 7812 | try self.type_map.ensureTotalCapacity(self.gpa, static_len); |
| 8695 | 7813 | try self.type_items.ensureTotalCapacity(self.gpa, static_len); |
| 8696 | | if (self.useLibLlvm()) try self.llvm.types.ensureTotalCapacity(self.gpa, static_len); |
| 8697 | 7814 | inline for (@typeInfo(Type.Simple).Enum.fields) |simple_field| { |
| 8698 | 7815 | const result = self.getOrPutTypeNoExtraAssumeCapacity( |
| 8699 | 7816 | .{ .tag = .simple, .data = simple_field.value }, |
| 8700 | 7817 | ); |
| 8701 | 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 | 7820 | inline for (.{ 1, 8, 16, 29, 32, 64, 80, 128 }) |bits| |
| 8707 | 7821 | assert(self.intTypeAssumeCapacity(bits) == |
| ... | ... | @@ -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 | 7831 | try self.attributes_indices.append(self.gpa, 0); |
| 8722 | 7832 | assert(try self.attrs(&.{}) == .none); |
| 8723 | 7833 | assert(try self.fnAttrs(&.{}) == .none); |
| ... | ... | @@ -8732,20 +7842,6 @@ pub fn init(options: Options) InitError!Builder { |
| 8732 | 7842 | } |
| 8733 | 7843 | |
| 8734 | 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 | 7845 | self.module_asm.deinit(self.gpa); |
| 8750 | 7846 | |
| 8751 | 7847 | self.string_map.deinit(self.gpa); |
| ... | ... | @@ -8788,198 +7884,6 @@ pub fn deinit(self: *Builder) void { |
| 8788 | 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 | 7887 | pub fn setModuleAsm(self: *Builder) std.ArrayListUnmanaged(u8).Writer { |
| 8984 | 7888 | self.module_asm.clearRetainingCapacity(); |
| 8985 | 7889 | return self.appendModuleAsm(); |
| ... | ... | @@ -8992,8 +7896,6 @@ pub fn appendModuleAsm(self: *Builder) std.ArrayListUnmanaged(u8).Writer { |
| 8992 | 7896 | pub fn finishModuleAsm(self: *Builder) Allocator.Error!void { |
| 8993 | 7897 | if (self.module_asm.getLastOrNull()) |last| if (last != '\n') |
| 8994 | 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 | 7901 | pub fn string(self: *Builder, bytes: []const u8) Allocator.Error!String { |
| ... | ... | @@ -9109,94 +8011,13 @@ pub fn namedTypeSetBody( |
| 9109 | 8011 | const named_item = self.type_items.items[@intFromEnum(named_type)]; |
| 9110 | 8012 | self.type_extra.items[named_item.data + std.meta.fieldIndex(Type.NamedStructure, "body").?] = |
| 9111 | 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 | 8016 | pub fn attr(self: *Builder, attribute: Attribute) Allocator.Error!Attribute.Index { |
| 9132 | 8017 | try self.attributes.ensureUnusedCapacity(self.gpa, 1); |
| 9133 | | if (self.useLibLlvm()) try self.llvm.attributes.ensureUnusedCapacity(self.gpa, 1); |
| 9134 | 8018 | |
| 9135 | 8019 | const gop = self.attributes.getOrPutAssumeCapacity(attribute.toStorage()); |
| 9136 | | if (!gop.found_existing) { |
| 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 | | } |
| 8020 | if (!gop.found_existing) gop.value_ptr.* = {}; |
| 9200 | 8021 | return @enumFromInt(gop.index); |
| 9201 | 8022 | } |
| 9202 | 8023 | |
| ... | ... | @@ -9246,7 +8067,6 @@ pub fn addGlobalAssumeCapacity(self: *Builder, name: String, global: Global) Glo |
| 9246 | 8067 | global_gop.value_ptr.* = global; |
| 9247 | 8068 | const global_index: Global.Index = @enumFromInt(global_gop.index); |
| 9248 | 8069 | global_index.updateDsoLocal(self); |
| 9249 | | global_index.updateName(self); |
| 9250 | 8070 | return global_index; |
| 9251 | 8071 | } |
| 9252 | 8072 | |
| ... | ... | @@ -9282,12 +8102,6 @@ pub fn addAliasAssumeCapacity( |
| 9282 | 8102 | addr_space: AddrSpace, |
| 9283 | 8103 | aliasee: Constant, |
| 9284 | 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 | 8105 | const alias_index: Alias.Index = @enumFromInt(self.aliases.items.len); |
| 9292 | 8106 | self.aliases.appendAssumeCapacity(.{ .global = self.addGlobalAssumeCapacity(name, .{ |
| 9293 | 8107 | .addr_space = addr_space, |
| ... | ... | @@ -9316,13 +8130,6 @@ pub fn addVariableAssumeCapacity( |
| 9316 | 8130 | name: String, |
| 9317 | 8131 | addr_space: AddrSpace, |
| 9318 | 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 | 8133 | const variable_index: Variable.Index = @enumFromInt(self.variables.items.len); |
| 9327 | 8134 | self.variables.appendAssumeCapacity(.{ .global = self.addGlobalAssumeCapacity(name, .{ |
| 9328 | 8135 | .addr_space = addr_space, |
| ... | ... | @@ -9352,13 +8159,6 @@ pub fn addFunctionAssumeCapacity( |
| 9352 | 8159 | addr_space: AddrSpace, |
| 9353 | 8160 | ) Function.Index { |
| 9354 | 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 | 8162 | const function_index: Function.Index = @enumFromInt(self.functions.items.len); |
| 9363 | 8163 | self.functions.appendAssumeCapacity(.{ .global = self.addGlobalAssumeCapacity(name, .{ |
| 9364 | 8164 | .addr_space = addr_space, |
| ... | ... | @@ -9486,7 +8286,6 @@ pub fn bigIntConst(self: *Builder, ty: Type, value: std.math.big.int.Const) Allo |
| 9486 | 8286 | try self.constant_map.ensureUnusedCapacity(self.gpa, 1); |
| 9487 | 8287 | try self.constant_items.ensureUnusedCapacity(self.gpa, 1); |
| 9488 | 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 | 8289 | return self.bigIntConstAssumeCapacity(ty, value); |
| 9491 | 8290 | } |
| 9492 | 8291 | |
| ... | ... | @@ -9904,72 +8703,20 @@ pub fn asmValue( |
| 9904 | 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 | 8706 | pub fn dump(self: *Builder) void { |
| 9942 | | if (self.useLibLlvm()) |
| 9943 | | self.llvm.module.?.dump() |
| 9944 | | else |
| 9945 | | self.print(std.io.getStdErr().writer()) catch {}; |
| 8707 | self.print(std.io.getStdErr().writer()) catch {}; |
| 9946 | 8708 | } |
| 9947 | 8709 | |
| 9948 | 8710 | pub fn printToFile(self: *Builder, path: []const u8) Allocator.Error!bool { |
| 9949 | | const path_z = try self.gpa.dupeZ(u8, path); |
| 9950 | | defer self.gpa.free(path_z); |
| 9951 | | return self.printToFileZ(path_z); |
| 9952 | | } |
| 9953 | | |
| 9954 | | pub fn printToFileZ(self: *Builder, path: [*:0]const u8) bool { |
| 9955 | | if (self.useLibLlvm()) { |
| 9956 | | var error_message: [*:0]const u8 = undefined; |
| 9957 | | if (self.llvm.module.?.printModuleToFile(path, &error_message).toBool()) { |
| 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 | | } |
| 8711 | var file = std.fs.cwd().createFile(path, .{}) catch |err| { |
| 8712 | log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) }); |
| 8713 | return false; |
| 8714 | }; |
| 8715 | defer file.close(); |
| 8716 | self.print(file.writer()) catch |err| { |
| 8717 | log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) }); |
| 8718 | return false; |
| 8719 | }; |
| 9973 | 8720 | return true; |
| 9974 | 8721 | } |
| 9975 | 8722 | |
| ... | ... | @@ -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 | 9329 | const NoExtra = struct {}; |
| 10587 | 9330 | |
| 10588 | 9331 | fn isValidIdentifier(id: []const u8) bool { |
| ... | ... | @@ -10614,7 +9357,6 @@ fn printEscapedString( |
| 10614 | 9357 | } |
| 10615 | 9358 | |
| 10616 | 9359 | fn ensureUnusedGlobalCapacity(self: *Builder, name: String) Allocator.Error!void { |
| 10617 | | if (self.useLibLlvm()) try self.llvm.globals.ensureUnusedCapacity(self.gpa, 1); |
| 10618 | 9360 | try self.string_map.ensureUnusedCapacity(self.gpa, 1); |
| 10619 | 9361 | if (name.slice(self)) |id| { |
| 10620 | 9362 | const count: usize = comptime std.fmt.count("{d}" ++ .{0}, .{std.math.maxInt(u32)}); |
| ... | ... | @@ -10667,20 +9409,6 @@ fn fnTypeAssumeCapacity( |
| 10667 | 9409 | }), |
| 10668 | 9410 | }); |
| 10669 | 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 | 9413 | return @enumFromInt(gop.index); |
| 10686 | 9414 | } |
| ... | ... | @@ -10688,8 +9416,6 @@ fn fnTypeAssumeCapacity( |
| 10688 | 9416 | fn intTypeAssumeCapacity(self: *Builder, bits: u24) Type { |
| 10689 | 9417 | assert(bits > 0); |
| 10690 | 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 | 9419 | return result.type; |
| 10694 | 9420 | } |
| 10695 | 9421 | |
| ... | ... | @@ -10697,8 +9423,6 @@ fn ptrTypeAssumeCapacity(self: *Builder, addr_space: AddrSpace) Type { |
| 10697 | 9423 | const result = self.getOrPutTypeNoExtraAssumeCapacity( |
| 10698 | 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 | 9426 | return result.type; |
| 10703 | 9427 | } |
| 10704 | 9428 | |
| ... | ... | @@ -10736,10 +9460,6 @@ fn vectorTypeAssumeCapacity( |
| 10736 | 9460 | .tag = tag, |
| 10737 | 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 | 9464 | return @enumFromInt(gop.index); |
| 10745 | 9465 | } |
| ... | ... | @@ -10769,9 +9489,6 @@ fn arrayTypeAssumeCapacity(self: *Builder, len: u64, child: Type) Type { |
| 10769 | 9489 | .tag = .small_array, |
| 10770 | 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 | 9493 | return @enumFromInt(gop.index); |
| 10777 | 9494 | } else { |
| ... | ... | @@ -10802,9 +9519,6 @@ fn arrayTypeAssumeCapacity(self: *Builder, len: u64, child: Type) Type { |
| 10802 | 9519 | .tag = .array, |
| 10803 | 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 | 9523 | return @enumFromInt(gop.index); |
| 10810 | 9524 | } |
| ... | ... | @@ -10846,25 +9560,6 @@ fn structTypeAssumeCapacity( |
| 10846 | 9560 | }), |
| 10847 | 9561 | }); |
| 10848 | 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 | 9564 | return @enumFromInt(gop.index); |
| 10870 | 9565 | } |
| ... | ... | @@ -10906,9 +9601,6 @@ fn opaqueTypeAssumeCapacity(self: *Builder, name: String) Type { |
| 10906 | 9601 | }); |
| 10907 | 9602 | const result: Type = @enumFromInt(gop.index); |
| 10908 | 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 | 9604 | return result; |
| 10913 | 9605 | } |
| 10914 | 9606 | |
| ... | ... | @@ -10931,7 +9623,6 @@ fn ensureUnusedTypeCapacity( |
| 10931 | 9623 | self.gpa, |
| 10932 | 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 | 9628 | fn getOrPutTypeNoExtraAssumeCapacity(self: *Builder, item: Type.Item) struct { new: bool, type: Type } { |
| ... | ... | @@ -11108,44 +9799,6 @@ fn bigIntConstAssumeCapacity( |
| 11108 | 9799 | @ptrCast(self.constant_limbs.addManyAsArrayAssumeCapacity(Constant.Integer.limbs)); |
| 11109 | 9800 | extra.* = .{ .type = ty, .limbs_len = @intCast(canonical_value.limbs.len) }; |
| 11110 | 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 | 9803 | return @enumFromInt(gop.index); |
| 11151 | 9804 | } |
| ... | ... | @@ -11154,13 +9807,6 @@ fn halfConstAssumeCapacity(self: *Builder, val: f16) Constant { |
| 11154 | 9807 | const result = self.getOrPutConstantNoExtraAssumeCapacity( |
| 11155 | 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 | 9810 | return result.constant; |
| 11165 | 9811 | } |
| 11166 | 9812 | |
| ... | ... | @@ -11169,16 +9815,6 @@ fn bfloatConstAssumeCapacity(self: *Builder, val: f32) Constant { |
| 11169 | 9815 | const result = self.getOrPutConstantNoExtraAssumeCapacity( |
| 11170 | 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 | 9818 | return result.constant; |
| 11183 | 9819 | } |
| 11184 | 9820 | |
| ... | ... | @@ -11186,13 +9822,6 @@ fn floatConstAssumeCapacity(self: *Builder, val: f32) Constant { |
| 11186 | 9822 | const result = self.getOrPutConstantNoExtraAssumeCapacity( |
| 11187 | 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 | 9825 | return result.constant; |
| 11197 | 9826 | } |
| 11198 | 9827 | |
| ... | ... | @@ -11223,13 +9852,6 @@ fn doubleConstAssumeCapacity(self: *Builder, val: f64) Constant { |
| 11223 | 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 | 9856 | return @enumFromInt(gop.index); |
| 11235 | 9857 | } |
| ... | ... | @@ -11264,17 +9886,6 @@ fn fp128ConstAssumeCapacity(self: *Builder, val: f128) Constant { |
| 11264 | 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 | 9890 | return @enumFromInt(gop.index); |
| 11280 | 9891 | } |
| ... | ... | @@ -11308,17 +9919,6 @@ fn x86_fp80ConstAssumeCapacity(self: *Builder, val: f80) Constant { |
| 11308 | 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 | 9923 | return @enumFromInt(gop.index); |
| 11324 | 9924 | } |
| ... | ... | @@ -11353,14 +9953,6 @@ fn ppc_fp128ConstAssumeCapacity(self: *Builder, val: [2]f64) Constant { |
| 11353 | 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 | 9957 | return @enumFromInt(gop.index); |
| 11366 | 9958 | } |
| ... | ... | @@ -11370,8 +9962,6 @@ fn nullConstAssumeCapacity(self: *Builder, ty: Type) Constant { |
| 11370 | 9962 | const result = self.getOrPutConstantNoExtraAssumeCapacity( |
| 11371 | 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 | 9965 | return result.constant; |
| 11376 | 9966 | } |
| 11377 | 9967 | |
| ... | ... | @@ -11380,8 +9970,6 @@ fn noneConstAssumeCapacity(self: *Builder, ty: Type) Constant { |
| 11380 | 9970 | const result = self.getOrPutConstantNoExtraAssumeCapacity( |
| 11381 | 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 | 9973 | return result.constant; |
| 11386 | 9974 | } |
| 11387 | 9975 | |
| ... | ... | @@ -11416,20 +10004,6 @@ fn structConstAssumeCapacity( |
| 11416 | 10004 | else => unreachable, |
| 11417 | 10005 | }; |
| 11418 | 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 | 10007 | return result.constant; |
| 11434 | 10008 | } |
| 11435 | 10009 | |
| ... | ... | @@ -11458,20 +10032,6 @@ fn arrayConstAssumeCapacity( |
| 11458 | 10032 | } else return self.zeroInitConstAssumeCapacity(ty); |
| 11459 | 10033 | |
| 11460 | 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 | 10035 | return result.constant; |
| 11476 | 10036 | } |
| 11477 | 10037 | |
| ... | ... | @@ -11482,9 +10042,6 @@ fn stringConstAssumeCapacity(self: *Builder, val: String) Constant { |
| 11482 | 10042 | const result = self.getOrPutConstantNoExtraAssumeCapacity( |
| 11483 | 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 | 10045 | return result.constant; |
| 11489 | 10046 | } |
| 11490 | 10047 | |
| ... | ... | @@ -11495,9 +10052,6 @@ fn stringNullConstAssumeCapacity(self: *Builder, val: String) Constant { |
| 11495 | 10052 | const result = self.getOrPutConstantNoExtraAssumeCapacity( |
| 11496 | 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 | 10055 | return result.constant; |
| 11502 | 10056 | } |
| 11503 | 10057 | |
| ... | ... | @@ -11518,20 +10072,6 @@ fn vectorConstAssumeCapacity( |
| 11518 | 10072 | } else return self.zeroInitConstAssumeCapacity(ty); |
| 11519 | 10073 | |
| 11520 | 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 | 10075 | return result.constant; |
| 11536 | 10076 | } |
| 11537 | 10077 | |
| ... | ... | @@ -11569,20 +10109,6 @@ fn splatConstAssumeCapacity( |
| 11569 | 10109 | .tag = .splat, |
| 11570 | 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 | 10113 | return @enumFromInt(gop.index); |
| 11588 | 10114 | } |
| ... | ... | @@ -11624,8 +10150,6 @@ fn zeroInitConstAssumeCapacity(self: *Builder, ty: Type) Constant { |
| 11624 | 10150 | const result = self.getOrPutConstantNoExtraAssumeCapacity( |
| 11625 | 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 | 10153 | return result.constant; |
| 11630 | 10154 | } |
| 11631 | 10155 | |
| ... | ... | @@ -11641,8 +10165,6 @@ fn undefConstAssumeCapacity(self: *Builder, ty: Type) Constant { |
| 11641 | 10165 | const result = self.getOrPutConstantNoExtraAssumeCapacity( |
| 11642 | 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 | 10168 | return result.constant; |
| 11647 | 10169 | } |
| 11648 | 10170 | |
| ... | ... | @@ -11658,8 +10180,6 @@ fn poisonConstAssumeCapacity(self: *Builder, ty: Type) Constant { |
| 11658 | 10180 | const result = self.getOrPutConstantNoExtraAssumeCapacity( |
| 11659 | 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 | 10183 | return result.constant; |
| 11664 | 10184 | } |
| 11665 | 10185 | |
| ... | ... | @@ -11692,9 +10212,6 @@ fn blockAddrConstAssumeCapacity( |
| 11692 | 10212 | .tag = .blockaddress, |
| 11693 | 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 | 10216 | return @enumFromInt(gop.index); |
| 11700 | 10217 | } |
| ... | ... | @@ -11703,7 +10220,6 @@ fn dsoLocalEquivalentConstAssumeCapacity(self: *Builder, function: Function.Inde |
| 11703 | 10220 | const result = self.getOrPutConstantNoExtraAssumeCapacity( |
| 11704 | 10221 | .{ .tag = .dso_local_equivalent, .data = @intFromEnum(function) }, |
| 11705 | 10222 | ); |
| 11706 | | if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(undefined); |
| 11707 | 10223 | return result.constant; |
| 11708 | 10224 | } |
| 11709 | 10225 | |
| ... | ... | @@ -11711,7 +10227,6 @@ fn noCfiConstAssumeCapacity(self: *Builder, function: Function.Index) Constant { |
| 11711 | 10227 | const result = self.getOrPutConstantNoExtraAssumeCapacity( |
| 11712 | 10228 | .{ .tag = .no_cfi, .data = @intFromEnum(function) }, |
| 11713 | 10229 | ); |
| 11714 | | if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(undefined); |
| 11715 | 10230 | return result.constant; |
| 11716 | 10231 | } |
| 11717 | 10232 | |
| ... | ... | @@ -11801,22 +10316,6 @@ fn castConstAssumeCapacity(self: *Builder, tag: Constant.Tag, val: Constant, ty: |
| 11801 | 10316 | .tag = tag, |
| 11802 | 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 | 10320 | return @enumFromInt(gop.index); |
| 11822 | 10321 | } |
| ... | ... | @@ -11909,21 +10408,6 @@ fn gepConstAssumeCapacity( |
| 11909 | 10408 | }), |
| 11910 | 10409 | }); |
| 11911 | 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 | 10412 | return @enumFromInt(gop.index); |
| 11929 | 10413 | } |
| ... | ... | @@ -11958,9 +10442,6 @@ fn icmpConstAssumeCapacity( |
| 11958 | 10442 | .tag = .icmp, |
| 11959 | 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 | 10446 | return @enumFromInt(gop.index); |
| 11966 | 10447 | } |
| ... | ... | @@ -11995,9 +10476,6 @@ fn fcmpConstAssumeCapacity( |
| 11995 | 10476 | .tag = .fcmp, |
| 11996 | 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 | 10480 | return @enumFromInt(gop.index); |
| 12003 | 10481 | } |
| ... | ... | @@ -12031,9 +10509,6 @@ fn extractElementConstAssumeCapacity( |
| 12031 | 10509 | .tag = .extractelement, |
| 12032 | 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 | 10513 | return @enumFromInt(gop.index); |
| 12039 | 10514 | } |
| ... | ... | @@ -12068,9 +10543,6 @@ fn insertElementConstAssumeCapacity( |
| 12068 | 10543 | .tag = .insertelement, |
| 12069 | 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 | 10547 | return @enumFromInt(gop.index); |
| 12076 | 10548 | } |
| ... | ... | @@ -12109,9 +10581,6 @@ fn shuffleVectorConstAssumeCapacity( |
| 12109 | 10581 | .tag = .shufflevector, |
| 12110 | 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 | 10585 | return @enumFromInt(gop.index); |
| 12117 | 10586 | } |
| ... | ... | @@ -12166,18 +10635,6 @@ fn binConstAssumeCapacity( |
| 12166 | 10635 | .tag = tag, |
| 12167 | 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 | 10639 | return @enumFromInt(gop.index); |
| 12183 | 10640 | } |
| ... | ... | @@ -12220,21 +10677,6 @@ fn asmConstAssumeCapacity( |
| 12220 | 10677 | .tag = data.tag, |
| 12221 | 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 | 10681 | return @enumFromInt(gop.index); |
| 12240 | 10682 | } |
| ... | ... | @@ -12251,7 +10693,6 @@ fn ensureUnusedConstantCapacity( |
| 12251 | 10693 | self.gpa, |
| 12252 | 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 | 10698 | fn getOrPutConstantNoExtraAssumeCapacity( |
| ... | ... | @@ -15513,10 +13954,6 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 15513 | 13954 | const assert = std.debug.assert; |
| 15514 | 13955 | const build_options = @import("build_options"); |
| 15515 | 13956 | const builtin = @import("builtin"); |
| 15516 | | const llvm = if (build_options.have_llvm) |
| 15517 | | @import("bindings.zig") |
| 15518 | | else |
| 15519 | | @compileError("LLVM unavailable"); |
| 15520 | 13957 | const log = std.log.scoped(.llvm); |
| 15521 | 13958 | const std = @import("std"); |
| 15522 | 13959 | |