Skip to content

Commit 03d0e29

Browse files
authored
Merge pull request #21710 from alexrp/function-alignment
Some improvements to the compiler's handling of function alignment
2 parents 5769592 + 6c1e306 commit 03d0e29

File tree

9 files changed

+102
-30
lines changed

9 files changed

+102
-30
lines changed

src/Sema.zig

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26658,9 +26658,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2665826658
if (val.isGenericPoison()) {
2665926659
break :blk null;
2666026660
}
26661-
const alignment = try sema.validateAlignAllowZero(block, align_src, try val.toUnsignedIntSema(pt));
26662-
const default = target_util.defaultFunctionAlignment(target);
26663-
break :blk if (alignment == default) .none else alignment;
26661+
break :blk try sema.validateAlignAllowZero(block, align_src, try val.toUnsignedIntSema(pt));
2666426662
} else if (extra.data.bits.has_align_ref) blk: {
2666526663
const align_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
2666626664
extra_index += 1;
@@ -26678,9 +26676,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2667826676
error.GenericPoison => break :blk null,
2667926677
else => |e| return e,
2668026678
};
26681-
const alignment = try sema.validateAlignAllowZero(block, align_src, try align_val.toUnsignedIntSema(pt));
26682-
const default = target_util.defaultFunctionAlignment(target);
26683-
break :blk if (alignment == default) .none else alignment;
26679+
break :blk try sema.validateAlignAllowZero(block, align_src, try align_val.toUnsignedIntSema(pt));
2668426680
} else .none;
2668526681

2668626682
const @"addrspace": ?std.builtin.AddressSpace = if (extra.data.bits.has_addrspace_body) blk: {

src/Type.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1027,7 +1027,7 @@ pub fn abiAlignmentInner(
10271027
},
10281028

10291029
// represents machine code; not a pointer
1030-
.func_type => return .{ .scalar = target_util.defaultFunctionAlignment(target) },
1030+
.func_type => return .{ .scalar = target_util.minFunctionAlignment(target) },
10311031

10321032
.simple_type => |t| switch (t) {
10331033
.bool,

src/codegen/llvm.zig

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,10 +458,15 @@ const DataLayoutBuilder = struct {
458458
if (idx != size) try writer.print(":{d}", .{idx});
459459
}
460460
}
461-
if (self.target.cpu.arch.isArmOrThumb()) try writer.writeAll("-Fi8") // for thumb interwork
461+
if (self.target.cpu.arch.isArmOrThumb())
462+
try writer.writeAll("-Fi8") // for thumb interwork
462463
else if (self.target.cpu.arch == .powerpc64 and
463-
self.target.os.tag != .freebsd and self.target.abi != .musl)
464+
self.target.os.tag != .freebsd and
465+
self.target.os.tag != .openbsd and
466+
!self.target.abi.isMusl())
464467
try writer.writeAll("-Fi64")
468+
else if (self.target.cpu.arch.isPowerPC() and self.target.os.tag == .aix)
469+
try writer.writeAll(if (self.target.cpu.arch.isPowerPC64()) "-Fi64" else "-Fi32")
465470
else if (self.target.cpu.arch.isPowerPC())
466471
try writer.writeAll("-Fn32");
467472
if (self.target.cpu.arch != .hexagon) {
@@ -574,6 +579,8 @@ const DataLayoutBuilder = struct {
574579
self.target.os.tag == .uefi or self.target.os.tag == .windows or
575580
self.target.cpu.arch == .riscv32)
576581
try writer.print("-S{d}", .{stack_abi});
582+
if (self.target.cpu.arch.isAARCH64())
583+
try writer.writeAll("-Fn32");
577584
switch (self.target.cpu.arch) {
578585
.hexagon, .ve => {
579586
try self.typeAlignment(.vector, 32, 128, 128, true, writer);

src/link/Coff.zig

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,9 +1388,11 @@ fn updateNavCode(
13881388

13891389
log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index });
13901390

1391-
const required_alignment = pt.navAlignment(nav_index).max(
1392-
target_util.minFunctionAlignment(zcu.navFileScope(nav_index).mod.resolved_target.result),
1393-
);
1391+
const target = zcu.navFileScope(nav_index).mod.resolved_target.result;
1392+
const required_alignment = switch (pt.navAlignment(nav_index)) {
1393+
.none => target_util.defaultFunctionAlignment(target),
1394+
else => |a| a.maxStrict(target_util.minFunctionAlignment(target)),
1395+
};
13941396

13951397
const nav_metadata = coff.navs.get(nav_index).?;
13961398
const atom_index = nav_metadata.atom;

src/link/Dwarf.zig

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2372,8 +2372,11 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
23722372
try wip_nav.infoAddrSym(sym_index, 0);
23732373
wip_nav.func_high_pc = @intCast(wip_nav.debug_info.items.len);
23742374
try diw.writeInt(u32, 0, dwarf.endian);
2375-
try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse
2376-
target_info.defaultFunctionAlignment(file.mod.resolved_target.result).toByteUnits().?);
2375+
const target = file.mod.resolved_target.result;
2376+
try uleb128(diw, switch (nav.status.resolved.alignment) {
2377+
.none => target_info.defaultFunctionAlignment(target),
2378+
else => |a| a.maxStrict(target_info.minFunctionAlignment(target)),
2379+
}.toByteUnits().?);
23772380
try diw.writeByte(@intFromBool(false));
23782381
try diw.writeByte(@intFromBool(func_type.return_type == .noreturn_type));
23792382

src/link/Elf/ZigObject.zig

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,9 +1271,11 @@ fn updateNavCode(
12711271

12721272
log.debug("updateNavCode {}({d})", .{ nav.fqn.fmt(ip), nav_index });
12731273

1274-
const required_alignment = pt.navAlignment(nav_index).max(
1275-
target_util.minFunctionAlignment(zcu.navFileScope(nav_index).mod.resolved_target.result),
1276-
);
1274+
const target = zcu.navFileScope(nav_index).mod.resolved_target.result;
1275+
const required_alignment = switch (pt.navAlignment(nav_index)) {
1276+
.none => target_util.defaultFunctionAlignment(target),
1277+
else => |a| a.maxStrict(target_util.minFunctionAlignment(target)),
1278+
};
12771279

12781280
const sym = self.symbol(sym_index);
12791281
const esym = &self.symtab.items(.elf_sym)[sym.esym_index];

src/link/MachO/ZigObject.zig

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -962,9 +962,11 @@ fn updateNavCode(
962962

963963
log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index });
964964

965-
const required_alignment = pt.navAlignment(nav_index).max(
966-
target_util.minFunctionAlignment(zcu.navFileScope(nav_index).mod.resolved_target.result),
967-
);
965+
const target = zcu.navFileScope(nav_index).mod.resolved_target.result;
966+
const required_alignment = switch (pt.navAlignment(nav_index)) {
967+
.none => target_util.defaultFunctionAlignment(target),
968+
else => |a| a.maxStrict(target_util.minFunctionAlignment(target)),
969+
};
968970

969971
const sect = &macho_file.sections.items(.header)[sect_index];
970972
const sym = &self.symbols.items[sym_index];

src/target.zig

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -436,35 +436,88 @@ pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 {
436436
}
437437
}
438438

439-
/// This function returns 1 if function alignment is not observable or settable.
439+
/// This function returns 1 if function alignment is not observable or settable. Note that this
440+
/// value will not necessarily match the backend's default function alignment (e.g. for LLVM).
440441
pub fn defaultFunctionAlignment(target: std.Target) Alignment {
442+
// Overrides of the minimum for performance.
441443
return switch (target.cpu.arch) {
442-
.arm, .armeb => .@"4",
443-
.aarch64, .aarch64_be => .@"4",
444-
.sparc, .sparc64 => .@"4",
445-
.riscv64 => .@"2",
446-
else => .@"1",
444+
.csky,
445+
.thumb,
446+
.thumbeb,
447+
.xcore,
448+
=> .@"4",
449+
.aarch64,
450+
.aarch64_be,
451+
.hexagon,
452+
.powerpc,
453+
.powerpcle,
454+
.powerpc64,
455+
.powerpc64le,
456+
.s390x,
457+
.x86,
458+
.x86_64,
459+
=> .@"16",
460+
.loongarch32,
461+
.loongarch64,
462+
=> .@"32",
463+
else => minFunctionAlignment(target),
447464
};
448465
}
449466

467+
/// This function returns 1 if function alignment is not observable or settable.
450468
pub fn minFunctionAlignment(target: std.Target) Alignment {
451469
return switch (target.cpu.arch) {
470+
.riscv32,
471+
.riscv64,
472+
=> if (std.Target.riscv.featureSetHasAny(target.cpu.features, .{ .c, .zca })) .@"2" else .@"4",
473+
.thumb,
474+
.thumbeb,
475+
.csky,
476+
.m68k,
477+
.msp430,
478+
.s390x,
479+
.xcore,
480+
=> .@"2",
481+
.arc,
452482
.arm,
453483
.armeb,
454484
.aarch64,
455485
.aarch64_be,
456-
.riscv32,
457-
.riscv64,
486+
.hexagon,
487+
.lanai,
488+
.loongarch32,
489+
.loongarch64,
490+
.mips,
491+
.mipsel,
492+
.powerpc,
493+
.powerpcle,
494+
.powerpc64,
495+
.powerpc64le,
458496
.sparc,
459497
.sparc64,
460-
=> .@"2",
498+
.xtensa,
499+
=> .@"4",
500+
.bpfel,
501+
.bpfeb,
502+
.mips64,
503+
.mips64el,
504+
=> .@"8",
505+
.ve,
506+
=> .@"16",
461507
else => .@"1",
462508
};
463509
}
464510

465511
pub fn supportsFunctionAlignment(target: std.Target) bool {
466512
return switch (target.cpu.arch) {
467-
.wasm32, .wasm64 => false,
513+
.nvptx,
514+
.nvptx64,
515+
.spirv,
516+
.spirv32,
517+
.spirv64,
518+
.wasm32,
519+
.wasm64,
520+
=> false,
468521
else => true,
469522
};
470523
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export fn entry() align(0) void {}
2+
3+
// error
4+
// backend=stage2
5+
// target=nvptx-cuda,nvptx64-cuda,spirv-vulkan,spirv32-opencl,spirv64-opencl,wasm32-freestanding,wasm64-freestanding
6+
//
7+
// :1:25: error: target does not support function alignment

0 commit comments

Comments
 (0)