mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
stage2: add initial impl of LLVM backend in self-hosted compiler
This commit is contained in:
parent
4a0d64300b
commit
071417161d
@ -527,7 +527,6 @@ set(ZIG_STAGE2_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/aarch64.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/arm.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/c.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/llvm.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/riscv64.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/spu-mk2.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/wasm.zig"
|
||||
@ -549,6 +548,7 @@ set(ZIG_STAGE2_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/src/link/cbe.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/link/msdos-stub.bin"
|
||||
"${CMAKE_SOURCE_DIR}/src/liveness.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/llvm_backend.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/llvm_bindings.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/main.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/mingw.zig"
|
||||
|
||||
@ -2106,7 +2106,7 @@ pub fn addCCArgs(
|
||||
try argv.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS");
|
||||
}
|
||||
|
||||
const llvm_triple = try @import("codegen/llvm.zig").targetTriple(arena, target);
|
||||
const llvm_triple = try @import("llvm_backend.zig").targetTriple(arena, target);
|
||||
try argv.appendSlice(&[_][]const u8{ "-target", llvm_triple });
|
||||
|
||||
switch (ext) {
|
||||
|
||||
@ -1,125 +0,0 @@
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
pub fn targetTriple(allocator: *Allocator, target: std.Target) ![]u8 {
|
||||
const llvm_arch = switch (target.cpu.arch) {
|
||||
.arm => "arm",
|
||||
.armeb => "armeb",
|
||||
.aarch64 => "aarch64",
|
||||
.aarch64_be => "aarch64_be",
|
||||
.aarch64_32 => "aarch64_32",
|
||||
.arc => "arc",
|
||||
.avr => "avr",
|
||||
.bpfel => "bpfel",
|
||||
.bpfeb => "bpfeb",
|
||||
.hexagon => "hexagon",
|
||||
.mips => "mips",
|
||||
.mipsel => "mipsel",
|
||||
.mips64 => "mips64",
|
||||
.mips64el => "mips64el",
|
||||
.msp430 => "msp430",
|
||||
.powerpc => "powerpc",
|
||||
.powerpc64 => "powerpc64",
|
||||
.powerpc64le => "powerpc64le",
|
||||
.r600 => "r600",
|
||||
.amdgcn => "amdgcn",
|
||||
.riscv32 => "riscv32",
|
||||
.riscv64 => "riscv64",
|
||||
.sparc => "sparc",
|
||||
.sparcv9 => "sparcv9",
|
||||
.sparcel => "sparcel",
|
||||
.s390x => "s390x",
|
||||
.tce => "tce",
|
||||
.tcele => "tcele",
|
||||
.thumb => "thumb",
|
||||
.thumbeb => "thumbeb",
|
||||
.i386 => "i386",
|
||||
.x86_64 => "x86_64",
|
||||
.xcore => "xcore",
|
||||
.nvptx => "nvptx",
|
||||
.nvptx64 => "nvptx64",
|
||||
.le32 => "le32",
|
||||
.le64 => "le64",
|
||||
.amdil => "amdil",
|
||||
.amdil64 => "amdil64",
|
||||
.hsail => "hsail",
|
||||
.hsail64 => "hsail64",
|
||||
.spir => "spir",
|
||||
.spir64 => "spir64",
|
||||
.kalimba => "kalimba",
|
||||
.shave => "shave",
|
||||
.lanai => "lanai",
|
||||
.wasm32 => "wasm32",
|
||||
.wasm64 => "wasm64",
|
||||
.renderscript32 => "renderscript32",
|
||||
.renderscript64 => "renderscript64",
|
||||
.ve => "ve",
|
||||
.spu_2 => return error.LLVMBackendDoesNotSupportSPUMarkII,
|
||||
};
|
||||
// TODO Add a sub-arch for some architectures depending on CPU features.
|
||||
|
||||
const llvm_os = switch (target.os.tag) {
|
||||
.freestanding => "unknown",
|
||||
.ananas => "ananas",
|
||||
.cloudabi => "cloudabi",
|
||||
.dragonfly => "dragonfly",
|
||||
.freebsd => "freebsd",
|
||||
.fuchsia => "fuchsia",
|
||||
.ios => "ios",
|
||||
.kfreebsd => "kfreebsd",
|
||||
.linux => "linux",
|
||||
.lv2 => "lv2",
|
||||
.macos => "macosx",
|
||||
.netbsd => "netbsd",
|
||||
.openbsd => "openbsd",
|
||||
.solaris => "solaris",
|
||||
.windows => "windows",
|
||||
.haiku => "haiku",
|
||||
.minix => "minix",
|
||||
.rtems => "rtems",
|
||||
.nacl => "nacl",
|
||||
.cnk => "cnk",
|
||||
.aix => "aix",
|
||||
.cuda => "cuda",
|
||||
.nvcl => "nvcl",
|
||||
.amdhsa => "amdhsa",
|
||||
.ps4 => "ps4",
|
||||
.elfiamcu => "elfiamcu",
|
||||
.tvos => "tvos",
|
||||
.watchos => "watchos",
|
||||
.mesa3d => "mesa3d",
|
||||
.contiki => "contiki",
|
||||
.amdpal => "amdpal",
|
||||
.hermit => "hermit",
|
||||
.hurd => "hurd",
|
||||
.wasi => "wasi",
|
||||
.emscripten => "emscripten",
|
||||
.uefi => "windows",
|
||||
.other => "unknown",
|
||||
};
|
||||
|
||||
const llvm_abi = switch (target.abi) {
|
||||
.none => "unknown",
|
||||
.gnu => "gnu",
|
||||
.gnuabin32 => "gnuabin32",
|
||||
.gnuabi64 => "gnuabi64",
|
||||
.gnueabi => "gnueabi",
|
||||
.gnueabihf => "gnueabihf",
|
||||
.gnux32 => "gnux32",
|
||||
.code16 => "code16",
|
||||
.eabi => "eabi",
|
||||
.eabihf => "eabihf",
|
||||
.android => "android",
|
||||
.musl => "musl",
|
||||
.musleabi => "musleabi",
|
||||
.musleabihf => "musleabihf",
|
||||
.msvc => "msvc",
|
||||
.itanium => "itanium",
|
||||
.cygnus => "cygnus",
|
||||
.coreclr => "coreclr",
|
||||
.simulator => "simulator",
|
||||
.macabi => "macabi",
|
||||
};
|
||||
|
||||
return std.fmt.allocPrint(allocator, "{}-unknown-{}-{}", .{ llvm_arch, llvm_os, llvm_abi });
|
||||
}
|
||||
@ -24,6 +24,7 @@ const build_options = @import("build_options");
|
||||
const target_util = @import("../target.zig");
|
||||
const glibc = @import("../glibc.zig");
|
||||
const Cache = @import("../Cache.zig");
|
||||
const llvm_backend = @import("../llvm_backend.zig");
|
||||
|
||||
const default_entry_addr = 0x8000000;
|
||||
|
||||
@ -33,6 +34,9 @@ base: File,
|
||||
|
||||
ptr_width: PtrWidth,
|
||||
|
||||
/// If this is not null, an object file is created by LLVM and linked with LLD afterwards.
|
||||
llvm_ir_module: ?*llvm_backend.LLVMIRModule = null,
|
||||
|
||||
/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write.
|
||||
/// Same order as in the file.
|
||||
sections: std.ArrayListUnmanaged(elf.Elf64_Shdr) = std.ArrayListUnmanaged(elf.Elf64_Shdr){},
|
||||
@ -224,7 +228,13 @@ pub const SrcFn = struct {
|
||||
pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*Elf {
|
||||
assert(options.object_format == .elf);
|
||||
|
||||
if (options.use_llvm) return error.LLVMBackendUnimplementedForELF; // TODO
|
||||
if (options.use_llvm) {
|
||||
const self = try createEmpty(allocator, options);
|
||||
errdefer self.base.destroy();
|
||||
|
||||
self.llvm_ir_module = try llvm_backend.LLVMIRModule.create(allocator, sub_path, options);
|
||||
return self;
|
||||
}
|
||||
|
||||
const file = try options.emit.?.directory.handle.createFile(sub_path, .{
|
||||
.truncate = false,
|
||||
@ -288,6 +298,7 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*Elf {
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Elf) void {
|
||||
if (self.llvm_ir_module) |ir_module| ir_module.deinit(self.base.allocator);
|
||||
self.sections.deinit(self.base.allocator);
|
||||
self.program_headers.deinit(self.base.allocator);
|
||||
self.shstrtab.deinit(self.base.allocator);
|
||||
@ -423,6 +434,8 @@ fn updateString(self: *Elf, old_str_off: u32, new_name: []const u8) !u32 {
|
||||
}
|
||||
|
||||
pub fn populateMissingMetadata(self: *Elf) !void {
|
||||
if (self.llvm_ir_module) |_| return;
|
||||
|
||||
const small_ptr = switch (self.ptr_width) {
|
||||
.p32 => true,
|
||||
.p64 => false,
|
||||
@ -727,6 +740,11 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
if (self.llvm_ir_module) |llvm_ir_module| {
|
||||
try llvm_ir_module.flushModule(comp);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO This linker code currently assumes there is only 1 compilation unit and it corresponds to the
|
||||
// Zig source code.
|
||||
const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
|
||||
@ -1261,6 +1279,9 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||
const stack_size = self.base.options.stack_size_override orelse 16777216;
|
||||
const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;
|
||||
const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt) blk: {
|
||||
// TODO: remove when stage2 can build compiler_rt.zig
|
||||
if (!build_options.is_stage1) break :blk null;
|
||||
|
||||
if (is_exe_or_dyn_lib) {
|
||||
break :blk comp.compiler_rt_static_lib.?.full_object_path;
|
||||
} else {
|
||||
@ -1552,7 +1573,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||
}
|
||||
|
||||
// libc
|
||||
if (is_exe_or_dyn_lib and !self.base.options.skip_linker_dependencies and !self.base.options.link_libc) {
|
||||
// TODO: enable when stage2 can build c.zig
|
||||
if (is_exe_or_dyn_lib and
|
||||
!self.base.options.skip_linker_dependencies and
|
||||
!self.base.options.link_libc and
|
||||
build_options.is_stage1)
|
||||
{
|
||||
try argv.append(comp.libc_static_lib.?.full_object_path);
|
||||
}
|
||||
|
||||
@ -2046,6 +2072,8 @@ fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, al
|
||||
}
|
||||
|
||||
pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void {
|
||||
if (self.llvm_ir_module) |_| return;
|
||||
|
||||
if (decl.link.elf.local_sym_index != 0) return;
|
||||
|
||||
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 {
|
||||
}
|
||||
|
||||
pub fn freeDecl(self: *Elf, decl: *Module.Decl) void {
|
||||
if (self.llvm_ir_module) |_| return;
|
||||
|
||||
// Appending to free lists is allowed to fail because the free lists are heuristics based anyway.
|
||||
self.freeTextBlock(&decl.link.elf);
|
||||
if (decl.link.elf.local_sym_index != 0) {
|
||||
@ -2119,6 +2149,11 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
if (self.llvm_ir_module) |llvm_ir_module| {
|
||||
try llvm_ir_module.updateDecl(module, decl);
|
||||
return;
|
||||
}
|
||||
|
||||
var code_buffer = std.ArrayList(u8).init(self.base.allocator);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
@ -2594,6 +2629,8 @@ pub fn updateDeclExports(
|
||||
decl: *const Module.Decl,
|
||||
exports: []const *Module.Export,
|
||||
) !void {
|
||||
if (self.llvm_ir_module) |_| return;
|
||||
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
@ -2667,6 +2704,8 @@ pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Dec
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
if (self.llvm_ir_module) |_| return;
|
||||
|
||||
const container_scope = decl.scope.cast(Module.Scope.Container).?;
|
||||
const tree = container_scope.file_scope.contents.tree;
|
||||
const file_ast_decls = tree.root_node.decls();
|
||||
@ -2685,6 +2724,8 @@ pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Dec
|
||||
}
|
||||
|
||||
pub fn deleteExport(self: *Elf, exp: Export) void {
|
||||
if (self.llvm_ir_module) |_| return;
|
||||
|
||||
const sym_index = exp.sym_index orelse return;
|
||||
self.global_symbol_free_list.append(self.base.allocator, sym_index) catch {};
|
||||
self.global_symbols.items[sym_index].st_info = 0;
|
||||
|
||||
410
src/llvm_backend.zig
Normal file
410
src/llvm_backend.zig
Normal file
@ -0,0 +1,410 @@
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Compilation = @import("Compilation.zig");
|
||||
const llvm = @import("llvm_bindings.zig");
|
||||
const link = @import("link.zig");
|
||||
|
||||
const Module = @import("Module.zig");
|
||||
const TypedValue = @import("TypedValue.zig");
|
||||
const ir = @import("ir.zig");
|
||||
const Inst = ir.Inst;
|
||||
|
||||
const Value = @import("value.zig").Value;
|
||||
const Type = @import("type.zig").Type;
|
||||
|
||||
pub fn targetTriple(allocator: *Allocator, target: std.Target) ![:0]u8 {
|
||||
const llvm_arch = switch (target.cpu.arch) {
|
||||
.arm => "arm",
|
||||
.armeb => "armeb",
|
||||
.aarch64 => "aarch64",
|
||||
.aarch64_be => "aarch64_be",
|
||||
.aarch64_32 => "aarch64_32",
|
||||
.arc => "arc",
|
||||
.avr => "avr",
|
||||
.bpfel => "bpfel",
|
||||
.bpfeb => "bpfeb",
|
||||
.hexagon => "hexagon",
|
||||
.mips => "mips",
|
||||
.mipsel => "mipsel",
|
||||
.mips64 => "mips64",
|
||||
.mips64el => "mips64el",
|
||||
.msp430 => "msp430",
|
||||
.powerpc => "powerpc",
|
||||
.powerpc64 => "powerpc64",
|
||||
.powerpc64le => "powerpc64le",
|
||||
.r600 => "r600",
|
||||
.amdgcn => "amdgcn",
|
||||
.riscv32 => "riscv32",
|
||||
.riscv64 => "riscv64",
|
||||
.sparc => "sparc",
|
||||
.sparcv9 => "sparcv9",
|
||||
.sparcel => "sparcel",
|
||||
.s390x => "s390x",
|
||||
.tce => "tce",
|
||||
.tcele => "tcele",
|
||||
.thumb => "thumb",
|
||||
.thumbeb => "thumbeb",
|
||||
.i386 => "i386",
|
||||
.x86_64 => "x86_64",
|
||||
.xcore => "xcore",
|
||||
.nvptx => "nvptx",
|
||||
.nvptx64 => "nvptx64",
|
||||
.le32 => "le32",
|
||||
.le64 => "le64",
|
||||
.amdil => "amdil",
|
||||
.amdil64 => "amdil64",
|
||||
.hsail => "hsail",
|
||||
.hsail64 => "hsail64",
|
||||
.spir => "spir",
|
||||
.spir64 => "spir64",
|
||||
.kalimba => "kalimba",
|
||||
.shave => "shave",
|
||||
.lanai => "lanai",
|
||||
.wasm32 => "wasm32",
|
||||
.wasm64 => "wasm64",
|
||||
.renderscript32 => "renderscript32",
|
||||
.renderscript64 => "renderscript64",
|
||||
.ve => "ve",
|
||||
.spu_2 => return error.LLVMBackendDoesNotSupportSPUMarkII,
|
||||
};
|
||||
// TODO Add a sub-arch for some architectures depending on CPU features.
|
||||
|
||||
const llvm_os = switch (target.os.tag) {
|
||||
.freestanding => "unknown",
|
||||
.ananas => "ananas",
|
||||
.cloudabi => "cloudabi",
|
||||
.dragonfly => "dragonfly",
|
||||
.freebsd => "freebsd",
|
||||
.fuchsia => "fuchsia",
|
||||
.ios => "ios",
|
||||
.kfreebsd => "kfreebsd",
|
||||
.linux => "linux",
|
||||
.lv2 => "lv2",
|
||||
.macos => "macosx",
|
||||
.netbsd => "netbsd",
|
||||
.openbsd => "openbsd",
|
||||
.solaris => "solaris",
|
||||
.windows => "windows",
|
||||
.haiku => "haiku",
|
||||
.minix => "minix",
|
||||
.rtems => "rtems",
|
||||
.nacl => "nacl",
|
||||
.cnk => "cnk",
|
||||
.aix => "aix",
|
||||
.cuda => "cuda",
|
||||
.nvcl => "nvcl",
|
||||
.amdhsa => "amdhsa",
|
||||
.ps4 => "ps4",
|
||||
.elfiamcu => "elfiamcu",
|
||||
.tvos => "tvos",
|
||||
.watchos => "watchos",
|
||||
.mesa3d => "mesa3d",
|
||||
.contiki => "contiki",
|
||||
.amdpal => "amdpal",
|
||||
.hermit => "hermit",
|
||||
.hurd => "hurd",
|
||||
.wasi => "wasi",
|
||||
.emscripten => "emscripten",
|
||||
.uefi => "windows",
|
||||
.other => "unknown",
|
||||
};
|
||||
|
||||
const llvm_abi = switch (target.abi) {
|
||||
.none => "unknown",
|
||||
.gnu => "gnu",
|
||||
.gnuabin32 => "gnuabin32",
|
||||
.gnuabi64 => "gnuabi64",
|
||||
.gnueabi => "gnueabi",
|
||||
.gnueabihf => "gnueabihf",
|
||||
.gnux32 => "gnux32",
|
||||
.code16 => "code16",
|
||||
.eabi => "eabi",
|
||||
.eabihf => "eabihf",
|
||||
.android => "android",
|
||||
.musl => "musl",
|
||||
.musleabi => "musleabi",
|
||||
.musleabihf => "musleabihf",
|
||||
.msvc => "msvc",
|
||||
.itanium => "itanium",
|
||||
.cygnus => "cygnus",
|
||||
.coreclr => "coreclr",
|
||||
.simulator => "simulator",
|
||||
.macabi => "macabi",
|
||||
};
|
||||
|
||||
return std.fmt.allocPrintZ(allocator, "{}-unknown-{}-{}", .{ llvm_arch, llvm_os, llvm_abi });
|
||||
}
|
||||
|
||||
pub const LLVMIRModule = struct {
|
||||
llvm_module: *const llvm.ModuleRef,
|
||||
target_machine: *const llvm.TargetMachineRef,
|
||||
output_path: []const u8,
|
||||
|
||||
gpa: *Allocator,
|
||||
err_msg: ?*Compilation.ErrorMsg = null,
|
||||
|
||||
pub fn create(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*LLVMIRModule {
|
||||
const self = try allocator.create(LLVMIRModule);
|
||||
errdefer allocator.destroy(self);
|
||||
|
||||
const gpa = options.module.?.gpa;
|
||||
|
||||
initializeLLVMTargets();
|
||||
|
||||
const root_nameZ = try gpa.dupeZ(u8, options.root_name);
|
||||
defer gpa.free(root_nameZ);
|
||||
const llvm_module = llvm.ModuleRef.createWithName(root_nameZ.ptr);
|
||||
errdefer llvm_module.disposeModule();
|
||||
|
||||
const llvm_target_triple = try targetTriple(gpa, options.target);
|
||||
defer gpa.free(llvm_target_triple);
|
||||
|
||||
var error_message: [*:0]const u8 = undefined;
|
||||
var target_ref: *const llvm.TargetRef = undefined;
|
||||
if (llvm.TargetRef.getTargetFromTriple(llvm_target_triple.ptr, &target_ref, &error_message)) {
|
||||
defer llvm.disposeMessage(error_message);
|
||||
|
||||
const stderr = std.io.getStdErr().outStream();
|
||||
try stderr.print(
|
||||
\\Zig is expecting LLVM to understand this target: '{s}'
|
||||
\\However LLVM responded with: "{s}"
|
||||
\\Zig is unable to continue. This is a bug in Zig:
|
||||
\\https://github.com/ziglang/zig/issues/438
|
||||
\\
|
||||
,
|
||||
.{
|
||||
llvm_target_triple,
|
||||
error_message,
|
||||
},
|
||||
);
|
||||
return error.InvalidLLVMTriple;
|
||||
}
|
||||
|
||||
const opt_level: llvm.CodeGenOptLevel = if (options.optimize_mode == .Debug) .None else .Aggressive;
|
||||
const target_machine = llvm.TargetMachineRef.createTargetMachine(
|
||||
target_ref,
|
||||
llvm_target_triple.ptr,
|
||||
"",
|
||||
"",
|
||||
opt_level,
|
||||
.Static,
|
||||
.Default,
|
||||
);
|
||||
errdefer target_machine.disposeTargetMachine();
|
||||
|
||||
self.* = .{
|
||||
.llvm_module = llvm_module,
|
||||
.target_machine = target_machine,
|
||||
.output_path = sub_path,
|
||||
.gpa = gpa,
|
||||
};
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *LLVMIRModule, allocator: *Allocator) void {
|
||||
self.llvm_module.disposeModule();
|
||||
self.target_machine.disposeTargetMachine();
|
||||
allocator.destroy(self);
|
||||
}
|
||||
|
||||
fn initializeLLVMTargets() void {
|
||||
llvm.initializeAllTargets();
|
||||
llvm.initializeAllTargetInfos();
|
||||
llvm.initializeAllTargetMCs();
|
||||
llvm.initializeAllAsmPrinters();
|
||||
llvm.initializeAllAsmParsers();
|
||||
}
|
||||
|
||||
pub fn flushModule(self: *LLVMIRModule, comp: *Compilation) !void {
|
||||
{
|
||||
var error_message: [*:0]const u8 = undefined;
|
||||
// verifyModule always allocs the error_message even if there is no error
|
||||
defer llvm.disposeMessage(error_message);
|
||||
|
||||
if (self.llvm_module.verifyModule(.ReturnStatus, &error_message)) {
|
||||
const stderr = std.io.getStdErr().outStream();
|
||||
try stderr.print("broken LLVM module found: {s}\nThis is a bug in the Zig compiler.", .{error_message});
|
||||
return error.BrokenLLVMModule;
|
||||
}
|
||||
}
|
||||
|
||||
if (comp.verbose_llvm_ir) {
|
||||
const dump = self.llvm_module.printToString();
|
||||
defer llvm.disposeMessage(dump);
|
||||
|
||||
const stderr = std.io.getStdErr().outStream();
|
||||
try stderr.writeAll(std.mem.spanZ(dump));
|
||||
}
|
||||
|
||||
const output_pathZ = try self.gpa.dupeZ(u8, self.output_path);
|
||||
defer self.gpa.free(output_pathZ);
|
||||
|
||||
var error_message: [*:0]const u8 = undefined;
|
||||
// TODO: where to put the output object, zig-cache something?
|
||||
// TODO: caching?
|
||||
if (self.target_machine.emitToFile(
|
||||
self.llvm_module,
|
||||
output_pathZ.ptr,
|
||||
.ObjectFile,
|
||||
&error_message,
|
||||
)) {
|
||||
defer llvm.disposeMessage(error_message);
|
||||
|
||||
const stderr = std.io.getStdErr().outStream();
|
||||
try stderr.print("LLVM failed to emit file: {s}\n", .{error_message});
|
||||
return error.FailedToEmit;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updateDecl(self: *LLVMIRModule, module: *Module, decl: *Module.Decl) !void {
|
||||
const typed_value = decl.typed_value.most_recent.typed_value;
|
||||
self.generate(module, typed_value, decl.src()) catch |err| switch (err) {
|
||||
error.CodegenFail => {
|
||||
decl.analysis = .codegen_failure;
|
||||
try module.failed_decls.put(module.gpa, decl, self.err_msg.?);
|
||||
return;
|
||||
},
|
||||
else => |e| return e,
|
||||
};
|
||||
}
|
||||
|
||||
fn generate(self: *LLVMIRModule, module: *Module, typed_value: TypedValue, src: usize) !void {
|
||||
switch (typed_value.ty.zigTypeTag()) {
|
||||
.Fn => {
|
||||
const func = typed_value.val.cast(Value.Payload.Function).?.func;
|
||||
|
||||
var codegen = CodeGen{
|
||||
.module = module,
|
||||
.llvm_module = self.llvm_module,
|
||||
.builder = llvm.BuilderRef.createBuilder(),
|
||||
};
|
||||
defer codegen.builder.disposeBuilder();
|
||||
|
||||
const llvm_func = try codegen.resolveLLVMFunction(func);
|
||||
|
||||
// We remove all the basic blocks of a function to support incremental
|
||||
// compilation!
|
||||
// TODO: remove all basic blocks if functions can have more than one
|
||||
if (llvm_func.getFirstBasicBlock()) |bb| {
|
||||
bb.deleteBasicBlock();
|
||||
}
|
||||
|
||||
const entry_block = llvm_func.appendBasicBlock("Entry");
|
||||
codegen.builder.positionBuilderAtEnd(entry_block);
|
||||
|
||||
const instructions = func.analysis.success.instructions;
|
||||
for (instructions) |inst| {
|
||||
switch (inst.tag) {
|
||||
.breakpoint => try codegen.generateBreakpoint(inst.castTag(.breakpoint).?),
|
||||
.call => try codegen.generateCall(inst.castTag(.call).?),
|
||||
.unreach => codegen.generateUnreach(inst.castTag(.unreach).?),
|
||||
.retvoid => codegen.generateRetVoid(inst.castTag(.retvoid).?),
|
||||
.dbg_stmt => {
|
||||
// TODO: implement debug info
|
||||
},
|
||||
else => |tag| return self.fail(src, "TODO implement LLVM codegen for Zir instruction: {}", .{tag}),
|
||||
}
|
||||
}
|
||||
},
|
||||
else => |ty| return self.fail(src, "TODO implement LLVM codegen for top-level decl type: {}", .{ty}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fail(self: *LLVMIRModule, src: usize, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
|
||||
@setCold(true);
|
||||
std.debug.assert(self.err_msg == null);
|
||||
self.err_msg = try Compilation.ErrorMsg.create(self.gpa, src, format, args);
|
||||
return error.CodegenFail;
|
||||
}
|
||||
};
|
||||
|
||||
const CodeGen = struct {
|
||||
module: *Module,
|
||||
llvm_module: *const llvm.ModuleRef,
|
||||
builder: *const llvm.BuilderRef,
|
||||
|
||||
fn generateCall(codegen: *CodeGen, inst: *Inst.Call) !void {
|
||||
if (inst.func.cast(Inst.Constant)) |func_inst| {
|
||||
if (func_inst.val.cast(Value.Payload.Function)) |func_val| {
|
||||
const func = func_val.func;
|
||||
const zig_fn_type = func.owner_decl.typed_value.most_recent.typed_value.ty;
|
||||
const llvm_fn = try codegen.resolveLLVMFunction(func);
|
||||
|
||||
// TODO: handle more arguments, inst.args
|
||||
|
||||
// TODO: LLVMBuildCall2 handles opaque function pointers, according to llvm docs
|
||||
// Do we need that?
|
||||
const call = codegen.builder.buildCall(llvm_fn, null, 0, "");
|
||||
|
||||
if (zig_fn_type.fnReturnType().zigTypeTag() == .NoReturn) {
|
||||
_ = codegen.builder.buildUnreachable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn generateRetVoid(codegen: *CodeGen, inst: *Inst.NoOp) void {
|
||||
_ = codegen.builder.buildRetVoid();
|
||||
}
|
||||
|
||||
fn generateUnreach(codegen: *CodeGen, inst: *Inst.NoOp) void {
|
||||
_ = codegen.builder.buildUnreachable();
|
||||
}
|
||||
|
||||
fn generateBreakpoint(codegen: *CodeGen, inst: *Inst.NoOp) !void {
|
||||
// TODO: Store this function somewhere such that we dont have to add it again
|
||||
const fn_type = llvm.TypeRef.functionType(llvm.voidType(), null, 0, false);
|
||||
const func = codegen.llvm_module.addFunction("llvm.debugtrap", fn_type);
|
||||
// TODO: add assertion: LLVMGetIntrinsicID
|
||||
_ = codegen.builder.buildCall(func, null, 0, "");
|
||||
}
|
||||
|
||||
/// If the llvm function does not exist, create it
|
||||
fn resolveLLVMFunction(codegen: *CodeGen, func: *Module.Fn) !*const llvm.ValueRef {
|
||||
// TODO: do we want to store this in our own datastructure?
|
||||
if (codegen.llvm_module.getNamedFunction(func.owner_decl.name)) |llvm_fn| return llvm_fn;
|
||||
|
||||
const zig_fn_type = func.owner_decl.typed_value.most_recent.typed_value.ty;
|
||||
const return_type = zig_fn_type.fnReturnType();
|
||||
|
||||
const fn_param_len = zig_fn_type.fnParamLen();
|
||||
|
||||
const fn_param_types = try codegen.module.gpa.alloc(Type, fn_param_len);
|
||||
defer codegen.module.gpa.free(fn_param_types);
|
||||
zig_fn_type.fnParamTypes(fn_param_types);
|
||||
|
||||
const llvm_param = try codegen.module.gpa.alloc(*const llvm.TypeRef, fn_param_len);
|
||||
defer codegen.module.gpa.free(llvm_param);
|
||||
|
||||
for (fn_param_types) |fn_param, i| {
|
||||
llvm_param[i] = codegen.getLLVMType(fn_param);
|
||||
}
|
||||
|
||||
const fn_type = llvm.TypeRef.functionType(
|
||||
codegen.getLLVMType(return_type),
|
||||
if (fn_param_len == 0) null else llvm_param.ptr,
|
||||
@intCast(c_uint, fn_param_len),
|
||||
false,
|
||||
);
|
||||
const llvm_fn = codegen.llvm_module.addFunction(func.owner_decl.name, fn_type);
|
||||
|
||||
if (return_type.zigTypeTag() == .NoReturn) {
|
||||
llvm_fn.addFnAttr("noreturn");
|
||||
}
|
||||
|
||||
return llvm_fn;
|
||||
}
|
||||
|
||||
fn getLLVMType(codegen: *CodeGen, t: Type) *const llvm.TypeRef {
|
||||
switch (t.zigTypeTag()) {
|
||||
.Void => return llvm.voidType(),
|
||||
.NoReturn => return llvm.voidType(),
|
||||
.Int => {
|
||||
const info = t.intInfo(codegen.module.getTarget());
|
||||
return llvm.intType(info.bits);
|
||||
},
|
||||
.Bool => return llvm.intType(1),
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -1,6 +1,364 @@
|
||||
//! We do this instead of @cImport because the self-hosted compiler is easier
|
||||
//! to bootstrap if it does not depend on translate-c.
|
||||
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
const LLVMBool = bool;
|
||||
pub const LLVMAttributeIndex = c_uint;
|
||||
|
||||
pub const ValueRef = opaque {
|
||||
pub const addAttributeAtIndex = LLVMAddAttributeAtIndex;
|
||||
extern fn LLVMAddAttributeAtIndex(*const ValueRef, Idx: LLVMAttributeIndex, A: *const AttributeRef) void;
|
||||
|
||||
pub const appendBasicBlock = LLVMAppendBasicBlock;
|
||||
extern fn LLVMAppendBasicBlock(Fn: *const ValueRef, Name: [*:0]const u8) *const BasicBlockRef;
|
||||
|
||||
pub const getFirstBasicBlock = LLVMGetFirstBasicBlock;
|
||||
extern fn LLVMGetFirstBasicBlock(Fn: *const ValueRef) ?*const BasicBlockRef;
|
||||
|
||||
// Helper functions
|
||||
// TODO: Do we want to put these functions here? It allows for convienient function calls
|
||||
// on ValueRef: llvm_fn.addFnAttr("noreturn")
|
||||
fn addAttr(val: *const ValueRef, index: LLVMAttributeIndex, name: []const u8) void {
|
||||
const kind_id = getEnumAttributeKindForName(name.ptr, name.len);
|
||||
assert(kind_id != 0);
|
||||
const llvm_attr = ContextRef.getGlobal().createEnumAttribute(kind_id, 0);
|
||||
val.addAttributeAtIndex(index, llvm_attr);
|
||||
}
|
||||
|
||||
pub fn addFnAttr(val: *const ValueRef, attr_name: []const u8) void {
|
||||
// TODO: improve this API, `addAttr(-1, attr_name)`
|
||||
val.addAttr(std.math.maxInt(LLVMAttributeIndex), attr_name);
|
||||
}
|
||||
};
|
||||
|
||||
pub const TypeRef = opaque {
|
||||
pub const functionType = LLVMFunctionType;
|
||||
extern fn LLVMFunctionType(ReturnType: *const TypeRef, ParamTypes: ?[*]*const TypeRef, ParamCount: c_uint, IsVarArg: LLVMBool) *const TypeRef;
|
||||
};
|
||||
|
||||
pub const ModuleRef = opaque {
|
||||
pub const createWithName = LLVMModuleCreateWithName;
|
||||
extern fn LLVMModuleCreateWithName(ModuleID: [*:0]const u8) *const ModuleRef;
|
||||
|
||||
pub const disposeModule = LLVMDisposeModule;
|
||||
extern fn LLVMDisposeModule(*const ModuleRef) void;
|
||||
|
||||
pub const verifyModule = LLVMVerifyModule;
|
||||
extern fn LLVMVerifyModule(*const ModuleRef, Action: VerifierFailureAction, OutMessage: *[*:0]const u8) LLVMBool;
|
||||
|
||||
pub const addFunction = LLVMAddFunction;
|
||||
extern fn LLVMAddFunction(*const ModuleRef, Name: [*:0]const u8, FunctionTy: *const TypeRef) *const ValueRef;
|
||||
|
||||
pub const getNamedFunction = LLVMGetNamedFunction;
|
||||
extern fn LLVMGetNamedFunction(*const ModuleRef, Name: [*:0]const u8) ?*const ValueRef;
|
||||
|
||||
pub const printToString = LLVMPrintModuleToString;
|
||||
extern fn LLVMPrintModuleToString(*const ModuleRef) [*:0]const u8;
|
||||
};
|
||||
|
||||
pub const disposeMessage = LLVMDisposeMessage;
|
||||
extern fn LLVMDisposeMessage(Message: [*:0]const u8) void;
|
||||
|
||||
pub const VerifierFailureAction = extern enum {
|
||||
AbortProcess,
|
||||
PrintMessage,
|
||||
ReturnStatus,
|
||||
};
|
||||
|
||||
pub const voidType = LLVMVoidType;
|
||||
extern fn LLVMVoidType() *const TypeRef;
|
||||
|
||||
pub const getEnumAttributeKindForName = LLVMGetEnumAttributeKindForName;
|
||||
extern fn LLVMGetEnumAttributeKindForName(Name: [*]const u8, SLen: usize) c_uint;
|
||||
|
||||
pub const AttributeRef = opaque {};
|
||||
|
||||
pub const ContextRef = opaque {
|
||||
pub const createEnumAttribute = LLVMCreateEnumAttribute;
|
||||
extern fn LLVMCreateEnumAttribute(*const ContextRef, KindID: c_uint, Val: u64) *const AttributeRef;
|
||||
|
||||
pub const getGlobal = LLVMGetGlobalContext;
|
||||
extern fn LLVMGetGlobalContext() *const ContextRef;
|
||||
};
|
||||
|
||||
pub const intType = LLVMIntType;
|
||||
extern fn LLVMIntType(NumBits: c_uint) *const TypeRef;
|
||||
|
||||
pub const BuilderRef = opaque {
|
||||
pub const createBuilder = LLVMCreateBuilder;
|
||||
extern fn LLVMCreateBuilder() *const BuilderRef;
|
||||
|
||||
pub const disposeBuilder = LLVMDisposeBuilder;
|
||||
extern fn LLVMDisposeBuilder(Builder: *const BuilderRef) void;
|
||||
|
||||
pub const positionBuilderAtEnd = LLVMPositionBuilderAtEnd;
|
||||
extern fn LLVMPositionBuilderAtEnd(Builder: *const BuilderRef, Block: *const BasicBlockRef) void;
|
||||
|
||||
pub const getInsertBlock = LLVMGetInsertBlock;
|
||||
extern fn LLVMGetInsertBlock(Builder: *const BuilderRef) *const BasicBlockRef;
|
||||
|
||||
pub const buildCall = LLVMBuildCall;
|
||||
extern fn LLVMBuildCall(*const BuilderRef, Fn: *const ValueRef, Args: ?[*]*const ValueRef, NumArgs: c_uint, Name: [*:0]const u8) *const ValueRef;
|
||||
|
||||
pub const buildCall2 = LLVMBuildCall2;
|
||||
extern fn LLVMBuildCall2(*const BuilderRef, *const TypeRef, Fn: *const ValueRef, Args: [*]*const ValueRef, NumArgs: c_uint, Name: [*:0]const u8) *const ValueRef;
|
||||
|
||||
pub const buildRetVoid = LLVMBuildRetVoid;
|
||||
extern fn LLVMBuildRetVoid(*const BuilderRef) *const ValueRef;
|
||||
|
||||
pub const buildUnreachable = LLVMBuildUnreachable;
|
||||
extern fn LLVMBuildUnreachable(*const BuilderRef) *const ValueRef;
|
||||
|
||||
pub const buildAlloca = LLVMBuildAlloca;
|
||||
extern fn LLVMBuildAlloca(*const BuilderRef, Ty: *const TypeRef, Name: [*:0]const u8) *const ValueRef;
|
||||
};
|
||||
|
||||
pub const BasicBlockRef = opaque {
|
||||
pub const deleteBasicBlock = LLVMDeleteBasicBlock;
|
||||
extern fn LLVMDeleteBasicBlock(BB: *const BasicBlockRef) void;
|
||||
};
|
||||
|
||||
pub const TargetMachineRef = opaque {
|
||||
pub const createTargetMachine = LLVMCreateTargetMachine;
|
||||
extern fn LLVMCreateTargetMachine(
|
||||
T: *const TargetRef,
|
||||
Triple: [*:0]const u8,
|
||||
CPU: [*:0]const u8,
|
||||
Features: [*:0]const u8,
|
||||
Level: CodeGenOptLevel,
|
||||
Reloc: RelocMode,
|
||||
CodeModel: CodeMode,
|
||||
) *const TargetMachineRef;
|
||||
|
||||
pub const disposeTargetMachine = LLVMDisposeTargetMachine;
|
||||
extern fn LLVMDisposeTargetMachine(T: *const TargetMachineRef) void;
|
||||
|
||||
pub const emitToFile = LLVMTargetMachineEmitToFile;
|
||||
extern fn LLVMTargetMachineEmitToFile(*const TargetMachineRef, M: *const ModuleRef, Filename: [*:0]const u8, codegen: CodeGenFileType, ErrorMessage: *[*:0]const u8) LLVMBool;
|
||||
};
|
||||
|
||||
pub const CodeMode = extern enum {
|
||||
Default,
|
||||
JITDefault,
|
||||
Tiny,
|
||||
Small,
|
||||
Kernel,
|
||||
Medium,
|
||||
Large,
|
||||
};
|
||||
|
||||
pub const CodeGenOptLevel = extern enum {
|
||||
None,
|
||||
Less,
|
||||
Default,
|
||||
Aggressive,
|
||||
};
|
||||
|
||||
pub const RelocMode = extern enum {
|
||||
Default,
|
||||
Static,
|
||||
PIC,
|
||||
DynamicNoPic,
|
||||
ROPI,
|
||||
RWPI,
|
||||
ROPI_RWPI,
|
||||
};
|
||||
|
||||
pub const CodeGenFileType = extern enum {
|
||||
AssemblyFile,
|
||||
ObjectFile,
|
||||
};
|
||||
|
||||
pub const TargetRef = opaque {
|
||||
pub const getTargetFromTriple = LLVMGetTargetFromTriple;
|
||||
extern fn LLVMGetTargetFromTriple(Triple: [*:0]const u8, T: **const TargetRef, ErrorMessage: *[*:0]const u8) LLVMBool;
|
||||
};
|
||||
|
||||
extern fn LLVMInitializeAArch64TargetInfo() void;
|
||||
extern fn LLVMInitializeAMDGPUTargetInfo() void;
|
||||
extern fn LLVMInitializeARMTargetInfo() void;
|
||||
extern fn LLVMInitializeAVRTargetInfo() void;
|
||||
extern fn LLVMInitializeBPFTargetInfo() void;
|
||||
extern fn LLVMInitializeHexagonTargetInfo() void;
|
||||
extern fn LLVMInitializeLanaiTargetInfo() void;
|
||||
extern fn LLVMInitializeMipsTargetInfo() void;
|
||||
extern fn LLVMInitializeMSP430TargetInfo() void;
|
||||
extern fn LLVMInitializeNVPTXTargetInfo() void;
|
||||
extern fn LLVMInitializePowerPCTargetInfo() void;
|
||||
extern fn LLVMInitializeRISCVTargetInfo() void;
|
||||
extern fn LLVMInitializeSparcTargetInfo() void;
|
||||
extern fn LLVMInitializeSystemZTargetInfo() void;
|
||||
extern fn LLVMInitializeWebAssemblyTargetInfo() void;
|
||||
extern fn LLVMInitializeX86TargetInfo() void;
|
||||
extern fn LLVMInitializeXCoreTargetInfo() void;
|
||||
extern fn LLVMInitializeAArch64Target() void;
|
||||
extern fn LLVMInitializeAMDGPUTarget() void;
|
||||
extern fn LLVMInitializeARMTarget() void;
|
||||
extern fn LLVMInitializeAVRTarget() void;
|
||||
extern fn LLVMInitializeBPFTarget() void;
|
||||
extern fn LLVMInitializeHexagonTarget() void;
|
||||
extern fn LLVMInitializeLanaiTarget() void;
|
||||
extern fn LLVMInitializeMipsTarget() void;
|
||||
extern fn LLVMInitializeMSP430Target() void;
|
||||
extern fn LLVMInitializeNVPTXTarget() void;
|
||||
extern fn LLVMInitializePowerPCTarget() void;
|
||||
extern fn LLVMInitializeRISCVTarget() void;
|
||||
extern fn LLVMInitializeSparcTarget() void;
|
||||
extern fn LLVMInitializeSystemZTarget() void;
|
||||
extern fn LLVMInitializeWebAssemblyTarget() void;
|
||||
extern fn LLVMInitializeX86Target() void;
|
||||
extern fn LLVMInitializeXCoreTarget() void;
|
||||
extern fn LLVMInitializeAArch64TargetMC() void;
|
||||
extern fn LLVMInitializeAMDGPUTargetMC() void;
|
||||
extern fn LLVMInitializeARMTargetMC() void;
|
||||
extern fn LLVMInitializeAVRTargetMC() void;
|
||||
extern fn LLVMInitializeBPFTargetMC() void;
|
||||
extern fn LLVMInitializeHexagonTargetMC() void;
|
||||
extern fn LLVMInitializeLanaiTargetMC() void;
|
||||
extern fn LLVMInitializeMipsTargetMC() void;
|
||||
extern fn LLVMInitializeMSP430TargetMC() void;
|
||||
extern fn LLVMInitializeNVPTXTargetMC() void;
|
||||
extern fn LLVMInitializePowerPCTargetMC() void;
|
||||
extern fn LLVMInitializeRISCVTargetMC() void;
|
||||
extern fn LLVMInitializeSparcTargetMC() void;
|
||||
extern fn LLVMInitializeSystemZTargetMC() void;
|
||||
extern fn LLVMInitializeWebAssemblyTargetMC() void;
|
||||
extern fn LLVMInitializeX86TargetMC() void;
|
||||
extern fn LLVMInitializeXCoreTargetMC() void;
|
||||
extern fn LLVMInitializeAArch64AsmPrinter() void;
|
||||
extern fn LLVMInitializeAMDGPUAsmPrinter() void;
|
||||
extern fn LLVMInitializeARMAsmPrinter() void;
|
||||
extern fn LLVMInitializeAVRAsmPrinter() void;
|
||||
extern fn LLVMInitializeBPFAsmPrinter() void;
|
||||
extern fn LLVMInitializeHexagonAsmPrinter() void;
|
||||
extern fn LLVMInitializeLanaiAsmPrinter() void;
|
||||
extern fn LLVMInitializeMipsAsmPrinter() void;
|
||||
extern fn LLVMInitializeMSP430AsmPrinter() void;
|
||||
extern fn LLVMInitializeNVPTXAsmPrinter() void;
|
||||
extern fn LLVMInitializePowerPCAsmPrinter() void;
|
||||
extern fn LLVMInitializeRISCVAsmPrinter() void;
|
||||
extern fn LLVMInitializeSparcAsmPrinter() void;
|
||||
extern fn LLVMInitializeSystemZAsmPrinter() void;
|
||||
extern fn LLVMInitializeWebAssemblyAsmPrinter() void;
|
||||
extern fn LLVMInitializeX86AsmPrinter() void;
|
||||
extern fn LLVMInitializeXCoreAsmPrinter() void;
|
||||
extern fn LLVMInitializeAArch64AsmParser() void;
|
||||
extern fn LLVMInitializeAMDGPUAsmParser() void;
|
||||
extern fn LLVMInitializeARMAsmParser() void;
|
||||
extern fn LLVMInitializeAVRAsmParser() void;
|
||||
extern fn LLVMInitializeBPFAsmParser() void;
|
||||
extern fn LLVMInitializeHexagonAsmParser() void;
|
||||
extern fn LLVMInitializeLanaiAsmParser() void;
|
||||
extern fn LLVMInitializeMipsAsmParser() void;
|
||||
extern fn LLVMInitializeMSP430AsmParser() void;
|
||||
extern fn LLVMInitializePowerPCAsmParser() void;
|
||||
extern fn LLVMInitializeRISCVAsmParser() void;
|
||||
extern fn LLVMInitializeSparcAsmParser() void;
|
||||
extern fn LLVMInitializeSystemZAsmParser() void;
|
||||
extern fn LLVMInitializeWebAssemblyAsmParser() void;
|
||||
extern fn LLVMInitializeX86AsmParser() void;
|
||||
|
||||
pub const initializeAllTargetInfos = LLVMInitializeAllTargetInfos;
|
||||
fn LLVMInitializeAllTargetInfos() callconv(.C) void {
|
||||
LLVMInitializeAArch64TargetInfo();
|
||||
LLVMInitializeAMDGPUTargetInfo();
|
||||
LLVMInitializeARMTargetInfo();
|
||||
LLVMInitializeAVRTargetInfo();
|
||||
LLVMInitializeBPFTargetInfo();
|
||||
LLVMInitializeHexagonTargetInfo();
|
||||
LLVMInitializeLanaiTargetInfo();
|
||||
LLVMInitializeMipsTargetInfo();
|
||||
LLVMInitializeMSP430TargetInfo();
|
||||
LLVMInitializeNVPTXTargetInfo();
|
||||
LLVMInitializePowerPCTargetInfo();
|
||||
LLVMInitializeRISCVTargetInfo();
|
||||
LLVMInitializeSparcTargetInfo();
|
||||
LLVMInitializeSystemZTargetInfo();
|
||||
LLVMInitializeWebAssemblyTargetInfo();
|
||||
LLVMInitializeX86TargetInfo();
|
||||
LLVMInitializeXCoreTargetInfo();
|
||||
}
|
||||
pub const initializeAllTargets = LLVMInitializeAllTargets;
|
||||
fn LLVMInitializeAllTargets() callconv(.C) void {
|
||||
LLVMInitializeAArch64Target();
|
||||
LLVMInitializeAMDGPUTarget();
|
||||
LLVMInitializeARMTarget();
|
||||
LLVMInitializeAVRTarget();
|
||||
LLVMInitializeBPFTarget();
|
||||
LLVMInitializeHexagonTarget();
|
||||
LLVMInitializeLanaiTarget();
|
||||
LLVMInitializeMipsTarget();
|
||||
LLVMInitializeMSP430Target();
|
||||
LLVMInitializeNVPTXTarget();
|
||||
LLVMInitializePowerPCTarget();
|
||||
LLVMInitializeRISCVTarget();
|
||||
LLVMInitializeSparcTarget();
|
||||
LLVMInitializeSystemZTarget();
|
||||
LLVMInitializeWebAssemblyTarget();
|
||||
LLVMInitializeX86Target();
|
||||
LLVMInitializeXCoreTarget();
|
||||
}
|
||||
pub const initializeAllTargetMCs = LLVMInitializeAllTargetMCs;
|
||||
fn LLVMInitializeAllTargetMCs() callconv(.C) void {
|
||||
LLVMInitializeAArch64TargetMC();
|
||||
LLVMInitializeAMDGPUTargetMC();
|
||||
LLVMInitializeARMTargetMC();
|
||||
LLVMInitializeAVRTargetMC();
|
||||
LLVMInitializeBPFTargetMC();
|
||||
LLVMInitializeHexagonTargetMC();
|
||||
LLVMInitializeLanaiTargetMC();
|
||||
LLVMInitializeMipsTargetMC();
|
||||
LLVMInitializeMSP430TargetMC();
|
||||
LLVMInitializeNVPTXTargetMC();
|
||||
LLVMInitializePowerPCTargetMC();
|
||||
LLVMInitializeRISCVTargetMC();
|
||||
LLVMInitializeSparcTargetMC();
|
||||
LLVMInitializeSystemZTargetMC();
|
||||
LLVMInitializeWebAssemblyTargetMC();
|
||||
LLVMInitializeX86TargetMC();
|
||||
LLVMInitializeXCoreTargetMC();
|
||||
}
|
||||
pub const initializeAllAsmPrinters = LLVMInitializeAllAsmPrinters;
|
||||
fn LLVMInitializeAllAsmPrinters() callconv(.C) void {
|
||||
LLVMInitializeAArch64AsmPrinter();
|
||||
LLVMInitializeAMDGPUAsmPrinter();
|
||||
LLVMInitializeARMAsmPrinter();
|
||||
LLVMInitializeAVRAsmPrinter();
|
||||
LLVMInitializeBPFAsmPrinter();
|
||||
LLVMInitializeHexagonAsmPrinter();
|
||||
LLVMInitializeLanaiAsmPrinter();
|
||||
LLVMInitializeMipsAsmPrinter();
|
||||
LLVMInitializeMSP430AsmPrinter();
|
||||
LLVMInitializeNVPTXAsmPrinter();
|
||||
LLVMInitializePowerPCAsmPrinter();
|
||||
LLVMInitializeRISCVAsmPrinter();
|
||||
LLVMInitializeSparcAsmPrinter();
|
||||
LLVMInitializeSystemZAsmPrinter();
|
||||
LLVMInitializeWebAssemblyAsmPrinter();
|
||||
LLVMInitializeX86AsmPrinter();
|
||||
LLVMInitializeXCoreAsmPrinter();
|
||||
}
|
||||
pub const initializeAllAsmParsers = LLVMInitializeAllAsmParsers;
|
||||
fn LLVMInitializeAllAsmParsers() callconv(.C) void {
|
||||
LLVMInitializeAArch64AsmParser();
|
||||
LLVMInitializeAMDGPUAsmParser();
|
||||
LLVMInitializeARMAsmParser();
|
||||
LLVMInitializeAVRAsmParser();
|
||||
LLVMInitializeBPFAsmParser();
|
||||
LLVMInitializeHexagonAsmParser();
|
||||
LLVMInitializeLanaiAsmParser();
|
||||
LLVMInitializeMipsAsmParser();
|
||||
LLVMInitializeMSP430AsmParser();
|
||||
LLVMInitializePowerPCAsmParser();
|
||||
LLVMInitializeRISCVAsmParser();
|
||||
LLVMInitializeSparcAsmParser();
|
||||
LLVMInitializeSystemZAsmParser();
|
||||
LLVMInitializeWebAssemblyAsmParser();
|
||||
LLVMInitializeX86AsmParser();
|
||||
}
|
||||
|
||||
extern fn ZigLLDLinkCOFF(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int;
|
||||
extern fn ZigLLDLinkELF(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int;
|
||||
extern fn ZigLLDLinkMachO(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user