authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-22 15:04:08-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-23 16:27:39-07:00
log989e782a012e273aec70d03dda7dfe05ecf94938
tree3f69fc2e432699d1e21b60d32e40f26daa0be6ca
parente0623df9f7bcd2f2cf55e11da535bcbd3455d64a

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.

4 files changed, 17 insertions(+), 23 deletions(-)

src/arch/riscv64/CodeGen.zig+2-2
...@@ -133,7 +133,7 @@ const Owner = union(enum) {...@@ -133,7 +133,7 @@ const Owner = union(enum) {
133 switch (owner) {133 switch (owner) {
134 .nav_index => |nav_index| {134 .nav_index => |nav_index| {
135 const elf_file = func.bin_file.cast(.elf).?;135 const elf_file = func.bin_file.cast(.elf).?;
136 return elf_file.zigObjectPtr().?.getOrCreateMetadataForNav(elf_file, nav_index);136 return elf_file.zigObjectPtr().?.getOrCreateMetadataForNav(pt.zcu, nav_index);
137 },137 },
138 .lazy_sym => |lazy_sym| {138 .lazy_sym => |lazy_sym| {
139 const elf_file = func.bin_file.cast(.elf).?;139 const elf_file = func.bin_file.cast(.elf).?;
...@@ -5002,7 +5002,7 @@ fn genCall(...@@ -5002,7 +5002,7 @@ fn genCall(
5002 .func => |func_val| {5002 .func => |func_val| {
5003 if (func.bin_file.cast(.elf)) |elf_file| {5003 if (func.bin_file.cast(.elf)) |elf_file| {
5004 const zo = elf_file.zigObjectPtr().?;5004 const zo = elf_file.zigObjectPtr().?;
5005 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func_val.owner_nav);5005 const sym_index = try zo.getOrCreateMetadataForNav(zcu, func_val.owner_nav);
50065006
5007 if (func.mod.pic) {5007 if (func.mod.pic) {
5008 return func.fail("TODO: genCall pic", .{});5008 return func.fail("TODO: genCall pic", .{});
src/arch/x86_64/CodeGen.zig+2-2
...@@ -126,7 +126,7 @@ const Owner = union(enum) {...@@ -126,7 +126,7 @@ const Owner = union(enum) {
126 const pt = ctx.pt;126 const pt = ctx.pt;
127 switch (owner) {127 switch (owner) {
128 .nav_index => |nav_index| if (ctx.bin_file.cast(.elf)) |elf_file| {128 .nav_index => |nav_index| if (ctx.bin_file.cast(.elf)) |elf_file| {
129 return elf_file.zigObjectPtr().?.getOrCreateMetadataForNav(elf_file, nav_index);129 return elf_file.zigObjectPtr().?.getOrCreateMetadataForNav(pt.zcu, nav_index);
130 } else if (ctx.bin_file.cast(.macho)) |macho_file| {130 } else if (ctx.bin_file.cast(.macho)) |macho_file| {
131 return macho_file.getZigObject().?.getOrCreateMetadataForNav(macho_file, nav_index);131 return macho_file.getZigObject().?.getOrCreateMetadataForNav(macho_file, nav_index);
132 } else if (ctx.bin_file.cast(.coff)) |coff_file| {132 } else if (ctx.bin_file.cast(.coff)) |coff_file| {
...@@ -12605,7 +12605,7 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12605,7 +12605,7 @@ fn genCall(self: *Self, info: union(enum) {
12605 .func => |func| {12605 .func => |func| {
12606 if (self.bin_file.cast(.elf)) |elf_file| {12606 if (self.bin_file.cast(.elf)) |elf_file| {
12607 const zo = elf_file.zigObjectPtr().?;12607 const zo = elf_file.zigObjectPtr().?;
12608 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav);12608 const sym_index = try zo.getOrCreateMetadataForNav(zcu, func.owner_nav);
12609 try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{ .sym_index = sym_index }));12609 try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{ .sym_index = sym_index }));
12610 } else if (self.bin_file.cast(.coff)) |coff_file| {12610 } else if (self.bin_file.cast(.coff)) |coff_file| {
12611 const atom = try coff_file.getOrCreateAtomForNav(func.owner_nav);12611 const atom = try coff_file.getOrCreateAtomForNav(func.owner_nav);
src/codegen.zig+1-1
...@@ -866,7 +866,7 @@ fn genNavRef(...@@ -866,7 +866,7 @@ fn genNavRef(
866 zo.symbol(sym_index).flags.is_extern_ptr = true;866 zo.symbol(sym_index).flags.is_extern_ptr = true;
867 return .{ .mcv = .{ .lea_symbol = sym_index } };867 return .{ .mcv = .{ .lea_symbol = sym_index } };
868 }868 }
869 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, nav_index);869 const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index);
870 if (!single_threaded and is_threadlocal) {870 if (!single_threaded and is_threadlocal) {
871 return .{ .mcv = .{ .load_tlv = sym_index } };871 return .{ .mcv = .{ .load_tlv = sym_index } };
872 }872 }
src/link/Elf/ZigObject.zig+12-18
...@@ -928,7 +928,7 @@ pub fn getNavVAddr(...@@ -928,7 +928,7 @@ pub fn getNavVAddr(
928 nav.name.toSlice(ip),928 nav.name.toSlice(ip),
929 @"extern".lib_name.toSlice(ip),929 @"extern".lib_name.toSlice(ip),
930 ),930 ),
931 else => try self.getOrCreateMetadataForNav(elf_file, nav_index),931 else => try self.getOrCreateMetadataForNav(zcu, nav_index),
932 };932 };
933 const this_sym = self.symbol(this_sym_index);933 const this_sym = self.symbol(this_sym_index);
934 const vaddr = this_sym.address(.{}, elf_file);934 const vaddr = this_sym.address(.{}, elf_file);
...@@ -1102,21 +1102,15 @@ pub fn freeNav(self: *ZigObject, elf_file: *Elf, nav_index: InternPool.Nav.Index...@@ -1102,21 +1102,15 @@ pub fn freeNav(self: *ZigObject, elf_file: *Elf, nav_index: InternPool.Nav.Index
1102 }1102 }
1103}1103}
11041104
1105pub fn getOrCreateMetadataForNav(1105pub fn getOrCreateMetadataForNav(self: *ZigObject, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Symbol.Index {
1106 self: *ZigObject,1106 const gpa = zcu.gpa;
1107 elf_file: *Elf,
1108 nav_index: InternPool.Nav.Index,
1109) !Symbol.Index {
1110 const gpa = elf_file.base.comp.gpa;
1111 const gop = try self.navs.getOrPut(gpa, nav_index);1107 const gop = try self.navs.getOrPut(gpa, nav_index);
1112 if (!gop.found_existing) {1108 if (!gop.found_existing) {
1113 const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;
1114 const symbol_index = try self.newSymbolWithAtom(gpa, 0);1109 const symbol_index = try self.newSymbolWithAtom(gpa, 0);
1115 const zcu = elf_file.base.comp.zcu.?;
1116 const nav_val = Value.fromInterned(zcu.intern_pool.getNav(nav_index).status.resolved.val);1110 const nav_val = Value.fromInterned(zcu.intern_pool.getNav(nav_index).status.resolved.val);
1117 const sym = self.symbol(symbol_index);1111 const sym = self.symbol(symbol_index);
1118 if (nav_val.getVariable(zcu)) |variable| {1112 if (nav_val.getVariable(zcu)) |variable| {
1119 if (variable.is_threadlocal and any_non_single_threaded) {1113 if (variable.is_threadlocal and zcu.comp.config.any_non_single_threaded) {
1120 sym.flags.is_tls = true;1114 sym.flags.is_tls = true;
1121 }1115 }
1122 }1116 }
...@@ -1425,8 +1419,8 @@ pub fn updateFunc(...@@ -1425,8 +1419,8 @@ pub fn updateFunc(
14251419
1426 log.debug("updateFunc {}({d})", .{ ip.getNav(func.owner_nav).fqn.fmt(ip), func.owner_nav });1420 log.debug("updateFunc {}({d})", .{ ip.getNav(func.owner_nav).fqn.fmt(ip), func.owner_nav });
14271421
1428 const sym_index = try self.getOrCreateMetadataForNav(elf_file, func.owner_nav);1422 const sym_index = try self.getOrCreateMetadataForNav(zcu, func.owner_nav);
1429 self.symbol(sym_index).atom(elf_file).?.freeRelocs(self);1423 self.atom(self.symbol(sym_index).ref.index).?.freeRelocs(self);
14301424
1431 var code_buffer = std.ArrayList(u8).init(gpa);1425 var code_buffer = std.ArrayList(u8).init(gpa);
1432 defer code_buffer.deinit();1426 defer code_buffer.deinit();
...@@ -1460,12 +1454,12 @@ pub fn updateFunc(...@@ -1460,12 +1454,12 @@ pub fn updateFunc(
1460 ip.getNav(func.owner_nav).fqn.fmt(ip),1454 ip.getNav(func.owner_nav).fqn.fmt(ip),
1461 });1455 });
1462 const old_rva, const old_alignment = blk: {1456 const old_rva, const old_alignment = blk: {
1463 const atom_ptr = self.symbol(sym_index).atom(elf_file).?;1457 const atom_ptr = self.atom(self.symbol(sym_index).ref.index).?;
1464 break :blk .{ atom_ptr.value, atom_ptr.alignment };1458 break :blk .{ atom_ptr.value, atom_ptr.alignment };
1465 };1459 };
1466 try self.updateNavCode(elf_file, pt, func.owner_nav, sym_index, shndx, code, elf.STT_FUNC);1460 try self.updateNavCode(elf_file, pt, func.owner_nav, sym_index, shndx, code, elf.STT_FUNC);
1467 const new_rva, const new_alignment = blk: {1461 const new_rva, const new_alignment = blk: {
1468 const atom_ptr = self.symbol(sym_index).atom(elf_file).?;1462 const atom_ptr = self.atom(self.symbol(sym_index).ref.index).?;
1469 break :blk .{ atom_ptr.value, atom_ptr.alignment };1463 break :blk .{ atom_ptr.value, atom_ptr.alignment };
1470 };1464 };
14711465
...@@ -1477,7 +1471,7 @@ pub fn updateFunc(...@@ -1477,7 +1471,7 @@ pub fn updateFunc(
1477 .{1471 .{
1478 .index = sym_index,1472 .index = sym_index,
1479 .addr = @intCast(sym.address(.{}, elf_file)),1473 .addr = @intCast(sym.address(.{}, elf_file)),
1480 .size = sym.atom(elf_file).?.size,1474 .size = self.atom(sym.ref.index).?.size,
1481 },1475 },
1482 wip_nav,1476 wip_nav,
1483 );1477 );
...@@ -1500,7 +1494,7 @@ pub fn updateFunc(...@@ -1500,7 +1494,7 @@ pub fn updateFunc(
1500 });1494 });
1501 defer gpa.free(name);1495 defer gpa.free(name);
1502 const osec = if (self.text_index) |sect_sym_index|1496 const osec = if (self.text_index) |sect_sym_index|
1503 self.symbol(sect_sym_index).atom(elf_file).?.output_section_index1497 self.atom(self.symbol(sect_sym_index).ref.index).?.output_section_index
1504 else osec: {1498 else osec: {
1505 const osec = try elf_file.addSection(.{1499 const osec = try elf_file.addSection(.{
1506 .name = try elf_file.insertShString(".text"),1500 .name = try elf_file.insertShString(".text"),
...@@ -1565,7 +1559,7 @@ pub fn updateNav(...@@ -1565,7 +1559,7 @@ pub fn updateNav(
1565 };1559 };
15661560
1567 if (nav_init != .none and Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(zcu)) {1561 if (nav_init != .none and Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(zcu)) {
1568 const sym_index = try self.getOrCreateMetadataForNav(elf_file, nav_index);1562 const sym_index = try self.getOrCreateMetadataForNav(zcu, nav_index);
1569 self.symbol(sym_index).atom(elf_file).?.freeRelocs(self);1563 self.symbol(sym_index).atom(elf_file).?.freeRelocs(self);
15701564
1571 var code_buffer = std.ArrayList(u8).init(zcu.gpa);1565 var code_buffer = std.ArrayList(u8).init(zcu.gpa);
...@@ -1789,7 +1783,7 @@ pub fn updateExports(...@@ -1789,7 +1783,7 @@ pub fn updateExports(
1789 const gpa = elf_file.base.comp.gpa;1783 const gpa = elf_file.base.comp.gpa;
1790 const metadata = switch (exported) {1784 const metadata = switch (exported) {
1791 .nav => |nav| blk: {1785 .nav => |nav| blk: {
1792 _ = try self.getOrCreateMetadataForNav(elf_file, nav);1786 _ = try self.getOrCreateMetadataForNav(zcu, nav);
1793 break :blk self.navs.getPtr(nav).?;1787 break :blk self.navs.getPtr(nav).?;
1794 },1788 },
1795 .uav => |uav| self.uavs.getPtr(uav) orelse blk: {1789 .uav => |uav| self.uavs.getPtr(uav) orelse blk: {