mitchell's touchups

- benchmark: avoid buffers to avoid a memcpy
- build: keep frame pointers on macOS. There was some debug changes from
  Zig 0.15 and this helps. Also, Apple actually requires/expects x29 to
  always be a frame pointer.
- build/macos: force libSystem symbols instead of compiler-rt
- global: add InitOpts.tool so that ghostty-gen/bench can parse their
  own actions in `+action`
- quirks: provide our own vectorized memset. see the comment for more
  details why.
- synthetic: fix UB by accessing global.io before it was initialized
- terminal/hash_map: force inline for unique repr types. Zig 0.15
  inlined and 0.16 doesn't, measured a huge slowdown in hyperlink
  benchmarks.
- terminal: add explicit `@Vector` usage for storing a run of identical cells
  as well as for scanning printable cells. This auto-vectorized in Zig
  0.15 but not in Zig 0.16. This produces the same assembly.
- unicode: properties and LUT need power-of-two backing integer to avoid
  bad LLVM codegen
This commit is contained in:
Mitchell Hashimoto
2026-07-20 20:33:23 -07:00
parent e8525c0fd9
commit f2a7652aba
35 changed files with 936 additions and 151 deletions

View File

@@ -579,8 +579,30 @@ pub fn Stream(comptime H: type) type {
continue;
}
// Find the end of the printable run. This is an
// early-exit search loop that LLVM won't
// auto-vectorize, and printable runs dominate real
// input, so scan several codepoints at a time
// manually (same idiom as the printSliceFill run
// scan).
var end = i + 1;
while (end < cps.len and cps[end] > 0xF) end += 1;
scan: {
if (simd.lanes(u32)) |lanes| {
const V = @Vector(lanes, u32);
const threshold: V = @splat(0xF);
while (end + lanes <= cps.len) {
const v: V = cps[end..][0..lanes].*;
const gt = v > threshold;
if (!@reduce(.And, gt)) {
const bits: std.meta.Int(.unsigned, lanes) = @bitCast(gt);
end += @ctz(~bits);
break :scan;
}
end += lanes;
}
}
while (end < cps.len and cps[end] > 0xF) end += 1;
}
self.handler.vt(.print_slice, .{ .cps = cps[i..end] });
i = end;
}