authorgravatar for timonkruiper@gmail.comTimon Kruiper <timonkruiper@gmail.com> 2020-12-19 11:22:49+01:00
committergravatar for timonkruiper@gmail.comTimon Kruiper <timonkruiper@gmail.com> 2020-12-28 21:19:40+01:00
log071417161d5d7ab91c32073693590ef161017dbe
tree891bfd9fecd90b9b341d95dfb78399788f62c3ed
parent4a0d64300bd9ab1a8c35c634856396e3413200f1

stage2: add initial impl of LLVM backend in self-hosted compiler


6 files changed, 813 insertions(+), 129 deletions(-)

CMakeLists.txt+1-1
...@@ -527,7 +527,6 @@ set(ZIG_STAGE2_SOURCES...@@ -527,7 +527,6 @@ set(ZIG_STAGE2_SOURCES
527 "${CMAKE_SOURCE_DIR}/src/codegen/aarch64.zig"527 "${CMAKE_SOURCE_DIR}/src/codegen/aarch64.zig"
528 "${CMAKE_SOURCE_DIR}/src/codegen/arm.zig"528 "${CMAKE_SOURCE_DIR}/src/codegen/arm.zig"
529 "${CMAKE_SOURCE_DIR}/src/codegen/c.zig"529 "${CMAKE_SOURCE_DIR}/src/codegen/c.zig"
530 "${CMAKE_SOURCE_DIR}/src/codegen/llvm.zig"
531 "${CMAKE_SOURCE_DIR}/src/codegen/riscv64.zig"530 "${CMAKE_SOURCE_DIR}/src/codegen/riscv64.zig"
532 "${CMAKE_SOURCE_DIR}/src/codegen/spu-mk2.zig"531 "${CMAKE_SOURCE_DIR}/src/codegen/spu-mk2.zig"
533 "${CMAKE_SOURCE_DIR}/src/codegen/wasm.zig"532 "${CMAKE_SOURCE_DIR}/src/codegen/wasm.zig"
...@@ -549,6 +548,7 @@ set(ZIG_STAGE2_SOURCES...@@ -549,6 +548,7 @@ set(ZIG_STAGE2_SOURCES
549 "${CMAKE_SOURCE_DIR}/src/link/cbe.h"548 "${CMAKE_SOURCE_DIR}/src/link/cbe.h"
550 "${CMAKE_SOURCE_DIR}/src/link/msdos-stub.bin"549 "${CMAKE_SOURCE_DIR}/src/link/msdos-stub.bin"
551 "${CMAKE_SOURCE_DIR}/src/liveness.zig"550 "${CMAKE_SOURCE_DIR}/src/liveness.zig"
551 "${CMAKE_SOURCE_DIR}/src/llvm_backend.zig"
552 "${CMAKE_SOURCE_DIR}/src/llvm_bindings.zig"552 "${CMAKE_SOURCE_DIR}/src/llvm_bindings.zig"
553 "${CMAKE_SOURCE_DIR}/src/main.zig"553 "${CMAKE_SOURCE_DIR}/src/main.zig"
554 "${CMAKE_SOURCE_DIR}/src/mingw.zig"554 "${CMAKE_SOURCE_DIR}/src/mingw.zig"
src/Compilation.zig+1-1
...@@ -2106,7 +2106,7 @@ pub fn addCCArgs(...@@ -2106,7 +2106,7 @@ pub fn addCCArgs(
2106 try argv.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS");2106 try argv.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS");
2107 }2107 }
21082108
2109 const llvm_triple = try @import("codegen/llvm.zig").targetTriple(arena, target);2109 const llvm_triple = try @import("llvm_backend.zig").targetTriple(arena, target);
2110 try argv.appendSlice(&[_][]const u8{ "-target", llvm_triple });2110 try argv.appendSlice(&[_][]const u8{ "-target", llvm_triple });
21112111
2112 switch (ext) {2112 switch (ext) {
src/codegen/llvm.zig deleted-125
...@@ -1,125 +0,0 @@
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3
4pub fn targetTriple(allocator: *Allocator, target: std.Target) ![]u8 {
5 const llvm_arch = switch (target.cpu.arch) {
6 .arm => "arm",
7 .armeb => "armeb",
8 .aarch64 => "aarch64",
9 .aarch64_be => "aarch64_be",
10 .aarch64_32 => "aarch64_32",
11 .arc => "arc",
12 .avr => "avr",
13 .bpfel => "bpfel",
14 .bpfeb => "bpfeb",
15 .hexagon => "hexagon",
16 .mips => "mips",
17 .mipsel => "mipsel",
18 .mips64 => "mips64",
19 .mips64el => "mips64el",
20 .msp430 => "msp430",
21 .powerpc => "powerpc",
22 .powerpc64 => "powerpc64",
23 .powerpc64le => "powerpc64le",
24 .r600 => "r600",
25 .amdgcn => "amdgcn",
26 .riscv32 => "riscv32",
27 .riscv64 => "riscv64",
28 .sparc => "sparc",
29 .sparcv9 => "sparcv9",
30 .sparcel => "sparcel",
31 .s390x => "s390x",
32 .tce => "tce",
33 .tcele => "tcele",
34 .thumb => "thumb",
35 .thumbeb => "thumbeb",
36 .i386 => "i386",
37 .x86_64 => "x86_64",
38 .xcore => "xcore",
39 .nvptx => "nvptx",
40 .nvptx64 => "nvptx64",
41 .le32 => "le32",
42 .le64 => "le64",
43 .amdil => "amdil",
44 .amdil64 => "amdil64",
45 .hsail => "hsail",
46 .hsail64 => "hsail64",
47 .spir => "spir",
48 .spir64 => "spir64",
49 .kalimba => "kalimba",
50 .shave => "shave",
51 .lanai => "lanai",
52 .wasm32 => "wasm32",
53 .wasm64 => "wasm64",
54 .renderscript32 => "renderscript32",
55 .renderscript64 => "renderscript64",
56 .ve => "ve",
57 .spu_2 => return error.LLVMBackendDoesNotSupportSPUMarkII,
58 };
59 // TODO Add a sub-arch for some architectures depending on CPU features.
60
61 const llvm_os = switch (target.os.tag) {
62 .freestanding => "unknown",
63 .ananas => "ananas",
64 .cloudabi => "cloudabi",
65 .dragonfly => "dragonfly",
66 .freebsd => "freebsd",
67 .fuchsia => "fuchsia",
68 .ios => "ios",
69 .kfreebsd => "kfreebsd",
70 .linux => "linux",
71 .lv2 => "lv2",
72 .macos => "macosx",
73 .netbsd => "netbsd",
74 .openbsd => "openbsd",
75 .solaris => "solaris",
76 .windows => "windows",
77 .haiku => "haiku",
78 .minix => "minix",
79 .rtems => "rtems",
80 .nacl => "nacl",
81 .cnk => "cnk",
82 .aix => "aix",
83 .cuda => "cuda",
84 .nvcl => "nvcl",
85 .amdhsa => "amdhsa",
86 .ps4 => "ps4",
87 .elfiamcu => "elfiamcu",
88 .tvos => "tvos",
89 .watchos => "watchos",
90 .mesa3d => "mesa3d",
91 .contiki => "contiki",
92 .amdpal => "amdpal",
93 .hermit => "hermit",
94 .hurd => "hurd",
95 .wasi => "wasi",
96 .emscripten => "emscripten",
97 .uefi => "windows",
98 .other => "unknown",
99 };
100
101 const llvm_abi = switch (target.abi) {
102 .none => "unknown",
103 .gnu => "gnu",
104 .gnuabin32 => "gnuabin32",
105 .gnuabi64 => "gnuabi64",
106 .gnueabi => "gnueabi",
107 .gnueabihf => "gnueabihf",
108 .gnux32 => "gnux32",
109 .code16 => "code16",
110 .eabi => "eabi",
111 .eabihf => "eabihf",
112 .android => "android",
113 .musl => "musl",
114 .musleabi => "musleabi",
115 .musleabihf => "musleabihf",
116 .msvc => "msvc",
117 .itanium => "itanium",
118 .cygnus => "cygnus",
119 .coreclr => "coreclr",
120 .simulator => "simulator",
121 .macabi => "macabi",
122 };
123
124 return std.fmt.allocPrint(allocator, "{}-unknown-{}-{}", .{ llvm_arch, llvm_os, llvm_abi });
125}
src/link/Elf.zig+43-2
...@@ -24,6 +24,7 @@ const build_options = @import("build_options");...@@ -24,6 +24,7 @@ const build_options = @import("build_options");
24const target_util = @import("../target.zig");24const target_util = @import("../target.zig");
25const glibc = @import("../glibc.zig");25const glibc = @import("../glibc.zig");
26const Cache = @import("../Cache.zig");26const Cache = @import("../Cache.zig");
27const llvm_backend = @import("../llvm_backend.zig");
2728
28const default_entry_addr = 0x8000000;29const default_entry_addr = 0x8000000;
2930
...@@ -33,6 +34,9 @@ base: File,...@@ -33,6 +34,9 @@ base: File,
3334
34ptr_width: PtrWidth,35ptr_width: PtrWidth,
3536
37/// If this is not null, an object file is created by LLVM and linked with LLD afterwards.
38llvm_ir_module: ?*llvm_backend.LLVMIRModule = null,
39
36/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write.40/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write.
37/// Same order as in the file.41/// Same order as in the file.
38sections: std.ArrayListUnmanaged(elf.Elf64_Shdr) = std.ArrayListUnmanaged(elf.Elf64_Shdr){},42sections: std.ArrayListUnmanaged(elf.Elf64_Shdr) = std.ArrayListUnmanaged(elf.Elf64_Shdr){},
...@@ -224,7 +228,13 @@ pub const SrcFn = struct {...@@ -224,7 +228,13 @@ pub const SrcFn = struct {
224pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*Elf {228pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*Elf {
225 assert(options.object_format == .elf);229 assert(options.object_format == .elf);
226230
227 if (options.use_llvm) return error.LLVMBackendUnimplementedForELF; // TODO231 if (options.use_llvm) {
232 const self = try createEmpty(allocator, options);
233 errdefer self.base.destroy();
234
235 self.llvm_ir_module = try llvm_backend.LLVMIRModule.create(allocator, sub_path, options);
236 return self;
237 }
228238
229 const file = try options.emit.?.directory.handle.createFile(sub_path, .{239 const file = try options.emit.?.directory.handle.createFile(sub_path, .{
230 .truncate = false,240 .truncate = false,
...@@ -288,6 +298,7 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*Elf {...@@ -288,6 +298,7 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*Elf {
288}298}
289299
290pub fn deinit(self: *Elf) void {300pub fn deinit(self: *Elf) void {
301 if (self.llvm_ir_module) |ir_module| ir_module.deinit(self.base.allocator);
291 self.sections.deinit(self.base.allocator);302 self.sections.deinit(self.base.allocator);
292 self.program_headers.deinit(self.base.allocator);303 self.program_headers.deinit(self.base.allocator);
293 self.shstrtab.deinit(self.base.allocator);304 self.shstrtab.deinit(self.base.allocator);
...@@ -423,6 +434,8 @@ fn updateString(self: *Elf, old_str_off: u32, new_name: []const u8) !u32 {...@@ -423,6 +434,8 @@ fn updateString(self: *Elf, old_str_off: u32, new_name: []const u8) !u32 {
423}434}
424435
425pub fn populateMissingMetadata(self: *Elf) !void {436pub fn populateMissingMetadata(self: *Elf) !void {
437 if (self.llvm_ir_module) |_| return;
438
426 const small_ptr = switch (self.ptr_width) {439 const small_ptr = switch (self.ptr_width) {
427 .p32 => true,440 .p32 => true,
428 .p64 => false,441 .p64 => false,
...@@ -727,6 +740,11 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {...@@ -727,6 +740,11 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
727 const tracy = trace(@src());740 const tracy = trace(@src());
728 defer tracy.end();741 defer tracy.end();
729742
743 if (self.llvm_ir_module) |llvm_ir_module| {
744 try llvm_ir_module.flushModule(comp);
745 return;
746 }
747
730 // TODO This linker code currently assumes there is only 1 compilation unit and it corresponds to the748 // TODO This linker code currently assumes there is only 1 compilation unit and it corresponds to the
731 // Zig source code.749 // Zig source code.
732 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;750 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
...@@ -1261,6 +1279,9 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1261,6 +1279,9 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1261 const stack_size = self.base.options.stack_size_override orelse 16777216;1279 const stack_size = self.base.options.stack_size_override orelse 16777216;
1262 const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;1280 const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;
1263 const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt) blk: {1281 const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt) blk: {
1282 // TODO: remove when stage2 can build compiler_rt.zig
1283 if (!build_options.is_stage1) break :blk null;
1284
1264 if (is_exe_or_dyn_lib) {1285 if (is_exe_or_dyn_lib) {
1265 break :blk comp.compiler_rt_static_lib.?.full_object_path;1286 break :blk comp.compiler_rt_static_lib.?.full_object_path;
1266 } else {1287 } else {
...@@ -1552,7 +1573,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1552,7 +1573,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1552 }1573 }
15531574
1554 // libc1575 // libc
1555 if (is_exe_or_dyn_lib and !self.base.options.skip_linker_dependencies and !self.base.options.link_libc) {1576 // TODO: enable when stage2 can build c.zig
1577 if (is_exe_or_dyn_lib and
1578 !self.base.options.skip_linker_dependencies and
1579 !self.base.options.link_libc and
1580 build_options.is_stage1)
1581 {
1556 try argv.append(comp.libc_static_lib.?.full_object_path);1582 try argv.append(comp.libc_static_lib.?.full_object_path);
1557 }1583 }
15581584
...@@ -2046,6 +2072,8 @@ fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, al...@@ -2046,6 +2072,8 @@ fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, al
2046}2072}
20472073
2048pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void {2074pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void {
2075 if (self.llvm_ir_module) |_| return;
2076
2049 if (decl.link.elf.local_sym_index != 0) return;2077 if (decl.link.elf.local_sym_index != 0) return;
20502078
2051 try self.local_symbols.ensureCapacity(self.base.allocator, self.local_symbols.items.len + 1);2079 try self.local_symbols.ensureCapacity(self.base.allocator, self.local_symbols.items.len + 1);
...@@ -2082,6 +2110,8 @@ pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void {...@@ -2082,6 +2110,8 @@ pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void {
2082}2110}
20832111
2084pub fn freeDecl(self: *Elf, decl: *Module.Decl) void {2112pub fn freeDecl(self: *Elf, decl: *Module.Decl) void {
2113 if (self.llvm_ir_module) |_| return;
2114
2085 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.2115 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.
2086 self.freeTextBlock(&decl.link.elf);2116 self.freeTextBlock(&decl.link.elf);
2087 if (decl.link.elf.local_sym_index != 0) {2117 if (decl.link.elf.local_sym_index != 0) {
...@@ -2119,6 +2149,11 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {...@@ -2119,6 +2149,11 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
2119 const tracy = trace(@src());2149 const tracy = trace(@src());
2120 defer tracy.end();2150 defer tracy.end();
21212151
2152 if (self.llvm_ir_module) |llvm_ir_module| {
2153 try llvm_ir_module.updateDecl(module, decl);
2154 return;
2155 }
2156
2122 var code_buffer = std.ArrayList(u8).init(self.base.allocator);2157 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
2123 defer code_buffer.deinit();2158 defer code_buffer.deinit();
21242159
...@@ -2594,6 +2629,8 @@ pub fn updateDeclExports(...@@ -2594,6 +2629,8 @@ pub fn updateDeclExports(
2594 decl: *const Module.Decl,2629 decl: *const Module.Decl,
2595 exports: []const *Module.Export,2630 exports: []const *Module.Export,
2596) !void {2631) !void {
2632 if (self.llvm_ir_module) |_| return;
2633
2597 const tracy = trace(@src());2634 const tracy = trace(@src());
2598 defer tracy.end();2635 defer tracy.end();
25992636
...@@ -2667,6 +2704,8 @@ pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Dec...@@ -2667,6 +2704,8 @@ pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Dec
2667 const tracy = trace(@src());2704 const tracy = trace(@src());
2668 defer tracy.end();2705 defer tracy.end();
26692706
2707 if (self.llvm_ir_module) |_| return;
2708
2670 const container_scope = decl.scope.cast(Module.Scope.Container).?;2709 const container_scope = decl.scope.cast(Module.Scope.Container).?;
2671 const tree = container_scope.file_scope.contents.tree;2710 const tree = container_scope.file_scope.contents.tree;
2672 const file_ast_decls = tree.root_node.decls();2711 const file_ast_decls = tree.root_node.decls();
...@@ -2685,6 +2724,8 @@ pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Dec...@@ -2685,6 +2724,8 @@ pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Dec
2685}2724}
26862725
2687pub fn deleteExport(self: *Elf, exp: Export) void {2726pub fn deleteExport(self: *Elf, exp: Export) void {
2727 if (self.llvm_ir_module) |_| return;
2728
2688 const sym_index = exp.sym_index orelse return;2729 const sym_index = exp.sym_index orelse return;
2689 self.global_symbol_free_list.append(self.base.allocator, sym_index) catch {};2730 self.global_symbol_free_list.append(self.base.allocator, sym_index) catch {};
2690 self.global_symbols.items[sym_index].st_info = 0;2731 self.global_symbols.items[sym_index].st_info = 0;
src/llvm_backend.zig created+410
...@@ -0,0 +1,410 @@
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3const Compilation = @import("Compilation.zig");
4const llvm = @import("llvm_bindings.zig");
5const link = @import("link.zig");
6
7const Module = @import("Module.zig");
8const TypedValue = @import("TypedValue.zig");
9const ir = @import("ir.zig");
10const Inst = ir.Inst;
11
12const Value = @import("value.zig").Value;
13const Type = @import("type.zig").Type;
14
15pub fn targetTriple(allocator: *Allocator, target: std.Target) ![:0]u8 {
16 const llvm_arch = switch (target.cpu.arch) {
17 .arm => "arm",
18 .armeb => "armeb",
19 .aarch64 => "aarch64",
20 .aarch64_be => "aarch64_be",
21 .aarch64_32 => "aarch64_32",
22 .arc => "arc",
23 .avr => "avr",
24 .bpfel => "bpfel",
25 .bpfeb => "bpfeb",
26 .hexagon => "hexagon",
27 .mips => "mips",
28 .mipsel => "mipsel",
29 .mips64 => "mips64",
30 .mips64el => "mips64el",
31 .msp430 => "msp430",
32 .powerpc => "powerpc",
33 .powerpc64 => "powerpc64",
34 .powerpc64le => "powerpc64le",
35 .r600 => "r600",
36 .amdgcn => "amdgcn",
37 .riscv32 => "riscv32",
38 .riscv64 => "riscv64",
39 .sparc => "sparc",
40 .sparcv9 => "sparcv9",
41 .sparcel => "sparcel",
42 .s390x => "s390x",
43 .tce => "tce",
44 .tcele => "tcele",
45 .thumb => "thumb",
46 .thumbeb => "thumbeb",
47 .i386 => "i386",
48 .x86_64 => "x86_64",
49 .xcore => "xcore",
50 .nvptx => "nvptx",
51 .nvptx64 => "nvptx64",
52 .le32 => "le32",
53 .le64 => "le64",
54 .amdil => "amdil",
55 .amdil64 => "amdil64",
56 .hsail => "hsail",
57 .hsail64 => "hsail64",
58 .spir => "spir",
59 .spir64 => "spir64",
60 .kalimba => "kalimba",
61 .shave => "shave",
62 .lanai => "lanai",
63 .wasm32 => "wasm32",
64 .wasm64 => "wasm64",
65 .renderscript32 => "renderscript32",
66 .renderscript64 => "renderscript64",
67 .ve => "ve",
68 .spu_2 => return error.LLVMBackendDoesNotSupportSPUMarkII,
69 };
70 // TODO Add a sub-arch for some architectures depending on CPU features.
71
72 const llvm_os = switch (target.os.tag) {
73 .freestanding => "unknown",
74 .ananas => "ananas",
75 .cloudabi => "cloudabi",
76 .dragonfly => "dragonfly",
77 .freebsd => "freebsd",
78 .fuchsia => "fuchsia",
79 .ios => "ios",
80 .kfreebsd => "kfreebsd",
81 .linux => "linux",
82 .lv2 => "lv2",
83 .macos => "macosx",
84 .netbsd => "netbsd",
85 .openbsd => "openbsd",
86 .solaris => "solaris",
87 .windows => "windows",
88 .haiku => "haiku",
89 .minix => "minix",
90 .rtems => "rtems",
91 .nacl => "nacl",
92 .cnk => "cnk",
93 .aix => "aix",
94 .cuda => "cuda",
95 .nvcl => "nvcl",
96 .amdhsa => "amdhsa",
97 .ps4 => "ps4",
98 .elfiamcu => "elfiamcu",
99 .tvos => "tvos",
100 .watchos => "watchos",
101 .mesa3d => "mesa3d",
102 .contiki => "contiki",
103 .amdpal => "amdpal",
104 .hermit => "hermit",
105 .hurd => "hurd",
106 .wasi => "wasi",
107 .emscripten => "emscripten",
108 .uefi => "windows",
109 .other => "unknown",
110 };
111
112 const llvm_abi = switch (target.abi) {
113 .none => "unknown",
114 .gnu => "gnu",
115 .gnuabin32 => "gnuabin32",
116 .gnuabi64 => "gnuabi64",
117 .gnueabi => "gnueabi",
118 .gnueabihf => "gnueabihf",
119 .gnux32 => "gnux32",
120 .code16 => "code16",
121 .eabi => "eabi",
122 .eabihf => "eabihf",
123 .android => "android",
124 .musl => "musl",
125 .musleabi => "musleabi",
126 .musleabihf => "musleabihf",
127 .msvc => "msvc",
128 .itanium => "itanium",
129 .cygnus => "cygnus",
130 .coreclr => "coreclr",
131 .simulator => "simulator",
132 .macabi => "macabi",
133 };
134
135 return std.fmt.allocPrintZ(allocator, "{}-unknown-{}-{}", .{ llvm_arch, llvm_os, llvm_abi });
136}
137
138pub const LLVMIRModule = struct {
139 llvm_module: *const llvm.ModuleRef,
140 target_machine: *const llvm.TargetMachineRef,
141 output_path: []const u8,
142
143 gpa: *Allocator,
144 err_msg: ?*Compilation.ErrorMsg = null,
145
146 pub fn create(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*LLVMIRModule {
147 const self = try allocator.create(LLVMIRModule);
148 errdefer allocator.destroy(self);
149
150 const gpa = options.module.?.gpa;
151
152 initializeLLVMTargets();
153
154 const root_nameZ = try gpa.dupeZ(u8, options.root_name);
155 defer gpa.free(root_nameZ);
156 const llvm_module = llvm.ModuleRef.createWithName(root_nameZ.ptr);
157 errdefer llvm_module.disposeModule();
158
159 const llvm_target_triple = try targetTriple(gpa, options.target);
160 defer gpa.free(llvm_target_triple);
161
162 var error_message: [*:0]const u8 = undefined;
163 var target_ref: *const llvm.TargetRef = undefined;
164 if (llvm.TargetRef.getTargetFromTriple(llvm_target_triple.ptr, &target_ref, &error_message)) {
165 defer llvm.disposeMessage(error_message);
166
167 const stderr = std.io.getStdErr().outStream();
168 try stderr.print(
169 \\Zig is expecting LLVM to understand this target: '{s}'
170 \\However LLVM responded with: "{s}"
171 \\Zig is unable to continue. This is a bug in Zig:
172 \\https://github.com/ziglang/zig/issues/438
173 \\
174 ,
175 .{
176 llvm_target_triple,
177 error_message,
178 },
179 );
180 return error.InvalidLLVMTriple;
181 }
182
183 const opt_level: llvm.CodeGenOptLevel = if (options.optimize_mode == .Debug) .None else .Aggressive;
184 const target_machine = llvm.TargetMachineRef.createTargetMachine(
185 target_ref,
186 llvm_target_triple.ptr,
187 "",
188 "",
189 opt_level,
190 .Static,
191 .Default,
192 );
193 errdefer target_machine.disposeTargetMachine();
194
195 self.* = .{
196 .llvm_module = llvm_module,
197 .target_machine = target_machine,
198 .output_path = sub_path,
199 .gpa = gpa,
200 };
201 return self;
202 }
203
204 pub fn deinit(self: *LLVMIRModule, allocator: *Allocator) void {
205 self.llvm_module.disposeModule();
206 self.target_machine.disposeTargetMachine();
207 allocator.destroy(self);
208 }
209
210 fn initializeLLVMTargets() void {
211 llvm.initializeAllTargets();
212 llvm.initializeAllTargetInfos();
213 llvm.initializeAllTargetMCs();
214 llvm.initializeAllAsmPrinters();
215 llvm.initializeAllAsmParsers();
216 }
217
218 pub fn flushModule(self: *LLVMIRModule, comp: *Compilation) !void {
219 {
220 var error_message: [*:0]const u8 = undefined;
221 // verifyModule always allocs the error_message even if there is no error
222 defer llvm.disposeMessage(error_message);
223
224 if (self.llvm_module.verifyModule(.ReturnStatus, &error_message)) {
225 const stderr = std.io.getStdErr().outStream();
226 try stderr.print("broken LLVM module found: {s}\nThis is a bug in the Zig compiler.", .{error_message});
227 return error.BrokenLLVMModule;
228 }
229 }
230
231 if (comp.verbose_llvm_ir) {
232 const dump = self.llvm_module.printToString();
233 defer llvm.disposeMessage(dump);
234
235 const stderr = std.io.getStdErr().outStream();
236 try stderr.writeAll(std.mem.spanZ(dump));
237 }
238
239 const output_pathZ = try self.gpa.dupeZ(u8, self.output_path);
240 defer self.gpa.free(output_pathZ);
241
242 var error_message: [*:0]const u8 = undefined;
243 // TODO: where to put the output object, zig-cache something?
244 // TODO: caching?
245 if (self.target_machine.emitToFile(
246 self.llvm_module,
247 output_pathZ.ptr,
248 .ObjectFile,
249 &error_message,
250 )) {
251 defer llvm.disposeMessage(error_message);
252
253 const stderr = std.io.getStdErr().outStream();
254 try stderr.print("LLVM failed to emit file: {s}\n", .{error_message});
255 return error.FailedToEmit;
256 }
257 }
258
259 pub fn updateDecl(self: *LLVMIRModule, module: *Module, decl: *Module.Decl) !void {
260 const typed_value = decl.typed_value.most_recent.typed_value;
261 self.generate(module, typed_value, decl.src()) catch |err| switch (err) {
262 error.CodegenFail => {
263 decl.analysis = .codegen_failure;
264 try module.failed_decls.put(module.gpa, decl, self.err_msg.?);
265 return;
266 },
267 else => |e| return e,
268 };
269 }
270
271 fn generate(self: *LLVMIRModule, module: *Module, typed_value: TypedValue, src: usize) !void {
272 switch (typed_value.ty.zigTypeTag()) {
273 .Fn => {
274 const func = typed_value.val.cast(Value.Payload.Function).?.func;
275
276 var codegen = CodeGen{
277 .module = module,
278 .llvm_module = self.llvm_module,
279 .builder = llvm.BuilderRef.createBuilder(),
280 };
281 defer codegen.builder.disposeBuilder();
282
283 const llvm_func = try codegen.resolveLLVMFunction(func);
284
285 // We remove all the basic blocks of a function to support incremental
286 // compilation!
287 // TODO: remove all basic blocks if functions can have more than one
288 if (llvm_func.getFirstBasicBlock()) |bb| {
289 bb.deleteBasicBlock();
290 }
291
292 const entry_block = llvm_func.appendBasicBlock("Entry");
293 codegen.builder.positionBuilderAtEnd(entry_block);
294
295 const instructions = func.analysis.success.instructions;
296 for (instructions) |inst| {
297 switch (inst.tag) {
298 .breakpoint => try codegen.generateBreakpoint(inst.castTag(.breakpoint).?),
299 .call => try codegen.generateCall(inst.castTag(.call).?),
300 .unreach => codegen.generateUnreach(inst.castTag(.unreach).?),
301 .retvoid => codegen.generateRetVoid(inst.castTag(.retvoid).?),
302 .dbg_stmt => {
303 // TODO: implement debug info
304 },
305 else => |tag| return self.fail(src, "TODO implement LLVM codegen for Zir instruction: {}", .{tag}),
306 }
307 }
308 },
309 else => |ty| return self.fail(src, "TODO implement LLVM codegen for top-level decl type: {}", .{ty}),
310 }
311 }
312
313 pub fn fail(self: *LLVMIRModule, src: usize, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
314 @setCold(true);
315 std.debug.assert(self.err_msg == null);
316 self.err_msg = try Compilation.ErrorMsg.create(self.gpa, src, format, args);
317 return error.CodegenFail;
318 }
319};
320
321const CodeGen = struct {
322 module: *Module,
323 llvm_module: *const llvm.ModuleRef,
324 builder: *const llvm.BuilderRef,
325
326 fn generateCall(codegen: *CodeGen, inst: *Inst.Call) !void {
327 if (inst.func.cast(Inst.Constant)) |func_inst| {
328 if (func_inst.val.cast(Value.Payload.Function)) |func_val| {
329 const func = func_val.func;
330 const zig_fn_type = func.owner_decl.typed_value.most_recent.typed_value.ty;
331 const llvm_fn = try codegen.resolveLLVMFunction(func);
332
333 // TODO: handle more arguments, inst.args
334
335 // TODO: LLVMBuildCall2 handles opaque function pointers, according to llvm docs
336 // Do we need that?
337 const call = codegen.builder.buildCall(llvm_fn, null, 0, "");
338
339 if (zig_fn_type.fnReturnType().zigTypeTag() == .NoReturn) {
340 _ = codegen.builder.buildUnreachable();
341 }
342 }
343 }
344 }
345
346 fn generateRetVoid(codegen: *CodeGen, inst: *Inst.NoOp) void {
347 _ = codegen.builder.buildRetVoid();
348 }
349
350 fn generateUnreach(codegen: *CodeGen, inst: *Inst.NoOp) void {
351 _ = codegen.builder.buildUnreachable();
352 }
353
354 fn generateBreakpoint(codegen: *CodeGen, inst: *Inst.NoOp) !void {
355 // TODO: Store this function somewhere such that we dont have to add it again
356 const fn_type = llvm.TypeRef.functionType(llvm.voidType(), null, 0, false);
357 const func = codegen.llvm_module.addFunction("llvm.debugtrap", fn_type);
358 // TODO: add assertion: LLVMGetIntrinsicID
359 _ = codegen.builder.buildCall(func, null, 0, "");
360 }
361
362 /// If the llvm function does not exist, create it
363 fn resolveLLVMFunction(codegen: *CodeGen, func: *Module.Fn) !*const llvm.ValueRef {
364 // TODO: do we want to store this in our own datastructure?
365 if (codegen.llvm_module.getNamedFunction(func.owner_decl.name)) |llvm_fn| return llvm_fn;
366
367 const zig_fn_type = func.owner_decl.typed_value.most_recent.typed_value.ty;
368 const return_type = zig_fn_type.fnReturnType();
369
370 const fn_param_len = zig_fn_type.fnParamLen();
371
372 const fn_param_types = try codegen.module.gpa.alloc(Type, fn_param_len);
373 defer codegen.module.gpa.free(fn_param_types);
374 zig_fn_type.fnParamTypes(fn_param_types);
375
376 const llvm_param = try codegen.module.gpa.alloc(*const llvm.TypeRef, fn_param_len);
377 defer codegen.module.gpa.free(llvm_param);
378
379 for (fn_param_types) |fn_param, i| {
380 llvm_param[i] = codegen.getLLVMType(fn_param);
381 }
382
383 const fn_type = llvm.TypeRef.functionType(
384 codegen.getLLVMType(return_type),
385 if (fn_param_len == 0) null else llvm_param.ptr,
386 @intCast(c_uint, fn_param_len),
387 false,
388 );
389 const llvm_fn = codegen.llvm_module.addFunction(func.owner_decl.name, fn_type);
390
391 if (return_type.zigTypeTag() == .NoReturn) {
392 llvm_fn.addFnAttr("noreturn");
393 }
394
395 return llvm_fn;
396 }
397
398 fn getLLVMType(codegen: *CodeGen, t: Type) *const llvm.TypeRef {
399 switch (t.zigTypeTag()) {
400 .Void => return llvm.voidType(),
401 .NoReturn => return llvm.voidType(),
402 .Int => {
403 const info = t.intInfo(codegen.module.getTarget());
404 return llvm.intType(info.bits);
405 },
406 .Bool => return llvm.intType(1),
407 else => unreachable,
408 }
409 }
410};
src/llvm_bindings.zig+358
...@@ -1,6 +1,364 @@...@@ -1,6 +1,364 @@
1//! We do this instead of @cImport because the self-hosted compiler is easier1//! We do this instead of @cImport because the self-hosted compiler is easier
2//! to bootstrap if it does not depend on translate-c.2//! to bootstrap if it does not depend on translate-c.
33
4const std = @import("std");
5const assert = std.debug.assert;
6
7const LLVMBool = bool;
8pub const LLVMAttributeIndex = c_uint;
9
10pub const ValueRef = opaque {
11 pub const addAttributeAtIndex = LLVMAddAttributeAtIndex;
12 extern fn LLVMAddAttributeAtIndex(*const ValueRef, Idx: LLVMAttributeIndex, A: *const AttributeRef) void;
13
14 pub const appendBasicBlock = LLVMAppendBasicBlock;
15 extern fn LLVMAppendBasicBlock(Fn: *const ValueRef, Name: [*:0]const u8) *const BasicBlockRef;
16
17 pub const getFirstBasicBlock = LLVMGetFirstBasicBlock;
18 extern fn LLVMGetFirstBasicBlock(Fn: *const ValueRef) ?*const BasicBlockRef;
19
20 // Helper functions
21 // TODO: Do we want to put these functions here? It allows for convienient function calls
22 // on ValueRef: llvm_fn.addFnAttr("noreturn")
23 fn addAttr(val: *const ValueRef, index: LLVMAttributeIndex, name: []const u8) void {
24 const kind_id = getEnumAttributeKindForName(name.ptr, name.len);
25 assert(kind_id != 0);
26 const llvm_attr = ContextRef.getGlobal().createEnumAttribute(kind_id, 0);
27 val.addAttributeAtIndex(index, llvm_attr);
28 }
29
30 pub fn addFnAttr(val: *const ValueRef, attr_name: []const u8) void {
31 // TODO: improve this API, `addAttr(-1, attr_name)`
32 val.addAttr(std.math.maxInt(LLVMAttributeIndex), attr_name);
33 }
34};
35
36pub const TypeRef = opaque {
37 pub const functionType = LLVMFunctionType;
38 extern fn LLVMFunctionType(ReturnType: *const TypeRef, ParamTypes: ?[*]*const TypeRef, ParamCount: c_uint, IsVarArg: LLVMBool) *const TypeRef;
39};
40
41pub const ModuleRef = opaque {
42 pub const createWithName = LLVMModuleCreateWithName;
43 extern fn LLVMModuleCreateWithName(ModuleID: [*:0]const u8) *const ModuleRef;
44
45 pub const disposeModule = LLVMDisposeModule;
46 extern fn LLVMDisposeModule(*const ModuleRef) void;
47
48 pub const verifyModule = LLVMVerifyModule;
49 extern fn LLVMVerifyModule(*const ModuleRef, Action: VerifierFailureAction, OutMessage: *[*:0]const u8) LLVMBool;
50
51 pub const addFunction = LLVMAddFunction;
52 extern fn LLVMAddFunction(*const ModuleRef, Name: [*:0]const u8, FunctionTy: *const TypeRef) *const ValueRef;
53
54 pub const getNamedFunction = LLVMGetNamedFunction;
55 extern fn LLVMGetNamedFunction(*const ModuleRef, Name: [*:0]const u8) ?*const ValueRef;
56
57 pub const printToString = LLVMPrintModuleToString;
58 extern fn LLVMPrintModuleToString(*const ModuleRef) [*:0]const u8;
59};
60
61pub const disposeMessage = LLVMDisposeMessage;
62extern fn LLVMDisposeMessage(Message: [*:0]const u8) void;
63
64pub const VerifierFailureAction = extern enum {
65 AbortProcess,
66 PrintMessage,
67 ReturnStatus,
68};
69
70pub const voidType = LLVMVoidType;
71extern fn LLVMVoidType() *const TypeRef;
72
73pub const getEnumAttributeKindForName = LLVMGetEnumAttributeKindForName;
74extern fn LLVMGetEnumAttributeKindForName(Name: [*]const u8, SLen: usize) c_uint;
75
76pub const AttributeRef = opaque {};
77
78pub const ContextRef = opaque {
79 pub const createEnumAttribute = LLVMCreateEnumAttribute;
80 extern fn LLVMCreateEnumAttribute(*const ContextRef, KindID: c_uint, Val: u64) *const AttributeRef;
81
82 pub const getGlobal = LLVMGetGlobalContext;
83 extern fn LLVMGetGlobalContext() *const ContextRef;
84};
85
86pub const intType = LLVMIntType;
87extern fn LLVMIntType(NumBits: c_uint) *const TypeRef;
88
89pub const BuilderRef = opaque {
90 pub const createBuilder = LLVMCreateBuilder;
91 extern fn LLVMCreateBuilder() *const BuilderRef;
92
93 pub const disposeBuilder = LLVMDisposeBuilder;
94 extern fn LLVMDisposeBuilder(Builder: *const BuilderRef) void;
95
96 pub const positionBuilderAtEnd = LLVMPositionBuilderAtEnd;
97 extern fn LLVMPositionBuilderAtEnd(Builder: *const BuilderRef, Block: *const BasicBlockRef) void;
98
99 pub const getInsertBlock = LLVMGetInsertBlock;
100 extern fn LLVMGetInsertBlock(Builder: *const BuilderRef) *const BasicBlockRef;
101
102 pub const buildCall = LLVMBuildCall;
103 extern fn LLVMBuildCall(*const BuilderRef, Fn: *const ValueRef, Args: ?[*]*const ValueRef, NumArgs: c_uint, Name: [*:0]const u8) *const ValueRef;
104
105 pub const buildCall2 = LLVMBuildCall2;
106 extern fn LLVMBuildCall2(*const BuilderRef, *const TypeRef, Fn: *const ValueRef, Args: [*]*const ValueRef, NumArgs: c_uint, Name: [*:0]const u8) *const ValueRef;
107
108 pub const buildRetVoid = LLVMBuildRetVoid;
109 extern fn LLVMBuildRetVoid(*const BuilderRef) *const ValueRef;
110
111 pub const buildUnreachable = LLVMBuildUnreachable;
112 extern fn LLVMBuildUnreachable(*const BuilderRef) *const ValueRef;
113
114 pub const buildAlloca = LLVMBuildAlloca;
115 extern fn LLVMBuildAlloca(*const BuilderRef, Ty: *const TypeRef, Name: [*:0]const u8) *const ValueRef;
116};
117
118pub const BasicBlockRef = opaque {
119 pub const deleteBasicBlock = LLVMDeleteBasicBlock;
120 extern fn LLVMDeleteBasicBlock(BB: *const BasicBlockRef) void;
121};
122
123pub const TargetMachineRef = opaque {
124 pub const createTargetMachine = LLVMCreateTargetMachine;
125 extern fn LLVMCreateTargetMachine(
126 T: *const TargetRef,
127 Triple: [*:0]const u8,
128 CPU: [*:0]const u8,
129 Features: [*:0]const u8,
130 Level: CodeGenOptLevel,
131 Reloc: RelocMode,
132 CodeModel: CodeMode,
133 ) *const TargetMachineRef;
134
135 pub const disposeTargetMachine = LLVMDisposeTargetMachine;
136 extern fn LLVMDisposeTargetMachine(T: *const TargetMachineRef) void;
137
138 pub const emitToFile = LLVMTargetMachineEmitToFile;
139 extern fn LLVMTargetMachineEmitToFile(*const TargetMachineRef, M: *const ModuleRef, Filename: [*:0]const u8, codegen: CodeGenFileType, ErrorMessage: *[*:0]const u8) LLVMBool;
140};
141
142pub const CodeMode = extern enum {
143 Default,
144 JITDefault,
145 Tiny,
146 Small,
147 Kernel,
148 Medium,
149 Large,
150};
151
152pub const CodeGenOptLevel = extern enum {
153 None,
154 Less,
155 Default,
156 Aggressive,
157};
158
159pub const RelocMode = extern enum {
160 Default,
161 Static,
162 PIC,
163 DynamicNoPic,
164 ROPI,
165 RWPI,
166 ROPI_RWPI,
167};
168
169pub const CodeGenFileType = extern enum {
170 AssemblyFile,
171 ObjectFile,
172};
173
174pub const TargetRef = opaque {
175 pub const getTargetFromTriple = LLVMGetTargetFromTriple;
176 extern fn LLVMGetTargetFromTriple(Triple: [*:0]const u8, T: **const TargetRef, ErrorMessage: *[*:0]const u8) LLVMBool;
177};
178
179extern fn LLVMInitializeAArch64TargetInfo() void;
180extern fn LLVMInitializeAMDGPUTargetInfo() void;
181extern fn LLVMInitializeARMTargetInfo() void;
182extern fn LLVMInitializeAVRTargetInfo() void;
183extern fn LLVMInitializeBPFTargetInfo() void;
184extern fn LLVMInitializeHexagonTargetInfo() void;
185extern fn LLVMInitializeLanaiTargetInfo() void;
186extern fn LLVMInitializeMipsTargetInfo() void;
187extern fn LLVMInitializeMSP430TargetInfo() void;
188extern fn LLVMInitializeNVPTXTargetInfo() void;
189extern fn LLVMInitializePowerPCTargetInfo() void;
190extern fn LLVMInitializeRISCVTargetInfo() void;
191extern fn LLVMInitializeSparcTargetInfo() void;
192extern fn LLVMInitializeSystemZTargetInfo() void;
193extern fn LLVMInitializeWebAssemblyTargetInfo() void;
194extern fn LLVMInitializeX86TargetInfo() void;
195extern fn LLVMInitializeXCoreTargetInfo() void;
196extern fn LLVMInitializeAArch64Target() void;
197extern fn LLVMInitializeAMDGPUTarget() void;
198extern fn LLVMInitializeARMTarget() void;
199extern fn LLVMInitializeAVRTarget() void;
200extern fn LLVMInitializeBPFTarget() void;
201extern fn LLVMInitializeHexagonTarget() void;
202extern fn LLVMInitializeLanaiTarget() void;
203extern fn LLVMInitializeMipsTarget() void;
204extern fn LLVMInitializeMSP430Target() void;
205extern fn LLVMInitializeNVPTXTarget() void;
206extern fn LLVMInitializePowerPCTarget() void;
207extern fn LLVMInitializeRISCVTarget() void;
208extern fn LLVMInitializeSparcTarget() void;
209extern fn LLVMInitializeSystemZTarget() void;
210extern fn LLVMInitializeWebAssemblyTarget() void;
211extern fn LLVMInitializeX86Target() void;
212extern fn LLVMInitializeXCoreTarget() void;
213extern fn LLVMInitializeAArch64TargetMC() void;
214extern fn LLVMInitializeAMDGPUTargetMC() void;
215extern fn LLVMInitializeARMTargetMC() void;
216extern fn LLVMInitializeAVRTargetMC() void;
217extern fn LLVMInitializeBPFTargetMC() void;
218extern fn LLVMInitializeHexagonTargetMC() void;
219extern fn LLVMInitializeLanaiTargetMC() void;
220extern fn LLVMInitializeMipsTargetMC() void;
221extern fn LLVMInitializeMSP430TargetMC() void;
222extern fn LLVMInitializeNVPTXTargetMC() void;
223extern fn LLVMInitializePowerPCTargetMC() void;
224extern fn LLVMInitializeRISCVTargetMC() void;
225extern fn LLVMInitializeSparcTargetMC() void;
226extern fn LLVMInitializeSystemZTargetMC() void;
227extern fn LLVMInitializeWebAssemblyTargetMC() void;
228extern fn LLVMInitializeX86TargetMC() void;
229extern fn LLVMInitializeXCoreTargetMC() void;
230extern fn LLVMInitializeAArch64AsmPrinter() void;
231extern fn LLVMInitializeAMDGPUAsmPrinter() void;
232extern fn LLVMInitializeARMAsmPrinter() void;
233extern fn LLVMInitializeAVRAsmPrinter() void;
234extern fn LLVMInitializeBPFAsmPrinter() void;
235extern fn LLVMInitializeHexagonAsmPrinter() void;
236extern fn LLVMInitializeLanaiAsmPrinter() void;
237extern fn LLVMInitializeMipsAsmPrinter() void;
238extern fn LLVMInitializeMSP430AsmPrinter() void;
239extern fn LLVMInitializeNVPTXAsmPrinter() void;
240extern fn LLVMInitializePowerPCAsmPrinter() void;
241extern fn LLVMInitializeRISCVAsmPrinter() void;
242extern fn LLVMInitializeSparcAsmPrinter() void;
243extern fn LLVMInitializeSystemZAsmPrinter() void;
244extern fn LLVMInitializeWebAssemblyAsmPrinter() void;
245extern fn LLVMInitializeX86AsmPrinter() void;
246extern fn LLVMInitializeXCoreAsmPrinter() void;
247extern fn LLVMInitializeAArch64AsmParser() void;
248extern fn LLVMInitializeAMDGPUAsmParser() void;
249extern fn LLVMInitializeARMAsmParser() void;
250extern fn LLVMInitializeAVRAsmParser() void;
251extern fn LLVMInitializeBPFAsmParser() void;
252extern fn LLVMInitializeHexagonAsmParser() void;
253extern fn LLVMInitializeLanaiAsmParser() void;
254extern fn LLVMInitializeMipsAsmParser() void;
255extern fn LLVMInitializeMSP430AsmParser() void;
256extern fn LLVMInitializePowerPCAsmParser() void;
257extern fn LLVMInitializeRISCVAsmParser() void;
258extern fn LLVMInitializeSparcAsmParser() void;
259extern fn LLVMInitializeSystemZAsmParser() void;
260extern fn LLVMInitializeWebAssemblyAsmParser() void;
261extern fn LLVMInitializeX86AsmParser() void;
262
263pub const initializeAllTargetInfos = LLVMInitializeAllTargetInfos;
264fn LLVMInitializeAllTargetInfos() callconv(.C) void {
265 LLVMInitializeAArch64TargetInfo();
266 LLVMInitializeAMDGPUTargetInfo();
267 LLVMInitializeARMTargetInfo();
268 LLVMInitializeAVRTargetInfo();
269 LLVMInitializeBPFTargetInfo();
270 LLVMInitializeHexagonTargetInfo();
271 LLVMInitializeLanaiTargetInfo();
272 LLVMInitializeMipsTargetInfo();
273 LLVMInitializeMSP430TargetInfo();
274 LLVMInitializeNVPTXTargetInfo();
275 LLVMInitializePowerPCTargetInfo();
276 LLVMInitializeRISCVTargetInfo();
277 LLVMInitializeSparcTargetInfo();
278 LLVMInitializeSystemZTargetInfo();
279 LLVMInitializeWebAssemblyTargetInfo();
280 LLVMInitializeX86TargetInfo();
281 LLVMInitializeXCoreTargetInfo();
282}
283pub const initializeAllTargets = LLVMInitializeAllTargets;
284fn LLVMInitializeAllTargets() callconv(.C) void {
285 LLVMInitializeAArch64Target();
286 LLVMInitializeAMDGPUTarget();
287 LLVMInitializeARMTarget();
288 LLVMInitializeAVRTarget();
289 LLVMInitializeBPFTarget();
290 LLVMInitializeHexagonTarget();
291 LLVMInitializeLanaiTarget();
292 LLVMInitializeMipsTarget();
293 LLVMInitializeMSP430Target();
294 LLVMInitializeNVPTXTarget();
295 LLVMInitializePowerPCTarget();
296 LLVMInitializeRISCVTarget();
297 LLVMInitializeSparcTarget();
298 LLVMInitializeSystemZTarget();
299 LLVMInitializeWebAssemblyTarget();
300 LLVMInitializeX86Target();
301 LLVMInitializeXCoreTarget();
302}
303pub const initializeAllTargetMCs = LLVMInitializeAllTargetMCs;
304fn LLVMInitializeAllTargetMCs() callconv(.C) void {
305 LLVMInitializeAArch64TargetMC();
306 LLVMInitializeAMDGPUTargetMC();
307 LLVMInitializeARMTargetMC();
308 LLVMInitializeAVRTargetMC();
309 LLVMInitializeBPFTargetMC();
310 LLVMInitializeHexagonTargetMC();
311 LLVMInitializeLanaiTargetMC();
312 LLVMInitializeMipsTargetMC();
313 LLVMInitializeMSP430TargetMC();
314 LLVMInitializeNVPTXTargetMC();
315 LLVMInitializePowerPCTargetMC();
316 LLVMInitializeRISCVTargetMC();
317 LLVMInitializeSparcTargetMC();
318 LLVMInitializeSystemZTargetMC();
319 LLVMInitializeWebAssemblyTargetMC();
320 LLVMInitializeX86TargetMC();
321 LLVMInitializeXCoreTargetMC();
322}
323pub const initializeAllAsmPrinters = LLVMInitializeAllAsmPrinters;
324fn LLVMInitializeAllAsmPrinters() callconv(.C) void {
325 LLVMInitializeAArch64AsmPrinter();
326 LLVMInitializeAMDGPUAsmPrinter();
327 LLVMInitializeARMAsmPrinter();
328 LLVMInitializeAVRAsmPrinter();
329 LLVMInitializeBPFAsmPrinter();
330 LLVMInitializeHexagonAsmPrinter();
331 LLVMInitializeLanaiAsmPrinter();
332 LLVMInitializeMipsAsmPrinter();
333 LLVMInitializeMSP430AsmPrinter();
334 LLVMInitializeNVPTXAsmPrinter();
335 LLVMInitializePowerPCAsmPrinter();
336 LLVMInitializeRISCVAsmPrinter();
337 LLVMInitializeSparcAsmPrinter();
338 LLVMInitializeSystemZAsmPrinter();
339 LLVMInitializeWebAssemblyAsmPrinter();
340 LLVMInitializeX86AsmPrinter();
341 LLVMInitializeXCoreAsmPrinter();
342}
343pub const initializeAllAsmParsers = LLVMInitializeAllAsmParsers;
344fn LLVMInitializeAllAsmParsers() callconv(.C) void {
345 LLVMInitializeAArch64AsmParser();
346 LLVMInitializeAMDGPUAsmParser();
347 LLVMInitializeARMAsmParser();
348 LLVMInitializeAVRAsmParser();
349 LLVMInitializeBPFAsmParser();
350 LLVMInitializeHexagonAsmParser();
351 LLVMInitializeLanaiAsmParser();
352 LLVMInitializeMipsAsmParser();
353 LLVMInitializeMSP430AsmParser();
354 LLVMInitializePowerPCAsmParser();
355 LLVMInitializeRISCVAsmParser();
356 LLVMInitializeSparcAsmParser();
357 LLVMInitializeSystemZAsmParser();
358 LLVMInitializeWebAssemblyAsmParser();
359 LLVMInitializeX86AsmParser();
360}
361
4extern fn ZigLLDLinkCOFF(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int;362extern fn ZigLLDLinkCOFF(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int;
5extern fn ZigLLDLinkELF(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int;363extern fn ZigLLDLinkELF(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int;
6extern fn ZigLLDLinkMachO(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int;364extern fn ZigLLDLinkMachO(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int;