All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
To: igt-dev@lists.freedesktop.org
Subject: [igt-dev] [PATCH i-g-t 2/2] lib/i915/perf: break generated code in separate files
Date: Tue, 10 Mar 2020 18:29:46 +0200	[thread overview]
Message-ID: <20200310162946.2335031-2-lionel.g.landwerlin@intel.com> (raw)
In-Reply-To: <20200310162946.2335031-1-lionel.g.landwerlin@intel.com>

Initially all the generated code was per generation. Eventually we
grouped it into a single file to reuse as much as possible equation
code (this reduce binary size by a factor). So many equations are just
the same from generation to generation.

But this generated file is 200k lines long...

This change puts all the metrics into a single file and then breaks
down the metric sets per generation.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
---
 lib/i915/perf-configs/perf-codegen.py | 311 +++++++++++++++++---------
 lib/i915/perf.c                       |  18 +-
 lib/meson.build                       |  21 +-
 3 files changed, 241 insertions(+), 109 deletions(-)

diff --git a/lib/i915/perf-configs/perf-codegen.py b/lib/i915/perf-configs/perf-codegen.py
index ac3ad683..e001fc84 100755
--- a/lib/i915/perf-configs/perf-codegen.py
+++ b/lib/i915/perf-configs/perf-codegen.py
@@ -252,33 +252,51 @@ def data_type_to_ctype(ret_type):
 
 
 def output_counter_read(gen, set, counter):
+    if counter.read_hash in hashed_funcs:
+        return
+
     c("\n")
     c("/* {0} :: {1} */".format(set.name, counter.get('name')))
 
+    ret_type = counter.get('data_type')
+    ret_ctype = data_type_to_ctype(ret_type)
+    read_eq = counter.get('equation')
+
+    c(ret_ctype)
+    c(counter.read_sym + "(const struct intel_perf *perf,\n")
+    c.indent(len(counter.read_sym) + 1)
+    c("const struct intel_perf_metric_set *metric_set,\n")
+    c("uint64_t *accumulator)\n")
+    c.outdent(len(counter.read_sym) + 1)
+
+    c("{")
+    c.indent(4)
+
+    output_rpn_equation_code(set, counter, read_eq)
+
+    c.outdent(4)
+    c("}")
+
+    hashed_funcs[counter.read_hash] = counter.read_sym
+
+
+def output_counter_read_definition(gen, set, counter):
     if counter.read_hash in hashed_funcs:
-        c("#define %s \\" % counter.read_sym)
-        c.indent(4)
-        c("%s" % hashed_funcs[counter.read_hash])
-        c.outdent(4)
+        h("#define %s \\" % counter.read_sym)
+        h.indent(4)
+        h("%s" % hashed_funcs[counter.read_hash])
+        h.outdent(4)
     else:
         ret_type = counter.get('data_type')
         ret_ctype = data_type_to_ctype(ret_type)
         read_eq = counter.get('equation')
 
-        c("static " + ret_ctype)
-        c(counter.read_sym + "(const struct intel_perf *perf,\n")
-        c.indent(len(counter.read_sym) + 1)
-        c("const struct intel_perf_metric_set *metric_set,\n")
-        c("uint64_t *accumulator)\n")
-        c.outdent(len(counter.read_sym) + 1)
-
-        c("{")
-        c.indent(4)
-
-        output_rpn_equation_code(set, counter, read_eq)
-
-        c.outdent(4)
-        c("}")
+        h(ret_ctype)
+        h(counter.read_sym + "(const struct intel_perf *perf,\n")
+        h.indent(len(counter.read_sym) + 1)
+        h("const struct intel_perf_metric_set *metric_set,\n")
+        h("uint64_t *accumulator);\n")
+        h.outdent(len(counter.read_sym) + 1)
 
         hashed_funcs[counter.read_hash] = counter.read_sym
 
@@ -289,33 +307,57 @@ def output_counter_max(gen, set, counter):
     if not max_eq or max_eq == "100":
         return
 
+    if counter.max_hash in hashed_funcs:
+        return
+
     c("\n")
     c("/* {0} :: {1} */".format(set.name, counter.get('name')))
 
+    ret_type = counter.get('data_type')
+    ret_ctype = data_type_to_ctype(ret_type)
+
+    c(ret_ctype)
+    c(counter.max_sym + "(const struct intel_perf *perf,\n")
+    c.indent(len(counter.max_sym) + 1)
+    c("const struct intel_perf_metric_set *metric_set,\n")
+    c("uint64_t *accumulator)\n")
+    c.outdent(len(counter.max_sym) + 1)
+
+    c("{")
+    c.indent(4)
+
+    output_rpn_equation_code(set, counter, max_eq)
+
+    c.outdent(4)
+    c("}")
+
+    hashed_funcs[counter.max_hash] = counter.max_sym
+
+
+def output_counter_max_definition(gen, set, counter):
+    max_eq = counter.get('max_equation')
+
+    if not max_eq or max_eq == "100":
+        return
+
     if counter.max_hash in hashed_funcs:
-        c("#define %s \\" % counter.max_sym)
-        c.indent(4)
-        c("%s" % hashed_funcs[counter.max_hash])
-        c.outdent(4)
+        h("#define %s \\" % counter.max_sym)
+        h.indent(4)
+        h("%s" % hashed_funcs[counter.max_hash])
+        h.outdent(4)
+        h("\n")
     else:
         ret_type = counter.get('data_type')
         ret_ctype = data_type_to_ctype(ret_type)
 
-        c("static " + ret_ctype)
+        h(ret_ctype)
 
-        c(counter.max_sym + "(const struct intel_perf *perf,\n")
-        c.indent(len(counter.max_sym) + 1)
-        c("const struct intel_perf_metric_set *metric_set,\n")
-        c("uint64_t *accumulator)\n")
-        c.outdent(len(counter.max_sym) + 1)
-
-        c("{")
-        c.indent(4)
-
-        output_rpn_equation_code(set, counter, max_eq)
-
-        c.outdent(4)
-        c("}")
+        h(counter.max_sym + "(const struct intel_perf *perf,")
+        h.indent(len(counter.max_sym) + 1)
+        h("const struct intel_perf_metric_set *metric_set,")
+        h("uint64_t *accumulator);")
+        h.outdent(len(counter.max_sym) + 1)
+        h("\n")
 
         hashed_funcs[counter.max_hash] = counter.max_sym
 
@@ -524,65 +566,13 @@ class Gen:
             self.sets.append(Set(self, xml_set))
 
 
-def main():
-    global c
-    global h
-    global xml_equations
+def generate_equations(args, gens):
+    global hashed_funcs
 
-    parser = argparse.ArgumentParser()
-    parser.add_argument("--header", help="Header file to write")
-    parser.add_argument("--code", help="C file to write")
-    parser.add_argument("xml_files", nargs='+', help="List of xml metrics files to process")
-
-    args = parser.parse_args()
-
-    # Note: either arg may == None
-    h = codegen.Codegen(args.header)
-    c = codegen.Codegen(args.code)
-
-    gens = []
-    for xml_file in args.xml_files:
-        gens.append(Gen(xml_file))
-
-    copyright = textwrap.dedent("""\
-        /* Autogenerated file, DO NOT EDIT manually! generated by {}
-         *
-         * Copyright (c) 2018 Intel Corporation
-         *
-         * Permission is hereby granted, free of charge, to any person obtaining a
-         * copy of this software and associated documentation files (the "Software"),
-         * to deal in the Software without restriction, including without limitation
-         * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-         * and/or sell copies of the Software, and to permit persons to whom the
-         * Software is furnished to do so, subject to the following conditions:
-         *
-         * The above copyright notice and this permission notice (including the next
-         * paragraph) shall be included in all copies or substantial portions of the
-         * Software.
-         *
-         * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-         * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-         * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-         * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-         * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-         * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-         * DEALINGS IN THE SOFTWARE.
-         */
-
-        """).format(os.path.basename(__file__))
-
-    h(copyright)
-    c(copyright)
-    c(textwrap.dedent("""\
-        #include <stddef.h>
-        #include <stdint.h>
-        #include <stdbool.h>
-        #include <assert.h>
-
-        """))
-
-    c("#include \"" + os.path.basename(args.header) + "\"")
+    header_file = os.path.basename(args.header)
+    header_define = header_file.replace('.', '_').upper()
 
+    hashed_funcs = {}
     c(textwrap.dedent("""\
         #include <stdlib.h>
         #include <string.h>
@@ -590,11 +580,12 @@ def main():
         #include <i915_drm.h>
 
         #include "i915/perf.h"
+        #include "%s"
 
         #define MIN(x, y) (((x) < (y)) ? (x) : (y))
         #define MAX(a, b) (((a) > (b)) ? (a) : (b))
 
-        static double
+        double
         percentage_max_callback_float(const struct intel_perf *perf,
                                       const struct intel_perf_metric_set *metric_set,
                                       uint64_t *accumulator)
@@ -602,7 +593,7 @@ def main():
            return 100;
         }
 
-        static uint64_t
+        uint64_t
         percentage_max_callback_uint64(const struct intel_perf *perf,
                                        const struct intel_perf_metric_set *metric_set,
                                        uint64_t *accumulator)
@@ -610,7 +601,7 @@ def main():
            return 100;
         }
 
-        """))
+        """ % os.path.basename(args.header)))
 
     # Print out all equation functions.
     for gen in gens:
@@ -619,6 +610,60 @@ def main():
                 output_counter_read(gen, set, counter)
                 output_counter_max(gen, set, counter)
 
+    hashed_funcs = {}
+    h(textwrap.dedent("""\
+        #ifndef __%s__
+        #define __%s__
+
+        #include <stddef.h>
+        #include <stdint.h>
+        #include <stdbool.h>
+
+        struct intel_perf;
+        struct intel_perf_metric_set;
+
+        double
+        percentage_max_callback_float(const struct intel_perf *perf,
+                                      const struct intel_perf_metric_set *metric_set,
+                                      uint64_t *accumulator);
+        uint64_t
+        percentage_max_callback_uint64(const struct intel_perf *perf,
+                                       const struct intel_perf_metric_set *metric_set,
+                                       uint64_t *accumulator);
+
+        """ % (header_define, header_define)))
+
+    # Print out all equation functions.
+    for gen in gens:
+        for set in gen.sets:
+            for counter in set.counters:
+                output_counter_read_definition(gen, set, counter)
+                output_counter_max_definition(gen, set, counter)
+
+    h(textwrap.dedent("""\
+
+        #endif /* __%s__ */
+        """ % header_define))
+
+
+def generate_metric_sets(args, gens):
+    header_file = os.path.basename(args.header)
+    header_define = header_file.replace('.', '_').upper()
+
+    c(textwrap.dedent("""\
+        #include <stddef.h>
+        #include <stdint.h>
+        #include <stdlib.h>
+        #include <stdbool.h>
+        #include <assert.h>
+
+        #include "i915_drm.h"
+
+        """))
+
+    c("#include \"{0}\"".format(os.path.basename(args.header)))
+    c("#include \"{0}\"".format(os.path.basename(args.equation_include)))
+
     # Print out all set registration functions for each set in each
     # generation.
     for gen in gens:
@@ -679,15 +724,12 @@ def main():
             c("}\n")
 
     h(textwrap.dedent("""\
-        #pragma once
+        #ifndef %s
+        #define %s
 
         #include "i915/perf.h"
 
-        #ifdef __cplusplus
-        extern "C" {
-        #endif
-
-        """))
+        """ % (header_define, header_define)))
 
     # Print out all set registration functions for each generation.
     for gen in gens:
@@ -705,11 +747,68 @@ def main():
         c("}")
 
     h(textwrap.dedent("""\
-        #ifdef __cplusplus
-        } /* extern C */
-        #endif
+        #endif /* %s */
+        """ % header_define))
+
+
+def main():
+    global c
+    global h
+    global xml_equations
+
+    parser = argparse.ArgumentParser()
+    parser.add_argument("--header", help="Header file to write")
+    parser.add_argument("--code", help="C file to write")
+    parser.add_argument("--equations", help="Output equations", action="store_true")
+    parser.add_argument("--metric_sets", help="Output metric sets", action="store_true")
+    parser.add_argument("--equation-include", help="Equation header file")
+    parser.add_argument("xml_files", nargs='+', help="List of xml metrics files to process")
+
+    args = parser.parse_args()
+
+    # Note: either arg may == None
+    h = codegen.Codegen(args.header)
+    c = codegen.Codegen(args.code)
+
+    gens = []
+    for xml_file in args.xml_files:
+        gens.append(Gen(xml_file))
+
+    copyright = textwrap.dedent("""\
+        /* Autogenerated file, DO NOT EDIT manually! generated by {}
+         *
+         * Copyright (c) 2018 Intel Corporation
+         *
+         * Permission is hereby granted, free of charge, to any person obtaining a
+         * copy of this software and associated documentation files (the "Software"),
+         * to deal in the Software without restriction, including without limitation
+         * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+         * and/or sell copies of the Software, and to permit persons to whom the
+         * Software is furnished to do so, subject to the following conditions:
+         *
+         * The above copyright notice and this permission notice (including the next
+         * paragraph) shall be included in all copies or substantial portions of the
+         * Software.
+         *
+         * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+         * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+         * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+         * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+         * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+         * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+         * DEALINGS IN THE SOFTWARE.
+         */
+
+        """).format(os.path.basename(__file__))
+
+    h(copyright)
+    c(copyright)
+
+    if args.equations:
+        generate_equations(args, gens)
+    if args.metric_sets:
+        generate_metric_sets(args, gens)
 
-        """))
 
 
 if __name__ == '__main__':
diff --git a/lib/i915/perf.c b/lib/i915/perf.c
index babfe633..8d3e188a 100644
--- a/lib/i915/perf.c
+++ b/lib/i915/perf.c
@@ -37,7 +37,23 @@
 
 #include "intel_chipset.h"
 #include "perf.h"
-#include "i915_perf_metrics.h"
+
+#include "i915_perf_metrics_hsw.h"
+#include "i915_perf_metrics_bdw.h"
+#include "i915_perf_metrics_chv.h"
+#include "i915_perf_metrics_sklgt2.h"
+#include "i915_perf_metrics_sklgt3.h"
+#include "i915_perf_metrics_sklgt4.h"
+#include "i915_perf_metrics_kblgt2.h"
+#include "i915_perf_metrics_kblgt3.h"
+#include "i915_perf_metrics_cflgt2.h"
+#include "i915_perf_metrics_cflgt3.h"
+#include "i915_perf_metrics_bxt.h"
+#include "i915_perf_metrics_glk.h"
+#include "i915_perf_metrics_cnl.h"
+#include "i915_perf_metrics_icl.h"
+#include "i915_perf_metrics_ehl.h"
+#include "i915_perf_metrics_tgl.h"
 
 static int
 perf_ioctl(int fd, unsigned long request, void *arg)
diff --git a/lib/meson.build b/lib/meson.build
index 8112bec4..f3649615 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -195,16 +195,33 @@ foreach hw : i915_perf_hardware
 endforeach
 
 i915_perf_files += custom_target(
-  'i915-perf-metrics',
+  'i915-perf-equations',
   input : i915_xml_files,
-  output : [ 'i915_perf_metrics.c', 'i915_perf_metrics.h' ],
+  output : [ 'i915_perf_equations.c', 'i915_perf_equations.h' ],
   command : [
     find_program('i915/perf-configs/perf-codegen.py'),
     '--code', '@OUTPUT0@',
     '--header', '@OUTPUT1@',
+    '--equations',
     '@INPUT@',
   ])
 
+foreach hw : i915_perf_hardware
+  i915_perf_files += custom_target(
+    'i915-perf-metrics-@0@'.format(hw),
+    input : 'i915/perf-configs/oa-@0@.xml'.format(hw),
+    output : [ 'i915_perf_metrics_@0@.c'.format(hw),
+               'i915_perf_metrics_@0@.h'.format(hw), ],
+    command : [
+      find_program('i915/perf-configs/perf-codegen.py'),
+      '--code', '@OUTPUT0@',
+      '--header', '@OUTPUT1@',
+      '--metric_sets',
+      '--equation-include', 'i915_perf_equations.h',
+      '@INPUT@',
+    ])
+endforeach
+
 lib_igt_i915_perf_build = shared_library(
   'i915_perf',
   i915_perf_files,
-- 
2.25.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

  reply	other threads:[~2020-03-10 16:30 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-10 16:29 [igt-dev] [PATCH i-g-t 1/2] lib/i915/perf: remove generation code for mathml render Lionel Landwerlin
2020-03-10 16:29 ` Lionel Landwerlin [this message]
2020-03-10 16:31   ` [igt-dev] [PATCH i-g-t 2/2] lib/i915/perf: break generated code in separate files Lionel Landwerlin
2020-03-10 16:40 ` [igt-dev] ✗ GitLab.Pipeline: warning for series starting with [i-g-t,1/2] lib/i915/perf: remove generation code for mathml render Patchwork
2020-03-10 17:00 ` [igt-dev] ✓ Fi.CI.BAT: success " Patchwork
2020-03-10 21:53 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200310162946.2335031-2-lionel.g.landwerlin@intel.com \
    --to=lionel.g.landwerlin@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.