authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-11-22 20:09:54-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-11-23 04:38:31-05:00
log115ec25f2e4eed5033f34eaee8bf3477ff417ecc
treed7bfc1bbc3cea5ce520e3bcf0b12e131ae04ac75
parentfcc071c9bd6b0c8e010957156505878ea6c0c55d

x86_64: optimize compile time of `mnemonic_to_encodings_map`

Remove all comptime sorts, making it compile 3x faster.

1 files changed, 19 insertions(+), 23 deletions(-)

src/arch/x86_64/Encoding.zig+19-23
...@@ -812,36 +812,32 @@ fn estimateInstructionLength(prefix: Prefix, encoding: Encoding, ops: []const Op...@@ -812,36 +812,32 @@ fn estimateInstructionLength(prefix: Prefix, encoding: Encoding, ops: []const Op
812}812}
813813
814const mnemonic_to_encodings_map = init: {814const mnemonic_to_encodings_map = init: {
815 @setEvalBranchQuota(60_000);815 @setEvalBranchQuota(4_000);
816 const mnemonic_count = @typeInfo(Mnemonic).Enum.fields.len;
817 var mnemonic_map: [mnemonic_count][]Data = .{&.{}} ** mnemonic_count;
816 const encodings = @import("encodings.zig");818 const encodings = @import("encodings.zig");
817 var entries = encodings.table;819 for (encodings.table) |entry| mnemonic_map[@intFromEnum(entry[0])].len += 1;
818 std.mem.sort(encodings.Entry, &entries, {}, struct {820 var data_storage: [encodings.table.len]Data = undefined;
819 fn lessThan(_: void, lhs: encodings.Entry, rhs: encodings.Entry) bool {821 var storage_i: usize = 0;
820 return @intFromEnum(lhs[0]) < @intFromEnum(rhs[0]);822 for (&mnemonic_map) |*value| {
821 }823 value.ptr = data_storage[storage_i..].ptr;
822 }.lessThan);824 storage_i += value.len;
823 var data_storage: [entries.len]Data = undefined;825 }
824 var mnemonic_map: [@typeInfo(Mnemonic).Enum.fields.len][]const Data = undefined;826 var mnemonic_i: [mnemonic_count]usize = .{0} ** mnemonic_count;
825 var mnemonic_int = 0;827 const ops_len = @typeInfo(std.meta.FieldType(Data, .ops)).Array.len;
826 var mnemonic_start = 0;828 const opc_len = @typeInfo(std.meta.FieldType(Data, .opc)).Array.len;
827 for (&data_storage, entries, 0..) |*data, entry, data_index| {829 for (encodings.table) |entry| {
828 data.* = .{830 const i = &mnemonic_i[@intFromEnum(entry[0])];
831 mnemonic_map[@intFromEnum(entry[0])][i.*] = .{
829 .op_en = entry[1],832 .op_en = entry[1],
830 .ops = (entry[2] ++ .{.none} ** (data.ops.len - entry[2].len)).*,833 .ops = (entry[2] ++ .{.none} ** (ops_len - entry[2].len)).*,
831 .opc_len = entry[3].len,834 .opc_len = entry[3].len,
832 .opc = (entry[3] ++ .{undefined} ** (data.opc.len - entry[3].len)).*,835 .opc = (entry[3] ++ .{undefined} ** (opc_len - entry[3].len)).*,
833 .modrm_ext = entry[4],836 .modrm_ext = entry[4],
834 .mode = entry[5],837 .mode = entry[5],
835 .feature = entry[6],838 .feature = entry[6],
836 };839 };
837 while (mnemonic_int < @intFromEnum(entry[0])) : (mnemonic_int += 1) {840 i.* += 1;
838 mnemonic_map[mnemonic_int] = data_storage[mnemonic_start..data_index];
839 mnemonic_start = data_index;
840 }
841 }
842 while (mnemonic_int < mnemonic_map.len) : (mnemonic_int += 1) {
843 mnemonic_map[mnemonic_int] = data_storage[mnemonic_start..];
844 mnemonic_start = data_storage.len;
845 }841 }
846 break :init mnemonic_map;842 break :init mnemonic_map;
847};843};