link.Elf.ZigObject.updateFunc: reduce data dependencies

Unfortunately it's not a complete solution, so a follow-up commit will
need to do something more drastic like not do the linker task queue at
the same time as codegen task queue.

From that point, it is possible to do more work at the same time but
that should be a separate branch. This one has gotten big enough.
This commit is contained in:
Andrew Kelley 2024-10-22 15:04:08 -07:00
parent e0623df9f7
commit 989e782a01
4 changed files with 17 additions and 23 deletions

View File

@ -133,7 +133,7 @@ const Owner = union(enum) {
switch (owner) {
.nav_index => |nav_index| {
const elf_file = func.bin_file.cast(.elf).?;
return elf_file.zigObjectPtr().?.getOrCreateMetadataForNav(elf_file, nav_index);
return elf_file.zigObjectPtr().?.getOrCreateMetadataForNav(pt.zcu, nav_index);
},
.lazy_sym => |lazy_sym| {
const elf_file = func.bin_file.cast(.elf).?;
@ -5002,7 +5002,7 @@ fn genCall(
.func => |func_val| {
if (func.bin_file.cast(.elf)) |elf_file| {
const zo = elf_file.zigObjectPtr().?;
const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func_val.owner_nav);
const sym_index = try zo.getOrCreateMetadataForNav(zcu, func_val.owner_nav);
if (func.mod.pic) {
return func.fail("TODO: genCall pic", .{});

View File

@ -126,7 +126,7 @@ const Owner = union(enum) {
const pt = ctx.pt;
switch (owner) {
.nav_index => |nav_index| if (ctx.bin_file.cast(.elf)) |elf_file| {
return elf_file.zigObjectPtr().?.getOrCreateMetadataForNav(elf_file, nav_index);
return elf_file.zigObjectPtr().?.getOrCreateMetadataForNav(pt.zcu, nav_index);
} else if (ctx.bin_file.cast(.macho)) |macho_file| {
return macho_file.getZigObject().?.getOrCreateMetadataForNav(macho_file, nav_index);
} else if (ctx.bin_file.cast(.coff)) |coff_file| {
@ -12605,7 +12605,7 @@ fn genCall(self: *Self, info: union(enum) {
.func => |func| {
if (self.bin_file.cast(.elf)) |elf_file| {
const zo = elf_file.zigObjectPtr().?;
const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav);
const sym_index = try zo.getOrCreateMetadataForNav(zcu, func.owner_nav);
try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{ .sym_index = sym_index }));
} else if (self.bin_file.cast(.coff)) |coff_file| {
const atom = try coff_file.getOrCreateAtomForNav(func.owner_nav);

View File

@ -866,7 +866,7 @@ fn genNavRef(
zo.symbol(sym_index).flags.is_extern_ptr = true;
return .{ .mcv = .{ .lea_symbol = sym_index } };
}
const sym_index = try zo.getOrCreateMetadataForNav(elf_file, nav_index);
const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index);
if (!single_threaded and is_threadlocal) {
return .{ .mcv = .{ .load_tlv = sym_index } };
}

View File

@ -928,7 +928,7 @@ pub fn getNavVAddr(
nav.name.toSlice(ip),
@"extern".lib_name.toSlice(ip),
),
else => try self.getOrCreateMetadataForNav(elf_file, nav_index),
else => try self.getOrCreateMetadataForNav(zcu, nav_index),
};
const this_sym = self.symbol(this_sym_index);
const vaddr = this_sym.address(.{}, elf_file);
@ -1102,21 +1102,15 @@ pub fn freeNav(self: *ZigObject, elf_file: *Elf, nav_index: InternPool.Nav.Index
}
}
pub fn getOrCreateMetadataForNav(
self: *ZigObject,
elf_file: *Elf,
nav_index: InternPool.Nav.Index,
) !Symbol.Index {
const gpa = elf_file.base.comp.gpa;
pub fn getOrCreateMetadataForNav(self: *ZigObject, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Symbol.Index {
const gpa = zcu.gpa;
const gop = try self.navs.getOrPut(gpa, nav_index);
if (!gop.found_existing) {
const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;
const symbol_index = try self.newSymbolWithAtom(gpa, 0);
const zcu = elf_file.base.comp.zcu.?;
const nav_val = Value.fromInterned(zcu.intern_pool.getNav(nav_index).status.resolved.val);
const sym = self.symbol(symbol_index);
if (nav_val.getVariable(zcu)) |variable| {
if (variable.is_threadlocal and any_non_single_threaded) {
if (variable.is_threadlocal and zcu.comp.config.any_non_single_threaded) {
sym.flags.is_tls = true;
}
}
@ -1425,8 +1419,8 @@ pub fn updateFunc(
log.debug("updateFunc {}({d})", .{ ip.getNav(func.owner_nav).fqn.fmt(ip), func.owner_nav });
const sym_index = try self.getOrCreateMetadataForNav(elf_file, func.owner_nav);
self.symbol(sym_index).atom(elf_file).?.freeRelocs(self);
const sym_index = try self.getOrCreateMetadataForNav(zcu, func.owner_nav);
self.atom(self.symbol(sym_index).ref.index).?.freeRelocs(self);
var code_buffer = std.ArrayList(u8).init(gpa);
defer code_buffer.deinit();
@ -1460,12 +1454,12 @@ pub fn updateFunc(
ip.getNav(func.owner_nav).fqn.fmt(ip),
});
const old_rva, const old_alignment = blk: {
const atom_ptr = self.symbol(sym_index).atom(elf_file).?;
const atom_ptr = self.atom(self.symbol(sym_index).ref.index).?;
break :blk .{ atom_ptr.value, atom_ptr.alignment };
};
try self.updateNavCode(elf_file, pt, func.owner_nav, sym_index, shndx, code, elf.STT_FUNC);
const new_rva, const new_alignment = blk: {
const atom_ptr = self.symbol(sym_index).atom(elf_file).?;
const atom_ptr = self.atom(self.symbol(sym_index).ref.index).?;
break :blk .{ atom_ptr.value, atom_ptr.alignment };
};
@ -1477,7 +1471,7 @@ pub fn updateFunc(
.{
.index = sym_index,
.addr = @intCast(sym.address(.{}, elf_file)),
.size = sym.atom(elf_file).?.size,
.size = self.atom(sym.ref.index).?.size,
},
wip_nav,
);
@ -1500,7 +1494,7 @@ pub fn updateFunc(
});
defer gpa.free(name);
const osec = if (self.text_index) |sect_sym_index|
self.symbol(sect_sym_index).atom(elf_file).?.output_section_index
self.atom(self.symbol(sect_sym_index).ref.index).?.output_section_index
else osec: {
const osec = try elf_file.addSection(.{
.name = try elf_file.insertShString(".text"),
@ -1565,7 +1559,7 @@ pub fn updateNav(
};
if (nav_init != .none and Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(zcu)) {
const sym_index = try self.getOrCreateMetadataForNav(elf_file, nav_index);
const sym_index = try self.getOrCreateMetadataForNav(zcu, nav_index);
self.symbol(sym_index).atom(elf_file).?.freeRelocs(self);
var code_buffer = std.ArrayList(u8).init(zcu.gpa);
@ -1789,7 +1783,7 @@ pub fn updateExports(
const gpa = elf_file.base.comp.gpa;
const metadata = switch (exported) {
.nav => |nav| blk: {
_ = try self.getOrCreateMetadataForNav(elf_file, nav);
_ = try self.getOrCreateMetadataForNav(zcu, nav);
break :blk self.navs.getPtr(nav).?;
},
.uav => |uav| self.uavs.getPtr(uav) orelse blk: {