diff --git a/lib/std/c/tokenizer.zig b/lib/std/c/tokenizer.zig index de8b1a429c5cc728d689516b466e07be00a53787..2e7722d0259e6d671a7d630edcbac9615705e5f4 100644 --- a/lib/std/c/tokenizer.zig +++ b/lib/std/c/tokenizer.zig @@ -1,5 +1,4 @@ const std = @import("std"); -const mem = std.mem; pub const Token = struct { id: Id, diff --git a/lib/std/comptime_string_map.zig b/lib/std/comptime_string_map.zig index e6859c32c15d9276dc4a6676b7dfe3216788131a..ee5e714c5de2c54d817808ad125921a3f68eb142 100644 --- a/lib/std/comptime_string_map.zig +++ b/lib/std/comptime_string_map.zig @@ -9,18 +9,12 @@ const mem = std.mem; /// You can pass `struct { []const u8 }` (only keys) tuples if `V` is `void`. pub fn ComptimeStringMap(comptime V: type, comptime kvs_list: anytype) type { const precomputed = comptime blk: { - @setEvalBranchQuota(2000); + @setEvalBranchQuota(1500); const KV = struct { key: []const u8, value: V, }; var sorted_kvs: [kvs_list.len]KV = undefined; - const lenAsc = (struct { - fn lenAsc(context: void, a: KV, b: KV) bool { - _ = context; - return a.key.len < b.key.len; - } - }).lenAsc; for (kvs_list, 0..) |kv, i| { if (V != void) { sorted_kvs[i] = .{ .key = kv.@"0", .value = kv.@"1" }; @@ -28,7 +22,20 @@ pub fn ComptimeStringMap(comptime V: type, comptime kvs_list: anytype) type { sorted_kvs[i] = .{ .key = kv.@"0", .value = {} }; } } - mem.sort(KV, &sorted_kvs, {}, lenAsc); + + const SortContext = struct { + kvs: []KV, + + pub fn lessThan(ctx: @This(), a: usize, b: usize) bool { + return ctx.kvs[a].key.len < ctx.kvs[b].key.len; + } + + pub fn swap(ctx: @This(), a: usize, b: usize) void { + return std.mem.swap(KV, &ctx.kvs[a], &ctx.kvs[b]); + } + }; + mem.sortUnstableContext(0, sorted_kvs.len, SortContext{ .kvs = &sorted_kvs }); + const min_len = sorted_kvs[0].key.len; const max_len = sorted_kvs[sorted_kvs.len - 1].key.len; var len_indexes: [max_len + 1]usize = undefined; diff --git a/lib/std/enums.zig b/lib/std/enums.zig index 9931b1d7c104072f72610f9a187a92f17e1313e6..3aa5a4fa79af17f50b009a02f2a7d989da39f634 100644 --- a/lib/std/enums.zig +++ b/lib/std/enums.zig @@ -1289,10 +1289,6 @@ test "std.enums.ensureIndexer" { }); } -fn ascByValue(ctx: void, comptime a: EnumField, comptime b: EnumField) bool { - _ = ctx; - return a.value < b.value; -} pub fn EnumIndexer(comptime E: type) type { if (!@typeInfo(E).Enum.is_exhaustive) { @compileError("Cannot create an enum indexer for a non-exhaustive enum."); @@ -1300,24 +1296,37 @@ pub fn EnumIndexer(comptime E: type) type { const const_fields = std.meta.fields(E); var fields = const_fields[0..const_fields.len].*; - if (fields.len == 0) { - return struct { - pub const Key = E; - pub const count: usize = 0; - pub fn indexOf(e: E) usize { - _ = e; - unreachable; - } - pub fn keyForIndex(i: usize) E { - _ = i; - unreachable; - } - }; - } - std.mem.sort(EnumField, &fields, {}, ascByValue); const min = fields[0].value; const max = fields[fields.len - 1].value; const fields_len = fields.len; + if (fields_len == 0) { + return struct { + pub const Key = E; + pub const count: usize = 0; + pub fn indexOf(e: E) usize { + _ = e; + unreachable; + } + pub fn keyForIndex(i: usize) E { + _ = i; + unreachable; + } + }; + } + + const SortContext = struct { + fields: []EnumField, + + pub fn lessThan(comptime ctx: @This(), comptime a: usize, comptime b: usize) bool { + return ctx.fields[a].value < ctx.fields[b].value; + } + + pub fn swap(comptime ctx: @This(), comptime a: usize, comptime b: usize) void { + return std.mem.swap(EnumField, &ctx.fields[a], &ctx.fields[b]); + } + }; + std.sort.insertionContext(0, fields_len, SortContext{ .fields = &fields }); + if (max - min == fields.len - 1) { return struct { pub const Key = E; diff --git a/lib/std/sort.zig b/lib/std/sort.zig index 1ae7e1e574e59620fdaf422b12f8d1cf9602ff21..48a54548e61a037880724ae01178447de3f86f1a 100644 --- a/lib/std/sort.zig +++ b/lib/std/sort.zig @@ -366,7 +366,7 @@ test "sort with context in the middle of a slice" { const slice = buf[0..case[0].len]; @memcpy(slice, case[0]); sortFn(range.start, range.end, Context{ .items = slice }); - try testing.expectEqualSlices(i32, slice[range.start..range.end], case[1][range.start..range.end]); + try testing.expectEqualSlices(i32, case[1][range.start..range.end], slice[range.start..range.end]); } } } diff --git a/lib/std/sort/block.zig b/lib/std/sort/block.zig index 518d148a732f10cf95ef680b482eae69da0af2cd..a61ea6e32603892d5c5585dff7a5bfec7fabd03f 100644 --- a/lib/std/sort/block.zig +++ b/lib/std/sort/block.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("../std.zig"); const sort = std.sort; const math = std.math; @@ -100,8 +101,16 @@ pub fn block( comptime T: type, items: []T, context: anytype, - comptime lessThan: fn (@TypeOf(context), lhs: T, rhs: T) bool, + comptime lessThanFn: fn (@TypeOf(context), lhs: T, rhs: T) bool, ) void { + const lessThan = if (builtin.mode == .Debug) struct { + fn lessThan(ctx: @TypeOf(context), lhs: T, rhs: T) bool { + const lt = lessThanFn(ctx, lhs, rhs); + const gt = lessThanFn(ctx, rhs, lhs); + std.debug.assert(!(lt and gt)); + return lt; + } + }.lessThan else lessThanFn; // Implementation ported from https://github.com/BonzaiThePenguin/WikiSort/blob/master/WikiSort.c var cache: [512]T = undefined; diff --git a/src/arch/x86_64/Encoding.zig b/src/arch/x86_64/Encoding.zig index ca260f5ec4af81070e2035f88eece5d1d4f622ad..d3c954fecb1580fb465165eecd8215c9540079e1 100644 --- a/src/arch/x86_64/Encoding.zig +++ b/src/arch/x86_64/Encoding.zig @@ -767,7 +767,7 @@ fn estimateInstructionLength(prefix: Prefix, encoding: Encoding, ops: []const Op } const mnemonic_to_encodings_map = init: { - @setEvalBranchQuota(30_000); + @setEvalBranchQuota(50_000); const encodings = @import("encodings.zig"); var entries = encodings.table; std.mem.sort(encodings.Entry, &entries, {}, struct {