Skip to content

Commit

Permalink
x86_64: fix crashes compiling the compiler and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobly0 committed Jan 16, 2025
1 parent 3f7dff1 commit 124e2d9
Show file tree
Hide file tree
Showing 8 changed files with 444 additions and 388 deletions.
4 changes: 3 additions & 1 deletion lib/std/Thread.zig
Original file line number Diff line number Diff line change
Expand Up @@ -372,9 +372,11 @@ pub const SpawnConfig = struct {
// https://github.com/ziglang/zig/issues/157

/// Size in bytes of the Thread's stack
stack_size: usize = 16 * 1024 * 1024,
stack_size: usize = default_stack_size,
/// The allocator to be used to allocate memory for the to-be-spawned thread
allocator: ?std.mem.Allocator = null,

pub const default_stack_size = 16 * 1024 * 1024;
};

pub const SpawnError = error{
Expand Down
6 changes: 5 additions & 1 deletion lib/std/Thread/Pool.zig
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub const Options = struct {
allocator: std.mem.Allocator,
n_jobs: ?usize = null,
track_ids: bool = false,
stack_size: usize = std.Thread.SpawnConfig.default_stack_size,
};

pub fn init(pool: *Pool, options: Options) !void {
Expand Down Expand Up @@ -54,7 +55,10 @@ pub fn init(pool: *Pool, options: Options) !void {
errdefer pool.join(spawned);

for (pool.threads) |*thread| {
thread.* = try std.Thread.spawn(.{}, worker, .{pool});
thread.* = try std.Thread.spawn(.{
.stack_size = options.stack_size,
.allocator = allocator,
}, worker, .{pool});
spawned += 1;
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/std/crypto/aes/aesni.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const mem = std.mem;
const debug = std.debug;

const has_vaes = builtin.cpu.arch == .x86_64 and std.Target.x86.featureSetHas(builtin.cpu.features, .vaes);
const has_avx512f = builtin.cpu.arch == .x86_64 and std.Target.x86.featureSetHas(builtin.cpu.features, .avx512f);
const has_avx512f = builtin.cpu.arch == .x86_64 and builtin.zig_backend != .stage2_x86_64 and std.Target.x86.featureSetHas(builtin.cpu.features, .avx512f);

/// A single AES block.
pub const Block = struct {
Expand Down
716 changes: 388 additions & 328 deletions src/arch/x86_64/CodeGen.zig

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions src/arch/x86_64/abi.zig
Original file line number Diff line number Diff line change
Expand Up @@ -540,8 +540,12 @@ pub fn getCAbiSseReturnRegs(cc: std.builtin.CallingConvention.Tag) []const Regis
}

pub fn getCAbiLinkerScratchReg(cc: std.builtin.CallingConvention.Tag) Register {
const int_return_regs = getCAbiIntReturnRegs(cc);
return int_return_regs[int_return_regs.len - 1];
return switch (cc) {
.auto => zigcc.int_return_regs[zigcc.int_return_regs.len - 1],
.x86_64_sysv => SysV.c_abi_int_return_regs[0],
.x86_64_win => Win64.c_abi_int_return_regs[0],
else => unreachable,
};
}

const gp_regs = [_]Register{
Expand Down
8 changes: 8 additions & 0 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ test {
_ = Package;
}

const thread_stack_size = switch (builtin.zig_backend) {
else => std.Thread.SpawnConfig.default_stack_size,
.stage2_x86_64 => 32 << 20,
};

pub const std_options: std.Options = .{
.wasiCwd = wasi_cwd,
.logFn = log,
Expand Down Expand Up @@ -3320,6 +3325,7 @@ fn buildOutputType(
.allocator = gpa,
.n_jobs = @min(@max(n_jobs orelse std.Thread.getCpuCount() catch 1, 1), std.math.maxInt(Zcu.PerThread.IdBacking)),
.track_ids = true,
.stack_size = thread_stack_size,
});
defer thread_pool.deinit();

Expand Down Expand Up @@ -5024,6 +5030,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
.allocator = gpa,
.n_jobs = @min(@max(n_jobs orelse std.Thread.getCpuCount() catch 1, 1), std.math.maxInt(Zcu.PerThread.IdBacking)),
.track_ids = true,
.stack_size = thread_stack_size,
});
defer thread_pool.deinit();

Expand Down Expand Up @@ -5460,6 +5467,7 @@ fn jitCmd(
.allocator = gpa,
.n_jobs = @min(@max(std.Thread.getCpuCount() catch 1, 1), std.math.maxInt(Zcu.PerThread.IdBacking)),
.track_ids = true,
.stack_size = thread_stack_size,
});
defer thread_pool.deinit();

Expand Down
78 changes: 23 additions & 55 deletions src/register_manager.zig
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,6 @@ pub fn RegisterManager(
return @alignCast(@fieldParentPtr("register_manager", self));
}

fn excludeRegister(reg: Register, register_class: RegisterBitSet) bool {
const index = indexOfRegIntoTracked(reg) orelse return true;
return !register_class.isSet(index);
}

fn markRegIndexAllocated(self: *Self, tracked_index: TrackedIndex) void {
self.allocated_registers.set(tracked_index);
}
Expand Down Expand Up @@ -234,28 +229,20 @@ pub fn RegisterManager(
) ?[count]Register {
comptime assert(count > 0 and count <= tracked_registers.len);

var free_and_not_locked_registers = self.free_registers;
free_and_not_locked_registers.setIntersection(register_class);

var unlocked_registers = self.locked_registers;
unlocked_registers.toggleAll();

free_and_not_locked_registers.setIntersection(unlocked_registers);

if (free_and_not_locked_registers.count() < count) return null;
var free_and_unlocked_registers = self.locked_registers;
free_and_unlocked_registers.toggleAll();
free_and_unlocked_registers.setIntersection(self.free_registers);
free_and_unlocked_registers.setIntersection(register_class);

var regs: [count]Register = undefined;
var i: usize = 0;
for (tracked_registers) |reg| {
if (i >= count) break;
if (excludeRegister(reg, register_class)) continue;
if (self.isRegLocked(reg)) continue;
if (!self.isRegFree(reg)) continue;

regs[i] = reg;
var it = free_and_unlocked_registers.iterator(.{});
while (it.next()) |reg_index| {
regs[i] = regAtTrackedIndex(@intCast(reg_index));
i += 1;
if (i >= count) break;
}
assert(i == count);
if (i < count) return null;

for (regs, insts) |reg, inst| {
log.debug("tryAllocReg {} for inst {?}", .{ reg, inst });
Expand Down Expand Up @@ -290,46 +277,27 @@ pub fn RegisterManager(
) AllocationError![count]Register {
comptime assert(count > 0 and count <= tracked_registers.len);

var locked_registers = self.locked_registers;
locked_registers.setIntersection(register_class);

if (count > register_class.count() - locked_registers.count()) return error.OutOfRegisters;

const result = self.tryAllocRegs(count, insts, register_class) orelse blk: {
var unlocked_registers = self.locked_registers;
unlocked_registers.toggleAll();
unlocked_registers.setIntersection(register_class);

// We'll take over the first count registers. Spill
// the instructions that were previously there to a
// stack allocations.
var regs: [count]Register = undefined;
var i: usize = 0;
for (tracked_registers) |reg| {
if (i >= count) break;
if (excludeRegister(reg, register_class)) break;
if (self.isRegLocked(reg)) continue;

log.debug("allocReg {} for inst {?}", .{ reg, insts[i] });
regs[i] = reg;
self.markRegAllocated(reg);
const index = indexOfRegIntoTracked(reg).?; // indexOfReg() on a callee-preserved reg should never return null
if (insts[i]) |inst| {
// Track the register
if (self.isRegFree(reg)) {
self.markRegUsed(reg);
} else {
const spilled_inst = self.registers[index];
try self.getFunction().spillInstruction(reg, spilled_inst);
}
self.registers[index] = inst;
} else {
// Don't track the register
if (!self.isRegFree(reg)) {
const spilled_inst = self.registers[index];
try self.getFunction().spillInstruction(reg, spilled_inst);
self.freeReg(reg);
}
}

var it = unlocked_registers.iterator(.{});
while (it.next()) |reg_index| {
const tracked_index: TrackedIndex = @intCast(reg_index);
if (!self.isRegIndexFree(tracked_index) and
self.registers[tracked_index].unwrap() == .target) continue;
try self.getRegIndex(tracked_index, insts[i]);
regs[i] = regAtTrackedIndex(tracked_index);
i += 1;
if (i >= count) break;
}
if (i < count) return error.OutOfRegisters;

break :blk regs;
};
Expand All @@ -351,7 +319,7 @@ pub fn RegisterManager(
/// Spills the register if it is currently allocated. If a
/// corresponding instruction is passed, will also track this
/// register.
fn getRegIndex(
pub fn getRegIndex(
self: *Self,
tracked_index: TrackedIndex,
inst: ?Air.Inst.Index,
Expand Down
10 changes: 10 additions & 0 deletions test/behavior/x86_64/math.zig
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,16 @@ fn testBinary(comptime op: anytype) !void {
0xb7935f5c2f3b1ae7a422c0a7c446884294b7d5370bada307d2fe5a4c4284a999,
0x310e6e196ba4f143b8d285ca6addf7f3bb3344224aff221b27607a31e148be08,
);
try testType(
u258,
0x186d5ddaab8cb8cb04e5b41e36f812e039d008baf49f12894c39e29a07796d800,
0x2072daba6ffad168826163eb136f6d28ca4360c8e7e5e41e29755e19e4753a4f5,
);
try testType(
u495,
0x6eaf4e252b3bf74b75bac59e0b43ca5326bad2a25b3fdb74a67ef132ac5e47d72eebc3316fb2351ee66c50dc5afb92a75cea9b0e35160652c7db39eeb158,
0x49fbed744a92b549d8c05bb3512c617d24dd824f3f69bdf3923bc326a75674b85f5b828d2566fab9c86f571d12c2a63c9164feb0d191d27905533d09622a,
);
try testType(
u512,
0xe5b1fedca3c77db765e517aabd05ffc524a3a8aff1784bbf67c45b894447ede32b65b9940e78173c591e56e078932d465f235aece7ad47b7f229df7ba8f12295,
Expand Down

0 comments on commit 124e2d9

Please sign in to comment.