mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
stage2: restructure LLVM backend
The LLVM backend is now structured into 3 different structs, namely Object, DeclGen and FuncGen. Object represents an object that is generated by the LLVM backend. DeclGen is responsible for generating a decl and FuncGen is responsible for generating llvm instructions from tzir in a function.
This commit is contained in:
parent
56677f2f2d
commit
a710368054
File diff suppressed because it is too large
Load Diff
@ -34,7 +34,7 @@ pub const base_tag: link.File.Tag = .coff;
|
||||
const msdos_stub = @embedFile("msdos-stub.bin");
|
||||
|
||||
/// If this is not null, an object file is created by LLVM and linked with LLD afterwards.
|
||||
llvm_ir_module: ?*llvm_backend.LLVMIRModule = null,
|
||||
llvm_object: ?*llvm_backend.Object = null,
|
||||
|
||||
base: link.File,
|
||||
ptr_width: PtrWidth,
|
||||
@ -129,7 +129,7 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
|
||||
const self = try createEmpty(allocator, options);
|
||||
errdefer self.base.destroy();
|
||||
|
||||
self.llvm_ir_module = try llvm_backend.LLVMIRModule.create(allocator, sub_path, options);
|
||||
self.llvm_object = try llvm_backend.Object.create(allocator, sub_path, options);
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -413,7 +413,7 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*Coff {
|
||||
}
|
||||
|
||||
pub fn allocateDeclIndexes(self: *Coff, decl: *Module.Decl) !void {
|
||||
if (self.llvm_ir_module) |_| return;
|
||||
if (self.llvm_object) |_| return;
|
||||
|
||||
try self.offset_table.ensureCapacity(self.base.allocator, self.offset_table.items.len + 1);
|
||||
|
||||
@ -660,7 +660,7 @@ pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void {
|
||||
defer tracy.end();
|
||||
|
||||
if (build_options.have_llvm)
|
||||
if (self.llvm_ir_module) |llvm_ir_module| return try llvm_ir_module.updateDecl(module, decl);
|
||||
if (self.llvm_object) |llvm_object| return try llvm_object.updateDecl(module, decl);
|
||||
|
||||
const typed_value = decl.typed_value.most_recent.typed_value;
|
||||
if (typed_value.val.tag() == .extern_fn) {
|
||||
@ -720,7 +720,7 @@ pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void {
|
||||
}
|
||||
|
||||
pub fn freeDecl(self: *Coff, decl: *Module.Decl) void {
|
||||
if (self.llvm_ir_module) |_| return;
|
||||
if (self.llvm_object) |_| return;
|
||||
|
||||
// Appending to free lists is allowed to fail because the free lists are heuristics based anyway.
|
||||
self.freeTextBlock(&decl.link.coff);
|
||||
@ -728,7 +728,7 @@ pub fn freeDecl(self: *Coff, decl: *Module.Decl) void {
|
||||
}
|
||||
|
||||
pub fn updateDeclExports(self: *Coff, module: *Module, decl: *Module.Decl, exports: []const *Module.Export) !void {
|
||||
if (self.llvm_ir_module) |_| return;
|
||||
if (self.llvm_object) |_| return;
|
||||
|
||||
for (exports) |exp| {
|
||||
if (exp.options.section) |section_name| {
|
||||
@ -771,7 +771,7 @@ pub fn flushModule(self: *Coff, comp: *Compilation) !void {
|
||||
defer tracy.end();
|
||||
|
||||
if (build_options.have_llvm)
|
||||
if (self.llvm_ir_module) |llvm_ir_module| return try llvm_ir_module.flushModule(comp);
|
||||
if (self.llvm_object) |llvm_object| return try llvm_object.flushModule(comp);
|
||||
|
||||
if (self.text_section_size_dirty) {
|
||||
// Write the new raw size in the .text header
|
||||
@ -1308,7 +1308,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
|
||||
}
|
||||
|
||||
pub fn getDeclVAddr(self: *Coff, decl: *const Module.Decl) u64 {
|
||||
assert(self.llvm_ir_module == null);
|
||||
assert(self.llvm_object == null);
|
||||
return self.text_section_virtual_address + decl.link.coff.text_offset;
|
||||
}
|
||||
|
||||
@ -1318,7 +1318,7 @@ pub fn updateDeclLineNumber(self: *Coff, module: *Module, decl: *Module.Decl) !v
|
||||
|
||||
pub fn deinit(self: *Coff) void {
|
||||
if (build_options.have_llvm)
|
||||
if (self.llvm_ir_module) |ir_module| ir_module.deinit(self.base.allocator);
|
||||
if (self.llvm_object) |ir_module| ir_module.deinit(self.base.allocator);
|
||||
|
||||
self.text_block_free_list.deinit(self.base.allocator);
|
||||
self.offset_table.deinit(self.base.allocator);
|
||||
|
||||
@ -35,7 +35,7 @@ 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,
|
||||
llvm_object: ?*llvm_backend.Object = null,
|
||||
|
||||
/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write.
|
||||
/// Same order as in the file.
|
||||
@ -232,7 +232,7 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
|
||||
const self = try createEmpty(allocator, options);
|
||||
errdefer self.base.destroy();
|
||||
|
||||
self.llvm_ir_module = try llvm_backend.LLVMIRModule.create(allocator, sub_path, options);
|
||||
self.llvm_object = try llvm_backend.Object.create(allocator, sub_path, options);
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -299,7 +299,7 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*Elf {
|
||||
|
||||
pub fn deinit(self: *Elf) void {
|
||||
if (build_options.have_llvm)
|
||||
if (self.llvm_ir_module) |ir_module|
|
||||
if (self.llvm_object) |ir_module|
|
||||
ir_module.deinit(self.base.allocator);
|
||||
|
||||
self.sections.deinit(self.base.allocator);
|
||||
@ -318,7 +318,7 @@ pub fn deinit(self: *Elf) void {
|
||||
}
|
||||
|
||||
pub fn getDeclVAddr(self: *Elf, decl: *const Module.Decl) u64 {
|
||||
assert(self.llvm_ir_module == null);
|
||||
assert(self.llvm_object == null);
|
||||
assert(decl.link.elf.local_sym_index != 0);
|
||||
return self.local_symbols.items[decl.link.elf.local_sym_index].st_value;
|
||||
}
|
||||
@ -438,7 +438,7 @@ fn updateString(self: *Elf, old_str_off: u32, new_name: []const u8) !u32 {
|
||||
}
|
||||
|
||||
pub fn populateMissingMetadata(self: *Elf) !void {
|
||||
assert(self.llvm_ir_module == null);
|
||||
assert(self.llvm_object == null);
|
||||
|
||||
const small_ptr = switch (self.ptr_width) {
|
||||
.p32 => true,
|
||||
@ -745,7 +745,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
|
||||
defer tracy.end();
|
||||
|
||||
if (build_options.have_llvm)
|
||||
if (self.llvm_ir_module) |llvm_ir_module| return try llvm_ir_module.flushModule(comp);
|
||||
if (self.llvm_object) |llvm_object| return try llvm_object.flushModule(comp);
|
||||
|
||||
// TODO This linker code currently assumes there is only 1 compilation unit and it corresponds to the
|
||||
// Zig source code.
|
||||
@ -2111,7 +2111,7 @@ 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 (self.llvm_object) |_| return;
|
||||
|
||||
if (decl.link.elf.local_sym_index != 0) return;
|
||||
|
||||
@ -2149,7 +2149,7 @@ pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void {
|
||||
}
|
||||
|
||||
pub fn freeDecl(self: *Elf, decl: *Module.Decl) void {
|
||||
if (self.llvm_ir_module) |_| return;
|
||||
if (self.llvm_object) |_| return;
|
||||
|
||||
// Appending to free lists is allowed to fail because the free lists are heuristics based anyway.
|
||||
self.freeTextBlock(&decl.link.elf);
|
||||
@ -2189,7 +2189,7 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
|
||||
defer tracy.end();
|
||||
|
||||
if (build_options.have_llvm)
|
||||
if (self.llvm_ir_module) |llvm_ir_module| return try llvm_ir_module.updateDecl(module, decl);
|
||||
if (self.llvm_object) |llvm_object| return try llvm_object.updateDecl(module, decl);
|
||||
|
||||
const typed_value = decl.typed_value.most_recent.typed_value;
|
||||
if (typed_value.val.tag() == .extern_fn) {
|
||||
@ -2673,7 +2673,7 @@ pub fn updateDeclExports(
|
||||
decl: *Module.Decl,
|
||||
exports: []const *Module.Export,
|
||||
) !void {
|
||||
if (self.llvm_ir_module) |_| return;
|
||||
if (self.llvm_object) |_| return;
|
||||
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
@ -2748,7 +2748,7 @@ pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Dec
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
if (self.llvm_ir_module) |_| return;
|
||||
if (self.llvm_object) |_| return;
|
||||
|
||||
const tree = decl.container.file_scope.tree;
|
||||
const node_tags = tree.nodes.items(.tag);
|
||||
@ -2773,7 +2773,7 @@ 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;
|
||||
if (self.llvm_object) |_| return;
|
||||
|
||||
const sym_index = exp.sym_index orelse return;
|
||||
self.global_symbol_free_list.append(self.base.allocator, sym_index) catch {};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user