mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
x86_64: fix crashes compiling the compiler and tests
This commit is contained in:
parent
c3d33440f0
commit
8c8dfb35f3
@ -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{
|
||||
|
||||
@ -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 {
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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{
|
||||
|
||||
@ -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,
|
||||
@ -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();
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
@ -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 });
|
||||
@ -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;
|
||||
};
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user