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
This commit is contained in:
Jimmi Holst Christensen 2022-04-25 19:08:39 +02:00 committed by Andrew Kelley
parent 18f3034629
commit cea310c908
2 changed files with 39 additions and 15 deletions

View File

@ -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;

View File

@ -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);