zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit cea310c9082a985b103953dd84579aa1a6dce6ea (tree)
parent 18f30346291bd2471e07924af161de080935dd60
Author: Jimmi Holst Christensen <jhc@dismail.de>
Date:   Mon, 25 Apr 2022 19:08:39 +0200

Remove usage of inline for from print_targets.cmdTargets

This function was one of the biggest zig functions in a debug build of
the compiler.

  $ bloaty stage3-debug/bin/zig -d symbols --tsv -n 10000000 |
      rg -v '(llvm|clang|std|lld|\(anonymous namespace\))::|\[section ' |
      sort -h -k 3

  ...
  translate_c.ast.renderNode                    86168   86219
  main.buildOutputType                         177959  178004
  InfoTable                                    184832  184870
  AArch64SVEIntrinsicMap                       188544  188596
  print_targets.cmdTargets__anon_4735          319156  319216
  __static_initialization_and_destruction_0()  486666  489582
  MatchTable1                                  621884  621997
  OperandMatchTable                           1139622 1139861
  MatchTable0                                 1899764 1900141

Diffstat:
Mlib/std/meta.zig | 27+++++++++++++++++++++++++++
Msrc/print_targets.zig | 27++++++++++++---------------
2 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/lib/std/meta.zig b/lib/std/meta.zig @@ -568,6 +568,33 @@ test "std.meta.fieldNames" { try testing.expectEqualSlices(u8, u1names[1], "b"); } +/// Given an enum or error set type, returns a pointer to an array containing all tags for that +/// enum or error set. +pub fn tags(comptime T: type) *const [fields(T).len]T { + comptime { + const fieldInfos = fields(T); + var res: [fieldInfos.len]T = undefined; + for (fieldInfos) |field, i| { + res[i] = @field(T, field.name); + } + return &res; + } +} + +test "std.meta.tags" { + const E1 = enum { A, B }; + const E2 = error{A}; + + const e1_tags = tags(E1); + const e2_tags = tags(E2); + + try testing.expect(e1_tags.len == 2); + try testing.expectEqual(E1.A, e1_tags[0]); + try testing.expectEqual(E1.B, e1_tags[1]); + try testing.expect(e2_tags.len == 1); + try testing.expectEqual(E2.A, e2_tags[0]); +} + pub fn FieldEnum(comptime T: type) type { const field_infos = fields(T); var enumFields: [field_infos.len]std.builtin.Type.EnumField = undefined; diff --git a/src/print_targets.zig b/src/print_targets.zig @@ -2,6 +2,7 @@ const std = @import("std"); const fs = std.fs; const io = std.io; const mem = std.mem; +const meta = std.meta; const Allocator = mem.Allocator; const Target = std.Target; const target = @import("target.zig"); @@ -35,27 +36,25 @@ pub fn cmdTargets( try jws.objectField("arch"); try jws.beginArray(); - { - inline for (@typeInfo(Target.Cpu.Arch).Enum.fields) |field| { - try jws.arrayElem(); - try jws.emitString(field.name); - } + for (meta.fieldNames(Target.Cpu.Arch)) |field| { + try jws.arrayElem(); + try jws.emitString(field); } try jws.endArray(); try jws.objectField("os"); try jws.beginArray(); - inline for (@typeInfo(Target.Os.Tag).Enum.fields) |field| { + for (meta.fieldNames(Target.Os.Tag)) |field| { try jws.arrayElem(); - try jws.emitString(field.name); + try jws.emitString(field); } try jws.endArray(); try jws.objectField("abi"); try jws.beginArray(); - inline for (@typeInfo(Target.Abi).Enum.fields) |field| { + for (meta.fieldNames(Target.Abi)) |field| { try jws.arrayElem(); - try jws.emitString(field.name); + try jws.emitString(field); } try jws.endArray(); @@ -84,10 +83,9 @@ pub fn cmdTargets( try jws.objectField("cpus"); try jws.beginObject(); - inline for (@typeInfo(Target.Cpu.Arch).Enum.fields) |field| { - try jws.objectField(field.name); + for (meta.tags(Target.Cpu.Arch)) |arch| { + try jws.objectField(@tagName(arch)); try jws.beginObject(); - const arch = @field(Target.Cpu.Arch, field.name); for (arch.allCpuModels()) |model| { try jws.objectField(model.name); try jws.beginArray(); @@ -105,10 +103,9 @@ pub fn cmdTargets( try jws.objectField("cpuFeatures"); try jws.beginObject(); - inline for (@typeInfo(Target.Cpu.Arch).Enum.fields) |field| { - try jws.objectField(field.name); + for (meta.tags(Target.Cpu.Arch)) |arch| { + try jws.objectField(@tagName(arch)); try jws.beginArray(); - const arch = @field(Target.Cpu.Arch, field.name); for (arch.allFeaturesList()) |feature| { try jws.arrayElem(); try jws.emitString(feature.name);