<soum...@nvidia.com> writes:
> From: Soumya AR <soum...@nvidia.com>
>
> This commit introduces a Python maintenance script that generates C++ code
> for parsing and serializing AArch64 JSON tuning parameters based on the
> schema defined in aarch64-json-schema.h.
>
> The script generates two include files:
>   - aarch64-json-tunings-parser-generated.inc
>   - aarch64-json-tunings-printer-generated.inc
>
> These generated files are committed as regular source files and included by
> aarch64-json-tunings-parser.cc and aarch64-json-tunings-printer.cc 
> respectively.
>
> The script should be run manually whenever the JSON schema is modified.
>
> Signed-off-by: Soumya AR <soum...@nvidia.com>
>
> gcc/ChangeLog:
>
>       * config/aarch64/aarch64-json-tunings-parser.cc: Include
>       aarch64-json-tunings-parser-generated.inc.
>       * config/aarch64/aarch64-json-tunings-printer.cc: Include
>       aarch64-json-tunings-printer-generated.inc.
>       * config/aarch64/aarch64-generate-json-tuning-routines.py: New
>       maintenance script to generate JSON parser/printer routines.
>       * config/aarch64/aarch64-json-tunings-parser-generated.inc: New
>       file.
>       * config/aarch64/aarch64-json-tunings-printer-generated.inc: New
>       file.
>       * config/aarch64/t-aarch64: Update dependencies to reference .inc
>       files.

Thanks, this looks really nice.

> ---
>  .../aarch64-generate-json-tuning-routines.py  | 370 +++++++++++++
>  .../aarch64-json-tunings-parser-generated.inc | 337 ++++++++++++
>  .../aarch64/aarch64-json-tunings-parser.cc    | 360 +------------
>  ...aarch64-json-tunings-printer-generated.inc | 421 +++++++++++++++
>  .../aarch64/aarch64-json-tunings-printer.cc   | 509 +-----------------
>  gcc/config/aarch64/t-aarch64                  |   2 +
>  6 files changed, 1134 insertions(+), 865 deletions(-)
>  create mode 100644 
> gcc/config/aarch64/aarch64-generate-json-tuning-routines.py
>  create mode 100644 
> gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc
>  create mode 100644 
> gcc/config/aarch64/aarch64-json-tunings-printer-generated.inc
>
> diff --git a/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py 
> b/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py
> new file mode 100644
> index 00000000000..393394fcd4e
> --- /dev/null
> +++ b/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py
> @@ -0,0 +1,370 @@
> +#!/usr/bin/env python3
> +
> +# Script to autogenerate the parsing and serialization routines for the
> +# aarch64 JSON tuning parameters.
> +#
> +# Copyright The GNU Toolchain Authors.
> +#
> +# This file is part of GCC.
> +#
> +# GCC is free software; you can redistribute it and/or modify it under
> +# the terms of the GNU General Public License as published by the Free
> +# Software Foundation; either version 3, or (at your option) any later
> +# version.
> +#
> +# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +# WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +# for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with GCC; see the file COPYING3.  If not see
> +# <http://www.gnu.org/licenses/>.
> +
> +DESCRIPTION = """
> +Maintenance script to regenerate aarch64-json-tunings-*-generated.inc files
> +from the JSON schema in aarch64-json-schema.h.
> +
> +This script should be run manually whenever aarch64-json-schema.h is 
> modified.
> +
> +Usage (from gcc/config/aarch64/ directory):
> +  python3 aarch64-generate-json-tuning-routines.py
> +
> +Generates:
> +  aarch64-json-tunings-parser-generated.inc
> +  aarch64-json-tunings-printer-generated.inc

I was going to say that we should allow the script to be run from
the toplevel, rather than directly from gcc/config/aarch64, but it
already does.  I think it'd be worth making that more explicit in
the usage instructions.

> +"""
> +
> +import json
> +import re
> +import os
> +from typing import Dict, Any, List, Tuple
> +
> +"""Extract the JSON schema string from the header file."""
> +def extract_schema_from_header(file_path: str) -> str:
> +    with open(file_path, "r") as f:
> +        content = f.read()
> +
> +    # Find the schema_json variable content between R"json( and )json"
> +    pattern = r'static const char \*schema_json = R"json\((.*?)\)json";'
> +    match = re.search(pattern, content, re.DOTALL)
> +
> +    if not match:
> +        raise ValueError("Could not find schema_json in header file")
> +
> +    return match.group(1).strip()
> +
> +"""Return the appropriate macro based on operation (PARSE/SERIALIZE) and 
> field type."""
> +def get_macro(operation: str, field_type: str) -> str:
> +    type_map = {
> +        "int": "INTEGER",
> +        "uint": "INTEGER",
> +        "boolean": "BOOLEAN",
> +        "string": "STRING",
> +        "enum": "ENUM",
> +    }
> +    if field_type not in type_map:
> +        raise ValueError(f"Unknown field type: {field_type}")
> +    return f"{operation}_{type_map[field_type]}_FIELD"
> +
> +def get_parse_macro(field_type: str) -> str:
> +    return get_macro("PARSE", field_type)
> +
> +def get_serialize_macro(field_type: str) -> str:
> +    return get_macro("SERIALIZE", field_type)

These two functions aren't used.

> +
> +"""Generate parsing or serialization code for a single field."""
> +def generate_field_code(
> +    operation: str,
> +    key: str,
> +    value: Any,
> +    struct_name: str,
> +    current_path: List[str],
> +    function_map: Dict[str, str],
> +    obj_name: str = "jo",
> +    indent: str = "  ",
> +) -> List[str]:
> +    lines = []
> +
> +    if isinstance(value, str):
> +        # Simple field type
> +        macro = get_macro(operation.upper(), value)
> +        if value == "enum":
> +            enum_mapping = f"{key}_mappings"
> +            lines.append(
> +                f'{indent}{macro} ({obj_name}, "{key}", {struct_name}.{key}, 
> {enum_mapping});'
> +            )
> +        else:
> +            lines.append(f'{indent}{macro} ({obj_name}, "{key}", 
> {struct_name}.{key});')
> +
> +    elif isinstance(value, dict):
> +        # Nested object - find function name based on current context + key
> +        child_path = current_path + [key]
> +        child_path_key = "_".join(child_path)
> +        func_name = function_map.get(child_path_key, 
> f"{operation.lower()}_{key}")
> +        macro_name = f"{operation.upper()}_OBJECT"
> +        lines.append(
> +            f'{indent}{macro_name} ({obj_name}, "{key}", 
> {struct_name}.{key}, {func_name});'
> +        )
> +
> +    elif isinstance(value, list) and len(value) > 0:
> +        if isinstance(value[0], dict):
> +            element_key = key.rstrip("s") if key.endswith("s") else 
> f"{key}_element"

How bad would it be if we didn't have this special case?  Not everything
ending in "s" is a plural, and not all plurals can be made singular by
dropping "s".

> +            element_path = current_path + [element_key]
> +            element_path_key = "_".join(element_path)
> +            func_name = function_map.get(
> +                element_path_key, f"{operation.lower()}_{element_key}"
> +            )
> +            macro_name = f"{operation.upper()}_ARRAY_FIELD"
> +
> +            if operation.lower() == "serialize":
> +                # Serialization needs an extra parameter for array count
> +                lines.append(
> +                    f'{indent}{macro_name} ({obj_name}, "{key}", 
> {struct_name}.{key}, 2, {func_name});'

It's an interesting quirk that all arrays currently have 2 elements.
What would we do if that wasn't the case in future?

Could the serialisation macro use ARRAY_SIZE instead?

> +                )
> +            else:
> +                lines.append(
> +                    f'{indent}{macro_name} ({obj_name}, "{key}", 
> {struct_name}.{key}, {func_name});'
> +                )

It might be good to close off the outer two ifs with elses that raise
a ValueError, so that we don't silently drop things.

> +
> +    return lines
> +
> +"""Generate parsing code for a single field."""
> +def generate_field_parsing(
> +    key: str,
> +    value: Any,
> +    struct_name: str,
> +    current_path: List[str],
> +    function_map: Dict[str, str],
> +    indent: str = "  ",
> +) -> List[str]:
> +    return generate_field_code(
> +        "parse", key, value, struct_name, current_path, function_map, "jo", 
> indent
> +    )
> +
> +"""Generate serialization code for a single field."""
> +def generate_field_serialization(
> +    key: str,
> +    value: Any,
> +    struct_name: str,
> +    obj_name: str,
> +    current_path: List[str],
> +    function_map: Dict[str, str],
> +    indent: str = "  ",
> +) -> List[str]:
> +    return generate_field_code(
> +        "serialize",
> +        key,
> +        value,
> +        struct_name,
> +        current_path,
> +        function_map,
> +        obj_name,
> +        indent,
> +    )
> +
> +"""Generate a complete parse or serialize function for a schema object."""
> +def generate_function(
> +    operation: str,
> +    full_name: str,
> +    local_name: str,
> +    schema: Dict[str, Any],
> +    current_path: List[str],
> +    function_map: Dict[str, str],
> +) -> List[str]:
> +    lines = []
> +    lines.append("template <typename T>")
> +
> +    if operation.lower() == "parse":
> +        lines.append("static void")
> +        lines.append(f"parse_{full_name} (const json::object *jo, T 
> &{local_name})")
> +        lines.append("{")
> +
> +        for key, value in schema.items():
> +            field_lines = generate_field_parsing(
> +                key, value, local_name, current_path, function_map
> +            )
> +            lines.extend(field_lines)
> +
> +    elif operation.lower() == "serialize":
> +        lines.append("static std::unique_ptr<json::object>")
> +        lines.append(f"serialize_{full_name} (const T &{local_name})")
> +        lines.append("{")
> +        lines.append(f"  auto {local_name}_obj = 
> std::make_unique<json::object> ();")
> +        lines.append("")
> +
> +        for key, value in schema.items():
> +            field_lines = generate_field_serialization(
> +                key, value, local_name, f"{local_name}_obj", current_path, 
> function_map
> +            )
> +            lines.extend(field_lines)
> +
> +        lines.append("")
> +        lines.append(f"  return {local_name}_obj;")
> +
> +    lines.append("}")
> +    lines.append("")

I suppose this is personal preference, but it seemed suprising to add
a blank line even for the final function.  It looks like this is instead
offsetting the use of "\n".join(...) later, but perhaps it would be more
obvious to add "\n" there instead.  An alternative would be to use
something like writelines([x + "\n" for x in ...]).

> +
> +    return lines
> +
> +
> +"""Collect all object schemas with their full paths. This is necessary for
> +generating names for the routines with the correct hierarchal path to ensure
> +that identical keys in different structures are not given the same name.
> +For example:
> +vec_costs.issue_info.sve maps to <parse/serialize>_vec_costs_issue_info_sve
> +vec_costs.sve maps to <parse/serialize>_vec_costs_sve.
> +"""
> +def collect_all_objects_with_paths(
> +    schema: Dict[str, Any], path: List[str] = []
> +) -> Dict[str, Tuple[List[str], Dict[str, Any]]]:
> +    objects = {}
> +
> +    for key, value in schema.items():
> +        current_path = path + [key]
> +
> +        if isinstance(value, dict):
> +            path_key = "_".join(current_path)
> +            objects[path_key] = (current_path, value)
> +            nested = collect_all_objects_with_paths(value, current_path)
> +            objects.update(nested)
> +
> +        elif isinstance(value, list) and len(value) > 0 and 
> isinstance(value[0], dict):
> +            element_key = key.rstrip("s") if key.endswith("s") else 
> f"{key}_element"
> +            element_path = current_path[:-1] + [element_key]
> +            element_path_key = "_".join(element_path)
> +            objects[element_path_key] = (element_path, value[0])
> +            nested = collect_all_objects_with_paths(value[0], element_path)
> +            objects.update(nested)
> +
> +    return objects
> +
> +
> +"""Calculate dependency depth of an object schema. 0 indicates no
> +dependencies, ie. the object has only primitive types."""
> +def get_dependency_depth(obj_schema: Dict[str, Any]) -> int:
> +    max_depth = 0
> +    for value in obj_schema.values():
> +        if isinstance(value, dict):
> +            max_depth = max(max_depth, 1 + get_dependency_depth(value))
> +        elif isinstance(value, list) and len(value) > 0 and 
> isinstance(value[0], dict):
> +            max_depth = max(max_depth, 1 + get_dependency_depth(value[0]))
> +    return max_depth
> +
> +
> +def generate_all_functions(schema_file: str, operation: str) -> str:
> +    schema_str = extract_schema_from_header(schema_file)
> +    schema = json.loads(schema_str)
> +    tune_params_schema = schema.get("tune_params", {})
> +
> +    all_objects_with_paths = 
> collect_all_objects_with_paths(tune_params_schema)
> +
> +    function_map = {}
> +    for path_key, (path, obj_schema) in all_objects_with_paths.items():
> +        filtered_path = [p for p in path if p != "tune_params"]
> +        if filtered_path:
> +            full_name = "_".join(filtered_path)
> +            function_map[path_key] = f"{operation}_{full_name}"
> +        else:
> +            function_map[path_key] = f"{operation}_{path_key}"

Are the 6 lines above equivalent to:

    if len(path) > 1:
        full_name = "_".join(path[1:])
        function_map[path_key] = f"{operation}_{full_name}"
    else:
        function_map[path_key] = f"{operation}_{path_key}"

?  If so, that might be easier to follow, since it emphasises that
we're structurally ignoring path[0] for all cases.  It looked at first
like the filtering might remove something other than the first element.

> +
> +    """ Structures can have nested structures that may not have been defined 
> yet.
> +    Therefore, we need to sort the objects by dependency depth and define 
> +    functions for the inner structures first."""
> +    sorted_objects = sorted(
> +        all_objects_with_paths.items(), key=lambda x: 
> get_dependency_depth(x[1][1])
> +    )
> +
> +    generated_functions = []
> +
> +    # Generate functions
> +    for path_key, (path, obj_schema) in sorted_objects:
> +        filtered_path = [p for p in path if p != "tune_params"]
> +        if filtered_path:
> +            full_name = "_".join(filtered_path)
> +            local_name = filtered_path[-1]
> +            current_path = filtered_path
> +        else:
> +            full_name = path_key
> +            local_name = path_key
> +            current_path = []

Same idea here with:

    current_path = path[1:]
    if current_path:
        full_name = "_".join(current_path)
        local_name = current_path[-1]
    else:
        full_name = path_key
        local_name = path_key

Thanks,
Richard

> +
> +        function_lines = generate_function(
> +            operation, full_name, local_name, obj_schema, current_path, 
> function_map
> +        )
> +        generated_functions.extend(function_lines)
> +
> +    main_function = generate_function(
> +        operation, "tunings", "tunings", tune_params_schema, [], function_map
> +    )
> +    generated_functions.extend(main_function)
> +
> +    return "\n".join(generated_functions)
> +
> +"""Write the generated code to a new include file."""
> +def write_generated_include_file(
> +    output_file_path: str, generated_code: str, operation: str
> +) -> None:
> +    header_comment = f"""/* This file is auto-generated by 
> aarch64-generate-json-tuning-routines.py.  */
> +/* Copyright The GNU Toolchain Authors.
> +   This file is part of GCC.
> +
> +   GCC is free software; you can redistribute it and/or modify it under
> +   the terms of the GNU General Public License as published by the Free
> +   Software Foundation; either version 3, or (at your option) any later
> +   version.
> +
> +   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +   WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +   for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with GCC; see the file COPYING3.  If not see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* This file contains the auto-generated {operation} functions for JSON 
> tuning parameters.  */
> +
> +"""
> +
> +    try:
> +        with open(output_file_path, "w") as f:
> +            f.write(header_comment)
> +            f.write(generated_code)
> +        print(f"Successfully generated {output_file_path}")
> +    except Exception as e:
> +        print(f"Error writing to {output_file_path}: {e}")
> +
> +def main():
> +    try:
> +        script_dir = os.path.dirname(os.path.abspath(__file__))
> +
> +        schema_file = os.path.join(script_dir, "aarch64-json-schema.h")
> +        parser_inc_file = os.path.join(
> +            script_dir, "aarch64-json-tunings-parser-generated.inc"
> +        )
> +        printer_inc_file = os.path.join(
> +            script_dir, "aarch64-json-tunings-printer-generated.inc"
> +        )
> +
> +        # Generate parser functions
> +        parser_generated_code = generate_all_functions(schema_file, "parse")
> +        write_generated_include_file(parser_inc_file, parser_generated_code, 
> "parser")
> +
> +        # Generate serializer functions
> +        serializer_generated_code = generate_all_functions(schema_file, 
> "serialize")
> +        write_generated_include_file(
> +            printer_inc_file, serializer_generated_code, "serializer"
> +        )
> +
> +        print("Code generation completed successfully!")
> +        print(f"Generated files in: {script_dir}")
> +
> +    except Exception as e:
> +        print(f"Error: {e}")
> +        return 1
> +
> +    return 0
> +
> +if __name__ == "__main__":
> +    exit(main())
> diff --git a/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc 
> b/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc
> new file mode 100644
> index 00000000000..da96e9b8ded
> --- /dev/null
> +++ b/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc
> @@ -0,0 +1,337 @@
> +/* This file is auto-generated by aarch64-generate-json-tuning-routines.py.  
> */
> +/* Copyright The GNU Toolchain Authors.
> +   This file is part of GCC.
> +
> +   GCC is free software; you can redistribute it and/or modify it under
> +   the terms of the GNU General Public License as published by the Free
> +   Software Foundation; either version 3, or (at your option) any later
> +   version.
> +
> +   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +   WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +   for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with GCC; see the file COPYING3.  If not see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* This file contains the auto-generated parser functions for JSON tuning 
> parameters.  */
> +
> +template <typename T>
> +static void
> +parse_insn_extra_cost_alu (const json::object *jo, T &alu)
> +{
> +  PARSE_INTEGER_FIELD (jo, "arith", alu.arith);
> +  PARSE_INTEGER_FIELD (jo, "logical", alu.logical);
> +  PARSE_INTEGER_FIELD (jo, "shift", alu.shift);
> +  PARSE_INTEGER_FIELD (jo, "shift_reg", alu.shift_reg);
> +  PARSE_INTEGER_FIELD (jo, "arith_shift", alu.arith_shift);
> +  PARSE_INTEGER_FIELD (jo, "arith_shift_reg", alu.arith_shift_reg);
> +  PARSE_INTEGER_FIELD (jo, "log_shift", alu.log_shift);
> +  PARSE_INTEGER_FIELD (jo, "log_shift_reg", alu.log_shift_reg);
> +  PARSE_INTEGER_FIELD (jo, "extend", alu.extend);
> +  PARSE_INTEGER_FIELD (jo, "extend_arith", alu.extend_arith);
> +  PARSE_INTEGER_FIELD (jo, "bfi", alu.bfi);
> +  PARSE_INTEGER_FIELD (jo, "bfx", alu.bfx);
> +  PARSE_INTEGER_FIELD (jo, "clz", alu.clz);
> +  PARSE_INTEGER_FIELD (jo, "rev", alu.rev);
> +  PARSE_INTEGER_FIELD (jo, "non_exec", alu.non_exec);
> +  PARSE_BOOLEAN_FIELD (jo, "non_exec_costs_exec", alu.non_exec_costs_exec);
> +}
> +
> +template <typename T>
> +static void
> +parse_insn_extra_cost_mult_element (const json::object *jo, T &mult_element)
> +{
> +  PARSE_INTEGER_FIELD (jo, "simple", mult_element.simple);
> +  PARSE_INTEGER_FIELD (jo, "flag_setting", mult_element.flag_setting);
> +  PARSE_INTEGER_FIELD (jo, "extend", mult_element.extend);
> +  PARSE_INTEGER_FIELD (jo, "add", mult_element.add);
> +  PARSE_INTEGER_FIELD (jo, "extend_add", mult_element.extend_add);
> +  PARSE_INTEGER_FIELD (jo, "idiv", mult_element.idiv);
> +}
> +
> +template <typename T>
> +static void
> +parse_insn_extra_cost_ldst (const json::object *jo, T &ldst)
> +{
> +  PARSE_INTEGER_FIELD (jo, "load", ldst.load);
> +  PARSE_INTEGER_FIELD (jo, "load_sign_extend", ldst.load_sign_extend);
> +  PARSE_INTEGER_FIELD (jo, "ldrd", ldst.ldrd);
> +  PARSE_INTEGER_FIELD (jo, "ldm_1st", ldst.ldm_1st);
> +  PARSE_INTEGER_FIELD (jo, "ldm_regs_per_insn_1st", 
> ldst.ldm_regs_per_insn_1st);
> +  PARSE_INTEGER_FIELD (jo, "ldm_regs_per_insn_subsequent", 
> ldst.ldm_regs_per_insn_subsequent);
> +  PARSE_INTEGER_FIELD (jo, "loadf", ldst.loadf);
> +  PARSE_INTEGER_FIELD (jo, "loadd", ldst.loadd);
> +  PARSE_INTEGER_FIELD (jo, "load_unaligned", ldst.load_unaligned);
> +  PARSE_INTEGER_FIELD (jo, "store", ldst.store);
> +  PARSE_INTEGER_FIELD (jo, "strd", ldst.strd);
> +  PARSE_INTEGER_FIELD (jo, "stm_1st", ldst.stm_1st);
> +  PARSE_INTEGER_FIELD (jo, "stm_regs_per_insn_1st", 
> ldst.stm_regs_per_insn_1st);
> +  PARSE_INTEGER_FIELD (jo, "stm_regs_per_insn_subsequent", 
> ldst.stm_regs_per_insn_subsequent);
> +  PARSE_INTEGER_FIELD (jo, "storef", ldst.storef);
> +  PARSE_INTEGER_FIELD (jo, "stored", ldst.stored);
> +  PARSE_INTEGER_FIELD (jo, "store_unaligned", ldst.store_unaligned);
> +  PARSE_INTEGER_FIELD (jo, "loadv", ldst.loadv);
> +  PARSE_INTEGER_FIELD (jo, "storev", ldst.storev);
> +}
> +
> +template <typename T>
> +static void
> +parse_insn_extra_cost_fp_element (const json::object *jo, T &fp_element)
> +{
> +  PARSE_INTEGER_FIELD (jo, "div", fp_element.div);
> +  PARSE_INTEGER_FIELD (jo, "mult", fp_element.mult);
> +  PARSE_INTEGER_FIELD (jo, "mult_addsub", fp_element.mult_addsub);
> +  PARSE_INTEGER_FIELD (jo, "fma", fp_element.fma);
> +  PARSE_INTEGER_FIELD (jo, "addsub", fp_element.addsub);
> +  PARSE_INTEGER_FIELD (jo, "fpconst", fp_element.fpconst);
> +  PARSE_INTEGER_FIELD (jo, "neg", fp_element.neg);
> +  PARSE_INTEGER_FIELD (jo, "compare", fp_element.compare);
> +  PARSE_INTEGER_FIELD (jo, "widen", fp_element.widen);
> +  PARSE_INTEGER_FIELD (jo, "narrow", fp_element.narrow);
> +  PARSE_INTEGER_FIELD (jo, "toint", fp_element.toint);
> +  PARSE_INTEGER_FIELD (jo, "fromint", fp_element.fromint);
> +  PARSE_INTEGER_FIELD (jo, "roundint", fp_element.roundint);
> +}
> +
> +template <typename T>
> +static void
> +parse_insn_extra_cost_vect (const json::object *jo, T &vect)
> +{
> +  PARSE_INTEGER_FIELD (jo, "alu", vect.alu);
> +  PARSE_INTEGER_FIELD (jo, "mult", vect.mult);
> +  PARSE_INTEGER_FIELD (jo, "movi", vect.movi);
> +  PARSE_INTEGER_FIELD (jo, "dup", vect.dup);
> +  PARSE_INTEGER_FIELD (jo, "extract", vect.extract);
> +}
> +
> +template <typename T>
> +static void
> +parse_addr_cost_addr_scale_costs (const json::object *jo, T 
> &addr_scale_costs)
> +{
> +  PARSE_INTEGER_FIELD (jo, "hi", addr_scale_costs.hi);
> +  PARSE_INTEGER_FIELD (jo, "si", addr_scale_costs.si);
> +  PARSE_INTEGER_FIELD (jo, "di", addr_scale_costs.di);
> +  PARSE_INTEGER_FIELD (jo, "ti", addr_scale_costs.ti);
> +}
> +
> +template <typename T>
> +static void
> +parse_regmove_cost (const json::object *jo, T &regmove_cost)
> +{
> +  PARSE_INTEGER_FIELD (jo, "GP2GP", regmove_cost.GP2GP);
> +  PARSE_INTEGER_FIELD (jo, "GP2FP", regmove_cost.GP2FP);
> +  PARSE_INTEGER_FIELD (jo, "FP2GP", regmove_cost.FP2GP);
> +  PARSE_INTEGER_FIELD (jo, "FP2FP", regmove_cost.FP2FP);
> +}
> +
> +template <typename T>
> +static void
> +parse_vec_costs_advsimd (const json::object *jo, T &advsimd)
> +{
> +  PARSE_INTEGER_FIELD (jo, "int_stmt_cost", advsimd.int_stmt_cost);
> +  PARSE_INTEGER_FIELD (jo, "fp_stmt_cost", advsimd.fp_stmt_cost);
> +  PARSE_INTEGER_FIELD (jo, "ld2_st2_permute_cost", 
> advsimd.ld2_st2_permute_cost);
> +  PARSE_INTEGER_FIELD (jo, "ld3_st3_permute_cost", 
> advsimd.ld3_st3_permute_cost);
> +  PARSE_INTEGER_FIELD (jo, "ld4_st4_permute_cost", 
> advsimd.ld4_st4_permute_cost);
> +  PARSE_INTEGER_FIELD (jo, "permute_cost", advsimd.permute_cost);
> +  PARSE_INTEGER_FIELD (jo, "reduc_i8_cost", advsimd.reduc_i8_cost);
> +  PARSE_INTEGER_FIELD (jo, "reduc_i16_cost", advsimd.reduc_i16_cost);
> +  PARSE_INTEGER_FIELD (jo, "reduc_i32_cost", advsimd.reduc_i32_cost);
> +  PARSE_INTEGER_FIELD (jo, "reduc_i64_cost", advsimd.reduc_i64_cost);
> +  PARSE_INTEGER_FIELD (jo, "reduc_f16_cost", advsimd.reduc_f16_cost);
> +  PARSE_INTEGER_FIELD (jo, "reduc_f32_cost", advsimd.reduc_f32_cost);
> +  PARSE_INTEGER_FIELD (jo, "reduc_f64_cost", advsimd.reduc_f64_cost);
> +  PARSE_INTEGER_FIELD (jo, "store_elt_extra_cost", 
> advsimd.store_elt_extra_cost);
> +  PARSE_INTEGER_FIELD (jo, "vec_to_scalar_cost", advsimd.vec_to_scalar_cost);
> +  PARSE_INTEGER_FIELD (jo, "scalar_to_vec_cost", advsimd.scalar_to_vec_cost);
> +  PARSE_INTEGER_FIELD (jo, "align_load_cost", advsimd.align_load_cost);
> +  PARSE_INTEGER_FIELD (jo, "unalign_load_cost", advsimd.unalign_load_cost);
> +  PARSE_INTEGER_FIELD (jo, "unalign_store_cost", advsimd.unalign_store_cost);
> +  PARSE_INTEGER_FIELD (jo, "store_cost", advsimd.store_cost);
> +}
> +
> +template <typename T>
> +static void
> +parse_vec_costs_sve (const json::object *jo, T &sve)
> +{
> +  PARSE_INTEGER_FIELD (jo, "clast_cost", sve.clast_cost);
> +  PARSE_INTEGER_FIELD (jo, "fadda_f16_cost", sve.fadda_f16_cost);
> +  PARSE_INTEGER_FIELD (jo, "fadda_f32_cost", sve.fadda_f32_cost);
> +  PARSE_INTEGER_FIELD (jo, "fadda_f64_cost", sve.fadda_f64_cost);
> +  PARSE_INTEGER_FIELD (jo, "gather_load_x32_cost", sve.gather_load_x32_cost);
> +  PARSE_INTEGER_FIELD (jo, "gather_load_x64_cost", sve.gather_load_x64_cost);
> +  PARSE_INTEGER_FIELD (jo, "gather_load_x32_init_cost", 
> sve.gather_load_x32_init_cost);
> +  PARSE_INTEGER_FIELD (jo, "gather_load_x64_init_cost", 
> sve.gather_load_x64_init_cost);
> +  PARSE_INTEGER_FIELD (jo, "scatter_store_elt_cost", 
> sve.scatter_store_elt_cost);
> +}
> +
> +template <typename T>
> +static void
> +parse_vec_costs_issue_info_scalar (const json::object *jo, T &scalar)
> +{
> +  PARSE_INTEGER_FIELD (jo, "loads_stores_per_cycle", 
> scalar.loads_stores_per_cycle);
> +  PARSE_INTEGER_FIELD (jo, "stores_per_cycle", scalar.stores_per_cycle);
> +  PARSE_INTEGER_FIELD (jo, "general_ops_per_cycle", 
> scalar.general_ops_per_cycle);
> +  PARSE_INTEGER_FIELD (jo, "fp_simd_load_general_ops", 
> scalar.fp_simd_load_general_ops);
> +  PARSE_INTEGER_FIELD (jo, "fp_simd_store_general_ops", 
> scalar.fp_simd_store_general_ops);
> +}
> +
> +template <typename T>
> +static void
> +parse_vec_costs_issue_info_advsimd (const json::object *jo, T &advsimd)
> +{
> +  PARSE_INTEGER_FIELD (jo, "loads_stores_per_cycle", 
> advsimd.loads_stores_per_cycle);
> +  PARSE_INTEGER_FIELD (jo, "stores_per_cycle", advsimd.stores_per_cycle);
> +  PARSE_INTEGER_FIELD (jo, "general_ops_per_cycle", 
> advsimd.general_ops_per_cycle);
> +  PARSE_INTEGER_FIELD (jo, "fp_simd_load_general_ops", 
> advsimd.fp_simd_load_general_ops);
> +  PARSE_INTEGER_FIELD (jo, "fp_simd_store_general_ops", 
> advsimd.fp_simd_store_general_ops);
> +  PARSE_INTEGER_FIELD (jo, "ld2_st2_general_ops", 
> advsimd.ld2_st2_general_ops);
> +  PARSE_INTEGER_FIELD (jo, "ld3_st3_general_ops", 
> advsimd.ld3_st3_general_ops);
> +  PARSE_INTEGER_FIELD (jo, "ld4_st4_general_ops", 
> advsimd.ld4_st4_general_ops);
> +}
> +
> +template <typename T>
> +static void
> +parse_vec_costs_issue_info_sve (const json::object *jo, T &sve)
> +{
> +  PARSE_INTEGER_FIELD (jo, "loads_stores_per_cycle", 
> sve.loads_stores_per_cycle);
> +  PARSE_INTEGER_FIELD (jo, "stores_per_cycle", sve.stores_per_cycle);
> +  PARSE_INTEGER_FIELD (jo, "general_ops_per_cycle", 
> sve.general_ops_per_cycle);
> +  PARSE_INTEGER_FIELD (jo, "fp_simd_load_general_ops", 
> sve.fp_simd_load_general_ops);
> +  PARSE_INTEGER_FIELD (jo, "fp_simd_store_general_ops", 
> sve.fp_simd_store_general_ops);
> +  PARSE_INTEGER_FIELD (jo, "ld2_st2_general_ops", sve.ld2_st2_general_ops);
> +  PARSE_INTEGER_FIELD (jo, "ld3_st3_general_ops", sve.ld3_st3_general_ops);
> +  PARSE_INTEGER_FIELD (jo, "ld4_st4_general_ops", sve.ld4_st4_general_ops);
> +  PARSE_INTEGER_FIELD (jo, "pred_ops_per_cycle", sve.pred_ops_per_cycle);
> +  PARSE_INTEGER_FIELD (jo, "while_pred_ops", sve.while_pred_ops);
> +  PARSE_INTEGER_FIELD (jo, "int_cmp_pred_ops", sve.int_cmp_pred_ops);
> +  PARSE_INTEGER_FIELD (jo, "fp_cmp_pred_ops", sve.fp_cmp_pred_ops);
> +  PARSE_INTEGER_FIELD (jo, "gather_scatter_pair_general_ops", 
> sve.gather_scatter_pair_general_ops);
> +  PARSE_INTEGER_FIELD (jo, "gather_scatter_pair_pred_ops", 
> sve.gather_scatter_pair_pred_ops);
> +}
> +
> +template <typename T>
> +static void
> +parse_branch_costs (const json::object *jo, T &branch_costs)
> +{
> +  PARSE_INTEGER_FIELD (jo, "predictable", branch_costs.predictable);
> +  PARSE_INTEGER_FIELD (jo, "unpredictable", branch_costs.unpredictable);
> +}
> +
> +template <typename T>
> +static void
> +parse_approx_modes (const json::object *jo, T &approx_modes)
> +{
> +  PARSE_INTEGER_FIELD (jo, "division", approx_modes.division);
> +  PARSE_INTEGER_FIELD (jo, "sqrt", approx_modes.sqrt);
> +  PARSE_INTEGER_FIELD (jo, "recip_sqrt", approx_modes.recip_sqrt);
> +}
> +
> +template <typename T>
> +static void
> +parse_memmov_cost (const json::object *jo, T &memmov_cost)
> +{
> +  PARSE_INTEGER_FIELD (jo, "load_int", memmov_cost.load_int);
> +  PARSE_INTEGER_FIELD (jo, "store_int", memmov_cost.store_int);
> +  PARSE_INTEGER_FIELD (jo, "load_fp", memmov_cost.load_fp);
> +  PARSE_INTEGER_FIELD (jo, "store_fp", memmov_cost.store_fp);
> +  PARSE_INTEGER_FIELD (jo, "load_pred", memmov_cost.load_pred);
> +  PARSE_INTEGER_FIELD (jo, "store_pred", memmov_cost.store_pred);
> +}
> +
> +template <typename T>
> +static void
> +parse_prefetch (const json::object *jo, T &prefetch)
> +{
> +  PARSE_INTEGER_FIELD (jo, "num_slots", prefetch.num_slots);
> +  PARSE_INTEGER_FIELD (jo, "l1_cache_size", prefetch.l1_cache_size);
> +  PARSE_INTEGER_FIELD (jo, "l1_cache_line_size", 
> prefetch.l1_cache_line_size);
> +  PARSE_INTEGER_FIELD (jo, "l2_cache_size", prefetch.l2_cache_size);
> +  PARSE_BOOLEAN_FIELD (jo, "prefetch_dynamic_strides", 
> prefetch.prefetch_dynamic_strides);
> +  PARSE_INTEGER_FIELD (jo, "minimum_stride", prefetch.minimum_stride);
> +  PARSE_INTEGER_FIELD (jo, "default_opt_level", prefetch.default_opt_level);
> +}
> +
> +template <typename T>
> +static void
> +parse_insn_extra_cost (const json::object *jo, T &insn_extra_cost)
> +{
> +  PARSE_OBJECT (jo, "alu", insn_extra_cost.alu, parse_insn_extra_cost_alu);
> +  PARSE_ARRAY_FIELD (jo, "mult", insn_extra_cost.mult, 
> parse_insn_extra_cost_mult_element);
> +  PARSE_OBJECT (jo, "ldst", insn_extra_cost.ldst, 
> parse_insn_extra_cost_ldst);
> +  PARSE_ARRAY_FIELD (jo, "fp", insn_extra_cost.fp, 
> parse_insn_extra_cost_fp_element);
> +  PARSE_OBJECT (jo, "vect", insn_extra_cost.vect, 
> parse_insn_extra_cost_vect);
> +}
> +
> +template <typename T>
> +static void
> +parse_addr_cost (const json::object *jo, T &addr_cost)
> +{
> +  PARSE_OBJECT (jo, "addr_scale_costs", addr_cost.addr_scale_costs, 
> parse_addr_cost_addr_scale_costs);
> +  PARSE_INTEGER_FIELD (jo, "pre_modify", addr_cost.pre_modify);
> +  PARSE_INTEGER_FIELD (jo, "post_modify", addr_cost.post_modify);
> +  PARSE_INTEGER_FIELD (jo, "post_modify_ld3_st3", 
> addr_cost.post_modify_ld3_st3);
> +  PARSE_INTEGER_FIELD (jo, "post_modify_ld4_st4", 
> addr_cost.post_modify_ld4_st4);
> +  PARSE_INTEGER_FIELD (jo, "register_offset", addr_cost.register_offset);
> +  PARSE_INTEGER_FIELD (jo, "register_sextend", addr_cost.register_sextend);
> +  PARSE_INTEGER_FIELD (jo, "register_zextend", addr_cost.register_zextend);
> +  PARSE_INTEGER_FIELD (jo, "imm_offset", addr_cost.imm_offset);
> +}
> +
> +template <typename T>
> +static void
> +parse_vec_costs_issue_info (const json::object *jo, T &issue_info)
> +{
> +  PARSE_OBJECT (jo, "scalar", issue_info.scalar, 
> parse_vec_costs_issue_info_scalar);
> +  PARSE_OBJECT (jo, "advsimd", issue_info.advsimd, 
> parse_vec_costs_issue_info_advsimd);
> +  PARSE_OBJECT (jo, "sve", issue_info.sve, parse_vec_costs_issue_info_sve);
> +}
> +
> +template <typename T>
> +static void
> +parse_vec_costs (const json::object *jo, T &vec_costs)
> +{
> +  PARSE_INTEGER_FIELD (jo, "scalar_int_stmt_cost", 
> vec_costs.scalar_int_stmt_cost);
> +  PARSE_INTEGER_FIELD (jo, "scalar_fp_stmt_cost", 
> vec_costs.scalar_fp_stmt_cost);
> +  PARSE_INTEGER_FIELD (jo, "scalar_load_cost", vec_costs.scalar_load_cost);
> +  PARSE_INTEGER_FIELD (jo, "scalar_store_cost", vec_costs.scalar_store_cost);
> +  PARSE_INTEGER_FIELD (jo, "cond_taken_branch_cost", 
> vec_costs.cond_taken_branch_cost);
> +  PARSE_INTEGER_FIELD (jo, "cond_not_taken_branch_cost", 
> vec_costs.cond_not_taken_branch_cost);
> +  PARSE_OBJECT (jo, "advsimd", vec_costs.advsimd, parse_vec_costs_advsimd);
> +  PARSE_OBJECT (jo, "sve", vec_costs.sve, parse_vec_costs_sve);
> +  PARSE_OBJECT (jo, "issue_info", vec_costs.issue_info, 
> parse_vec_costs_issue_info);
> +}
> +
> +template <typename T>
> +static void
> +parse_tunings (const json::object *jo, T &tunings)
> +{
> +  PARSE_OBJECT (jo, "insn_extra_cost", tunings.insn_extra_cost, 
> parse_insn_extra_cost);
> +  PARSE_OBJECT (jo, "addr_cost", tunings.addr_cost, parse_addr_cost);
> +  PARSE_OBJECT (jo, "regmove_cost", tunings.regmove_cost, 
> parse_regmove_cost);
> +  PARSE_OBJECT (jo, "vec_costs", tunings.vec_costs, parse_vec_costs);
> +  PARSE_OBJECT (jo, "branch_costs", tunings.branch_costs, 
> parse_branch_costs);
> +  PARSE_OBJECT (jo, "approx_modes", tunings.approx_modes, 
> parse_approx_modes);
> +  PARSE_INTEGER_FIELD (jo, "sve_width", tunings.sve_width);
> +  PARSE_OBJECT (jo, "memmov_cost", tunings.memmov_cost, parse_memmov_cost);
> +  PARSE_INTEGER_FIELD (jo, "issue_rate", tunings.issue_rate);
> +  PARSE_INTEGER_FIELD (jo, "fusible_ops", tunings.fusible_ops);
> +  PARSE_STRING_FIELD (jo, "function_align", tunings.function_align);
> +  PARSE_STRING_FIELD (jo, "jump_align", tunings.jump_align);
> +  PARSE_STRING_FIELD (jo, "loop_align", tunings.loop_align);
> +  PARSE_INTEGER_FIELD (jo, "int_reassoc_width", tunings.int_reassoc_width);
> +  PARSE_INTEGER_FIELD (jo, "fp_reassoc_width", tunings.fp_reassoc_width);
> +  PARSE_INTEGER_FIELD (jo, "fma_reassoc_width", tunings.fma_reassoc_width);
> +  PARSE_INTEGER_FIELD (jo, "vec_reassoc_width", tunings.vec_reassoc_width);
> +  PARSE_INTEGER_FIELD (jo, "min_div_recip_mul_sf", 
> tunings.min_div_recip_mul_sf);
> +  PARSE_INTEGER_FIELD (jo, "min_div_recip_mul_df", 
> tunings.min_div_recip_mul_df);
> +  PARSE_INTEGER_FIELD (jo, "max_case_values", tunings.max_case_values);
> +  PARSE_ENUM_FIELD (jo, "autoprefetcher_model", 
> tunings.autoprefetcher_model, autoprefetcher_model_mappings);
> +  PARSE_INTEGER_FIELD (jo, "extra_tuning_flags", tunings.extra_tuning_flags);
> +  PARSE_OBJECT (jo, "prefetch", tunings.prefetch, parse_prefetch);
> +  PARSE_ENUM_FIELD (jo, "ldp_policy_model", tunings.ldp_policy_model, 
> ldp_policy_model_mappings);
> +  PARSE_ENUM_FIELD (jo, "stp_policy_model", tunings.stp_policy_model, 
> stp_policy_model_mappings);
> +}
> diff --git a/gcc/config/aarch64/aarch64-json-tunings-parser.cc 
> b/gcc/config/aarch64/aarch64-json-tunings-parser.cc
> index b1d4402a89f..9ee1122ce97 100644
> --- a/gcc/config/aarch64/aarch64-json-tunings-parser.cc
> +++ b/gcc/config/aarch64/aarch64-json-tunings-parser.cc
> @@ -223,364 +223,8 @@ static const enum_mapping<aarch64_ldp_stp_policy> 
> stp_policy_model_mappings[]
>       {"AARCH64_LDP_STP_POLICY_ALWAYS", AARCH64_LDP_STP_POLICY_ALWAYS},
>       {"AARCH64_LDP_STP_POLICY_NEVER", AARCH64_LDP_STP_POLICY_NEVER}};
>  
> -template <typename T>
> -static void
> -parse_insn_extra_cost_alu (const json::object *jo, T &alu)
> -{
> -  PARSE_INTEGER_FIELD (jo, "arith", alu.arith);
> -  PARSE_INTEGER_FIELD (jo, "logical", alu.logical);
> -  PARSE_INTEGER_FIELD (jo, "shift", alu.shift);
> -  PARSE_INTEGER_FIELD (jo, "shift_reg", alu.shift_reg);
> -  PARSE_INTEGER_FIELD (jo, "arith_shift", alu.arith_shift);
> -  PARSE_INTEGER_FIELD (jo, "arith_shift_reg", alu.arith_shift_reg);
> -  PARSE_INTEGER_FIELD (jo, "log_shift", alu.log_shift);
> -  PARSE_INTEGER_FIELD (jo, "log_shift_reg", alu.log_shift_reg);
> -  PARSE_INTEGER_FIELD (jo, "extend", alu.extend);
> -  PARSE_INTEGER_FIELD (jo, "extend_arith", alu.extend_arith);
> -  PARSE_INTEGER_FIELD (jo, "bfi", alu.bfi);
> -  PARSE_INTEGER_FIELD (jo, "bfx", alu.bfx);
> -  PARSE_INTEGER_FIELD (jo, "clz", alu.clz);
> -  PARSE_INTEGER_FIELD (jo, "rev", alu.rev);
> -  PARSE_INTEGER_FIELD (jo, "non_exec", alu.non_exec);
> -  PARSE_BOOLEAN_FIELD (jo, "non_exec_costs_exec", alu.non_exec_costs_exec);
> -}
> -
> -template <typename T>
> -static void
> -parse_insn_extra_cost_mult_element (const json::object *jo, T &mult_element)
> -{
> -  PARSE_INTEGER_FIELD (jo, "simple", mult_element.simple);
> -  PARSE_INTEGER_FIELD (jo, "flag_setting", mult_element.flag_setting);
> -  PARSE_INTEGER_FIELD (jo, "extend", mult_element.extend);
> -  PARSE_INTEGER_FIELD (jo, "add", mult_element.add);
> -  PARSE_INTEGER_FIELD (jo, "extend_add", mult_element.extend_add);
> -  PARSE_INTEGER_FIELD (jo, "idiv", mult_element.idiv);
> -}
> -
> -template <typename T>
> -static void
> -parse_insn_extra_cost_ldst (const json::object *jo, T &ldst)
> -{
> -  PARSE_INTEGER_FIELD (jo, "load", ldst.load);
> -  PARSE_INTEGER_FIELD (jo, "load_sign_extend", ldst.load_sign_extend);
> -  PARSE_INTEGER_FIELD (jo, "ldrd", ldst.ldrd);
> -  PARSE_INTEGER_FIELD (jo, "ldm_1st", ldst.ldm_1st);
> -  PARSE_INTEGER_FIELD (jo, "ldm_regs_per_insn_1st", 
> ldst.ldm_regs_per_insn_1st);
> -  PARSE_INTEGER_FIELD (jo, "ldm_regs_per_insn_subsequent",
> -                    ldst.ldm_regs_per_insn_subsequent);
> -  PARSE_INTEGER_FIELD (jo, "loadf", ldst.loadf);
> -  PARSE_INTEGER_FIELD (jo, "loadd", ldst.loadd);
> -  PARSE_INTEGER_FIELD (jo, "load_unaligned", ldst.load_unaligned);
> -  PARSE_INTEGER_FIELD (jo, "store", ldst.store);
> -  PARSE_INTEGER_FIELD (jo, "strd", ldst.strd);
> -  PARSE_INTEGER_FIELD (jo, "stm_1st", ldst.stm_1st);
> -  PARSE_INTEGER_FIELD (jo, "stm_regs_per_insn_1st", 
> ldst.stm_regs_per_insn_1st);
> -  PARSE_INTEGER_FIELD (jo, "stm_regs_per_insn_subsequent",
> -                    ldst.stm_regs_per_insn_subsequent);
> -  PARSE_INTEGER_FIELD (jo, "storef", ldst.storef);
> -  PARSE_INTEGER_FIELD (jo, "stored", ldst.stored);
> -  PARSE_INTEGER_FIELD (jo, "store_unaligned", ldst.store_unaligned);
> -  PARSE_INTEGER_FIELD (jo, "loadv", ldst.loadv);
> -  PARSE_INTEGER_FIELD (jo, "storev", ldst.storev);
> -}
> -
> -template <typename T>
> -static void
> -parse_insn_extra_cost_fp_element (const json::object *jo, T &fp_element)
> -{
> -  PARSE_INTEGER_FIELD (jo, "div", fp_element.div);
> -  PARSE_INTEGER_FIELD (jo, "mult", fp_element.mult);
> -  PARSE_INTEGER_FIELD (jo, "mult_addsub", fp_element.mult_addsub);
> -  PARSE_INTEGER_FIELD (jo, "fma", fp_element.fma);
> -  PARSE_INTEGER_FIELD (jo, "addsub", fp_element.addsub);
> -  PARSE_INTEGER_FIELD (jo, "fpconst", fp_element.fpconst);
> -  PARSE_INTEGER_FIELD (jo, "neg", fp_element.neg);
> -  PARSE_INTEGER_FIELD (jo, "compare", fp_element.compare);
> -  PARSE_INTEGER_FIELD (jo, "widen", fp_element.widen);
> -  PARSE_INTEGER_FIELD (jo, "narrow", fp_element.narrow);
> -  PARSE_INTEGER_FIELD (jo, "toint", fp_element.toint);
> -  PARSE_INTEGER_FIELD (jo, "fromint", fp_element.fromint);
> -  PARSE_INTEGER_FIELD (jo, "roundint", fp_element.roundint);
> -}
> -
> -template <typename T>
> -static void
> -parse_insn_extra_cost_vect (const json::object *jo, T &vect)
> -{
> -  PARSE_INTEGER_FIELD (jo, "alu", vect.alu);
> -  PARSE_INTEGER_FIELD (jo, "mult", vect.mult);
> -  PARSE_INTEGER_FIELD (jo, "movi", vect.movi);
> -  PARSE_INTEGER_FIELD (jo, "dup", vect.dup);
> -  PARSE_INTEGER_FIELD (jo, "extract", vect.extract);
> -}
> -
> -template <typename T>
> -static void
> -parse_addr_cost_addr_scale_costs (const json::object *jo, T 
> &addr_scale_costs)
> -{
> -  PARSE_INTEGER_FIELD (jo, "hi", addr_scale_costs.hi);
> -  PARSE_INTEGER_FIELD (jo, "si", addr_scale_costs.si);
> -  PARSE_INTEGER_FIELD (jo, "di", addr_scale_costs.di);
> -  PARSE_INTEGER_FIELD (jo, "ti", addr_scale_costs.ti);
> -}
> -
> -template <typename T>
> -static void
> -parse_regmove_cost (const json::object *jo, T &regmove_cost)
> -{
> -  PARSE_INTEGER_FIELD (jo, "GP2GP", regmove_cost.GP2GP);
> -  PARSE_INTEGER_FIELD (jo, "GP2FP", regmove_cost.GP2FP);
> -  PARSE_INTEGER_FIELD (jo, "FP2GP", regmove_cost.FP2GP);
> -  PARSE_INTEGER_FIELD (jo, "FP2FP", regmove_cost.FP2FP);
> -}
> -
> -template <typename T>
> -static void
> -parse_vec_costs_advsimd (const json::object *jo, T &advsimd)
> -{
> -  PARSE_INTEGER_FIELD (jo, "int_stmt_cost", advsimd.int_stmt_cost);
> -  PARSE_INTEGER_FIELD (jo, "fp_stmt_cost", advsimd.fp_stmt_cost);
> -  PARSE_INTEGER_FIELD (jo, "ld2_st2_permute_cost",
> -                    advsimd.ld2_st2_permute_cost);
> -  PARSE_INTEGER_FIELD (jo, "ld3_st3_permute_cost",
> -                    advsimd.ld3_st3_permute_cost);
> -  PARSE_INTEGER_FIELD (jo, "ld4_st4_permute_cost",
> -                    advsimd.ld4_st4_permute_cost);
> -  PARSE_INTEGER_FIELD (jo, "permute_cost", advsimd.permute_cost);
> -  PARSE_INTEGER_FIELD (jo, "reduc_i8_cost", advsimd.reduc_i8_cost);
> -  PARSE_INTEGER_FIELD (jo, "reduc_i16_cost", advsimd.reduc_i16_cost);
> -  PARSE_INTEGER_FIELD (jo, "reduc_i32_cost", advsimd.reduc_i32_cost);
> -  PARSE_INTEGER_FIELD (jo, "reduc_i64_cost", advsimd.reduc_i64_cost);
> -  PARSE_INTEGER_FIELD (jo, "reduc_f16_cost", advsimd.reduc_f16_cost);
> -  PARSE_INTEGER_FIELD (jo, "reduc_f32_cost", advsimd.reduc_f32_cost);
> -  PARSE_INTEGER_FIELD (jo, "reduc_f64_cost", advsimd.reduc_f64_cost);
> -  PARSE_INTEGER_FIELD (jo, "store_elt_extra_cost",
> -                    advsimd.store_elt_extra_cost);
> -  PARSE_INTEGER_FIELD (jo, "vec_to_scalar_cost", advsimd.vec_to_scalar_cost);
> -  PARSE_INTEGER_FIELD (jo, "scalar_to_vec_cost", advsimd.scalar_to_vec_cost);
> -  PARSE_INTEGER_FIELD (jo, "align_load_cost", advsimd.align_load_cost);
> -  PARSE_INTEGER_FIELD (jo, "unalign_load_cost", advsimd.unalign_load_cost);
> -  PARSE_INTEGER_FIELD (jo, "unalign_store_cost", advsimd.unalign_store_cost);
> -  PARSE_INTEGER_FIELD (jo, "store_cost", advsimd.store_cost);
> -}
> -
> -template <typename T>
> -static void
> -parse_vec_costs_sve (const json::object *jo, T &sve)
> -{
> -  PARSE_INTEGER_FIELD (jo, "clast_cost", sve.clast_cost);
> -  PARSE_INTEGER_FIELD (jo, "fadda_f16_cost", sve.fadda_f16_cost);
> -  PARSE_INTEGER_FIELD (jo, "fadda_f32_cost", sve.fadda_f32_cost);
> -  PARSE_INTEGER_FIELD (jo, "fadda_f64_cost", sve.fadda_f64_cost);
> -  PARSE_INTEGER_FIELD (jo, "gather_load_x32_cost", sve.gather_load_x32_cost);
> -  PARSE_INTEGER_FIELD (jo, "gather_load_x64_cost", sve.gather_load_x64_cost);
> -  PARSE_INTEGER_FIELD (jo, "gather_load_x32_init_cost",
> -                    sve.gather_load_x32_init_cost);
> -  PARSE_INTEGER_FIELD (jo, "gather_load_x64_init_cost",
> -                    sve.gather_load_x64_init_cost);
> -  PARSE_INTEGER_FIELD (jo, "scatter_store_elt_cost",
> -                    sve.scatter_store_elt_cost);
> -}
> -
> -template <typename T>
> -static void
> -parse_vec_costs_issue_info_scalar (const json::object *jo, T &scalar)
> -{
> -  PARSE_INTEGER_FIELD (jo, "loads_stores_per_cycle",
> -                    scalar.loads_stores_per_cycle);
> -  PARSE_INTEGER_FIELD (jo, "stores_per_cycle", scalar.stores_per_cycle);
> -  PARSE_INTEGER_FIELD (jo, "general_ops_per_cycle",
> -                    scalar.general_ops_per_cycle);
> -  PARSE_INTEGER_FIELD (jo, "fp_simd_load_general_ops",
> -                    scalar.fp_simd_load_general_ops);
> -  PARSE_INTEGER_FIELD (jo, "fp_simd_store_general_ops",
> -                    scalar.fp_simd_store_general_ops);
> -}
> -
> -template <typename T>
> -static void
> -parse_vec_costs_issue_info_advsimd (const json::object *jo, T &advsimd)
> -{
> -  PARSE_INTEGER_FIELD (jo, "loads_stores_per_cycle",
> -                    advsimd.loads_stores_per_cycle);
> -  PARSE_INTEGER_FIELD (jo, "stores_per_cycle", advsimd.stores_per_cycle);
> -  PARSE_INTEGER_FIELD (jo, "general_ops_per_cycle",
> -                    advsimd.general_ops_per_cycle);
> -  PARSE_INTEGER_FIELD (jo, "fp_simd_load_general_ops",
> -                    advsimd.fp_simd_load_general_ops);
> -  PARSE_INTEGER_FIELD (jo, "fp_simd_store_general_ops",
> -                    advsimd.fp_simd_store_general_ops);
> -  PARSE_INTEGER_FIELD (jo, "ld2_st2_general_ops", 
> advsimd.ld2_st2_general_ops);
> -  PARSE_INTEGER_FIELD (jo, "ld3_st3_general_ops", 
> advsimd.ld3_st3_general_ops);
> -  PARSE_INTEGER_FIELD (jo, "ld4_st4_general_ops", 
> advsimd.ld4_st4_general_ops);
> -}
> -
> -template <typename T>
> -static void
> -parse_vec_costs_issue_info_sve (const json::object *jo, T &sve)
> -{
> -  PARSE_INTEGER_FIELD (jo, "loads_stores_per_cycle",
> -                    sve.loads_stores_per_cycle);
> -  PARSE_INTEGER_FIELD (jo, "stores_per_cycle", sve.stores_per_cycle);
> -  PARSE_INTEGER_FIELD (jo, "general_ops_per_cycle", 
> sve.general_ops_per_cycle);
> -  PARSE_INTEGER_FIELD (jo, "fp_simd_load_general_ops",
> -                    sve.fp_simd_load_general_ops);
> -  PARSE_INTEGER_FIELD (jo, "fp_simd_store_general_ops",
> -                    sve.fp_simd_store_general_ops);
> -  PARSE_INTEGER_FIELD (jo, "ld2_st2_general_ops", sve.ld2_st2_general_ops);
> -  PARSE_INTEGER_FIELD (jo, "ld3_st3_general_ops", sve.ld3_st3_general_ops);
> -  PARSE_INTEGER_FIELD (jo, "ld4_st4_general_ops", sve.ld4_st4_general_ops);
> -  PARSE_INTEGER_FIELD (jo, "pred_ops_per_cycle", sve.pred_ops_per_cycle);
> -  PARSE_INTEGER_FIELD (jo, "while_pred_ops", sve.while_pred_ops);
> -  PARSE_INTEGER_FIELD (jo, "int_cmp_pred_ops", sve.int_cmp_pred_ops);
> -  PARSE_INTEGER_FIELD (jo, "fp_cmp_pred_ops", sve.fp_cmp_pred_ops);
> -  PARSE_INTEGER_FIELD (jo, "gather_scatter_pair_general_ops",
> -                    sve.gather_scatter_pair_general_ops);
> -  PARSE_INTEGER_FIELD (jo, "gather_scatter_pair_pred_ops",
> -                    sve.gather_scatter_pair_pred_ops);
> -}
> -
> -template <typename T>
> -static void
> -parse_branch_costs (const json::object *jo, T &branch_costs)
> -{
> -  PARSE_INTEGER_FIELD (jo, "predictable", branch_costs.predictable);
> -  PARSE_INTEGER_FIELD (jo, "unpredictable", branch_costs.unpredictable);
> -}
> -
> -template <typename T>
> -static void
> -parse_approx_modes (const json::object *jo, T &approx_modes)
> -{
> -  PARSE_INTEGER_FIELD (jo, "division", approx_modes.division);
> -  PARSE_INTEGER_FIELD (jo, "sqrt", approx_modes.sqrt);
> -  PARSE_INTEGER_FIELD (jo, "recip_sqrt", approx_modes.recip_sqrt);
> -}
> -
> -template <typename T>
> -static void
> -parse_memmov_cost (const json::object *jo, T &memmov_cost)
> -{
> -  PARSE_INTEGER_FIELD (jo, "load_int", memmov_cost.load_int);
> -  PARSE_INTEGER_FIELD (jo, "store_int", memmov_cost.store_int);
> -  PARSE_INTEGER_FIELD (jo, "load_fp", memmov_cost.load_fp);
> -  PARSE_INTEGER_FIELD (jo, "store_fp", memmov_cost.store_fp);
> -  PARSE_INTEGER_FIELD (jo, "load_pred", memmov_cost.load_pred);
> -  PARSE_INTEGER_FIELD (jo, "store_pred", memmov_cost.store_pred);
> -}
> -
> -template <typename T>
> -static void
> -parse_prefetch (const json::object *jo, T &prefetch)
> -{
> -  PARSE_INTEGER_FIELD (jo, "num_slots", prefetch.num_slots);
> -  PARSE_INTEGER_FIELD (jo, "l1_cache_size", prefetch.l1_cache_size);
> -  PARSE_INTEGER_FIELD (jo, "l1_cache_line_size", 
> prefetch.l1_cache_line_size);
> -  PARSE_INTEGER_FIELD (jo, "l2_cache_size", prefetch.l2_cache_size);
> -  PARSE_BOOLEAN_FIELD (jo, "prefetch_dynamic_strides",
> -                    prefetch.prefetch_dynamic_strides);
> -  PARSE_INTEGER_FIELD (jo, "minimum_stride", prefetch.minimum_stride);
> -  PARSE_INTEGER_FIELD (jo, "default_opt_level", prefetch.default_opt_level);
> -}
> -
> -template <typename T>
> -static void
> -parse_insn_extra_cost (const json::object *jo, T &insn_extra_cost)
> -{
> -  PARSE_OBJECT (jo, "alu", insn_extra_cost.alu, parse_insn_extra_cost_alu);
> -  PARSE_ARRAY_FIELD (jo, "mult", insn_extra_cost.mult,
> -                  parse_insn_extra_cost_mult_element);
> -  PARSE_OBJECT (jo, "ldst", insn_extra_cost.ldst, 
> parse_insn_extra_cost_ldst);
> -  PARSE_ARRAY_FIELD (jo, "fp", insn_extra_cost.fp,
> -                  parse_insn_extra_cost_fp_element);
> -  PARSE_OBJECT (jo, "vect", insn_extra_cost.vect, 
> parse_insn_extra_cost_vect);
> -}
> -
> -template <typename T>
> -static void
> -parse_addr_cost (const json::object *jo, T &addr_cost)
> -{
> -  PARSE_OBJECT (jo, "addr_scale_costs", addr_cost.addr_scale_costs,
> -             parse_addr_cost_addr_scale_costs);
> -  PARSE_INTEGER_FIELD (jo, "pre_modify", addr_cost.pre_modify);
> -  PARSE_INTEGER_FIELD (jo, "post_modify", addr_cost.post_modify);
> -  PARSE_INTEGER_FIELD (jo, "post_modify_ld3_st3",
> -                    addr_cost.post_modify_ld3_st3);
> -  PARSE_INTEGER_FIELD (jo, "post_modify_ld4_st4",
> -                    addr_cost.post_modify_ld4_st4);
> -  PARSE_INTEGER_FIELD (jo, "register_offset", addr_cost.register_offset);
> -  PARSE_INTEGER_FIELD (jo, "register_sextend", addr_cost.register_sextend);
> -  PARSE_INTEGER_FIELD (jo, "register_zextend", addr_cost.register_zextend);
> -  PARSE_INTEGER_FIELD (jo, "imm_offset", addr_cost.imm_offset);
> -}
> -
> -template <typename T>
> -static void
> -parse_vec_costs_issue_info (const json::object *jo, T &issue_info)
> -{
> -  PARSE_OBJECT (jo, "scalar", issue_info.scalar,
> -             parse_vec_costs_issue_info_scalar);
> -  PARSE_OBJECT (jo, "advsimd", issue_info.advsimd,
> -             parse_vec_costs_issue_info_advsimd);
> -  PARSE_OBJECT (jo, "sve", issue_info.sve, parse_vec_costs_issue_info_sve);
> -}
> -
> -template <typename T>
> -static void
> -parse_vec_costs (const json::object *jo, T &vec_costs)
> -{
> -  PARSE_INTEGER_FIELD (jo, "scalar_int_stmt_cost",
> -                    vec_costs.scalar_int_stmt_cost);
> -  PARSE_INTEGER_FIELD (jo, "scalar_fp_stmt_cost",
> -                    vec_costs.scalar_fp_stmt_cost);
> -  PARSE_INTEGER_FIELD (jo, "scalar_load_cost", vec_costs.scalar_load_cost);
> -  PARSE_INTEGER_FIELD (jo, "scalar_store_cost", vec_costs.scalar_store_cost);
> -  PARSE_INTEGER_FIELD (jo, "cond_taken_branch_cost",
> -                    vec_costs.cond_taken_branch_cost);
> -  PARSE_INTEGER_FIELD (jo, "cond_not_taken_branch_cost",
> -                    vec_costs.cond_not_taken_branch_cost);
> -  PARSE_OBJECT (jo, "advsimd", vec_costs.advsimd, parse_vec_costs_advsimd);
> -  PARSE_OBJECT (jo, "sve", vec_costs.sve, parse_vec_costs_sve);
> -  PARSE_OBJECT (jo, "issue_info", vec_costs.issue_info,
> -             parse_vec_costs_issue_info);
> -}
> -
> -template <typename T>
> -static void
> -parse_tunings (const json::object *jo, T &tunings)
> -{
> -  PARSE_OBJECT (jo, "insn_extra_cost", tunings.insn_extra_cost,
> -             parse_insn_extra_cost);
> -  PARSE_OBJECT (jo, "addr_cost", tunings.addr_cost, parse_addr_cost);
> -  PARSE_OBJECT (jo, "regmove_cost", tunings.regmove_cost, 
> parse_regmove_cost);
> -  PARSE_OBJECT (jo, "vec_costs", tunings.vec_costs, parse_vec_costs);
> -  PARSE_OBJECT (jo, "branch_costs", tunings.branch_costs, 
> parse_branch_costs);
> -  PARSE_OBJECT (jo, "approx_modes", tunings.approx_modes, 
> parse_approx_modes);
> -  PARSE_INTEGER_FIELD (jo, "sve_width", tunings.sve_width);
> -  PARSE_OBJECT (jo, "memmov_cost", tunings.memmov_cost, parse_memmov_cost);
> -  PARSE_INTEGER_FIELD (jo, "issue_rate", tunings.issue_rate);
> -  PARSE_INTEGER_FIELD (jo, "fusible_ops", tunings.fusible_ops);
> -  PARSE_STRING_FIELD (jo, "function_align", tunings.function_align);
> -  PARSE_STRING_FIELD (jo, "jump_align", tunings.jump_align);
> -  PARSE_STRING_FIELD (jo, "loop_align", tunings.loop_align);
> -  PARSE_INTEGER_FIELD (jo, "int_reassoc_width", tunings.int_reassoc_width);
> -  PARSE_INTEGER_FIELD (jo, "fp_reassoc_width", tunings.fp_reassoc_width);
> -  PARSE_INTEGER_FIELD (jo, "fma_reassoc_width", tunings.fma_reassoc_width);
> -  PARSE_INTEGER_FIELD (jo, "vec_reassoc_width", tunings.vec_reassoc_width);
> -  PARSE_INTEGER_FIELD (jo, "min_div_recip_mul_sf",
> -                    tunings.min_div_recip_mul_sf);
> -  PARSE_INTEGER_FIELD (jo, "min_div_recip_mul_df",
> -                    tunings.min_div_recip_mul_df);
> -  PARSE_INTEGER_FIELD (jo, "max_case_values", tunings.max_case_values);
> -  PARSE_ENUM_FIELD (jo, "autoprefetcher_model", tunings.autoprefetcher_model,
> -                 autoprefetcher_model_mappings);
> -  PARSE_INTEGER_FIELD (jo, "extra_tuning_flags", tunings.extra_tuning_flags);
> -  PARSE_OBJECT (jo, "prefetch", tunings.prefetch, parse_prefetch);
> -  PARSE_ENUM_FIELD (jo, "ldp_policy_model", tunings.ldp_policy_model,
> -                 ldp_policy_model_mappings);
> -  PARSE_ENUM_FIELD (jo, "stp_policy_model", tunings.stp_policy_model,
> -                 stp_policy_model_mappings);
> -}
> +/* Include auto-generated parsing routines.  */
> +#include "aarch64-json-tunings-parser-generated.inc"
>  
>  /* Validate the user provided JSON data against the present schema.
>     Checks for correct types, fields, and expected format.  */
> diff --git a/gcc/config/aarch64/aarch64-json-tunings-printer-generated.inc 
> b/gcc/config/aarch64/aarch64-json-tunings-printer-generated.inc
> new file mode 100644
> index 00000000000..e347cb9dfcf
> --- /dev/null
> +++ b/gcc/config/aarch64/aarch64-json-tunings-printer-generated.inc
> @@ -0,0 +1,421 @@
> +/* This file is auto-generated by aarch64-generate-json-tuning-routines.py.  
> */
> +/* Copyright The GNU Toolchain Authors.
> +   This file is part of GCC.
> +
> +   GCC is free software; you can redistribute it and/or modify it under
> +   the terms of the GNU General Public License as published by the Free
> +   Software Foundation; either version 3, or (at your option) any later
> +   version.
> +
> +   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +   WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +   for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with GCC; see the file COPYING3.  If not see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* This file contains the auto-generated serializer functions for JSON 
> tuning parameters.  */
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_insn_extra_cost_alu (const T &alu)
> +{
> +  auto alu_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_INTEGER_FIELD (alu_obj, "arith", alu.arith);
> +  SERIALIZE_INTEGER_FIELD (alu_obj, "logical", alu.logical);
> +  SERIALIZE_INTEGER_FIELD (alu_obj, "shift", alu.shift);
> +  SERIALIZE_INTEGER_FIELD (alu_obj, "shift_reg", alu.shift_reg);
> +  SERIALIZE_INTEGER_FIELD (alu_obj, "arith_shift", alu.arith_shift);
> +  SERIALIZE_INTEGER_FIELD (alu_obj, "arith_shift_reg", alu.arith_shift_reg);
> +  SERIALIZE_INTEGER_FIELD (alu_obj, "log_shift", alu.log_shift);
> +  SERIALIZE_INTEGER_FIELD (alu_obj, "log_shift_reg", alu.log_shift_reg);
> +  SERIALIZE_INTEGER_FIELD (alu_obj, "extend", alu.extend);
> +  SERIALIZE_INTEGER_FIELD (alu_obj, "extend_arith", alu.extend_arith);
> +  SERIALIZE_INTEGER_FIELD (alu_obj, "bfi", alu.bfi);
> +  SERIALIZE_INTEGER_FIELD (alu_obj, "bfx", alu.bfx);
> +  SERIALIZE_INTEGER_FIELD (alu_obj, "clz", alu.clz);
> +  SERIALIZE_INTEGER_FIELD (alu_obj, "rev", alu.rev);
> +  SERIALIZE_INTEGER_FIELD (alu_obj, "non_exec", alu.non_exec);
> +  SERIALIZE_BOOLEAN_FIELD (alu_obj, "non_exec_costs_exec", 
> alu.non_exec_costs_exec);
> +
> +  return alu_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_insn_extra_cost_mult_element (const T &mult_element)
> +{
> +  auto mult_element_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_INTEGER_FIELD (mult_element_obj, "simple", mult_element.simple);
> +  SERIALIZE_INTEGER_FIELD (mult_element_obj, "flag_setting", 
> mult_element.flag_setting);
> +  SERIALIZE_INTEGER_FIELD (mult_element_obj, "extend", mult_element.extend);
> +  SERIALIZE_INTEGER_FIELD (mult_element_obj, "add", mult_element.add);
> +  SERIALIZE_INTEGER_FIELD (mult_element_obj, "extend_add", 
> mult_element.extend_add);
> +  SERIALIZE_INTEGER_FIELD (mult_element_obj, "idiv", mult_element.idiv);
> +
> +  return mult_element_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_insn_extra_cost_ldst (const T &ldst)
> +{
> +  auto ldst_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "load", ldst.load);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "load_sign_extend", 
> ldst.load_sign_extend);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "ldrd", ldst.ldrd);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "ldm_1st", ldst.ldm_1st);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "ldm_regs_per_insn_1st", 
> ldst.ldm_regs_per_insn_1st);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "ldm_regs_per_insn_subsequent", 
> ldst.ldm_regs_per_insn_subsequent);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "loadf", ldst.loadf);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "loadd", ldst.loadd);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "load_unaligned", ldst.load_unaligned);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "store", ldst.store);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "strd", ldst.strd);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "stm_1st", ldst.stm_1st);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "stm_regs_per_insn_1st", 
> ldst.stm_regs_per_insn_1st);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "stm_regs_per_insn_subsequent", 
> ldst.stm_regs_per_insn_subsequent);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "storef", ldst.storef);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "stored", ldst.stored);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "store_unaligned", 
> ldst.store_unaligned);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "loadv", ldst.loadv);
> +  SERIALIZE_INTEGER_FIELD (ldst_obj, "storev", ldst.storev);
> +
> +  return ldst_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_insn_extra_cost_fp_element (const T &fp_element)
> +{
> +  auto fp_element_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_INTEGER_FIELD (fp_element_obj, "div", fp_element.div);
> +  SERIALIZE_INTEGER_FIELD (fp_element_obj, "mult", fp_element.mult);
> +  SERIALIZE_INTEGER_FIELD (fp_element_obj, "mult_addsub", 
> fp_element.mult_addsub);
> +  SERIALIZE_INTEGER_FIELD (fp_element_obj, "fma", fp_element.fma);
> +  SERIALIZE_INTEGER_FIELD (fp_element_obj, "addsub", fp_element.addsub);
> +  SERIALIZE_INTEGER_FIELD (fp_element_obj, "fpconst", fp_element.fpconst);
> +  SERIALIZE_INTEGER_FIELD (fp_element_obj, "neg", fp_element.neg);
> +  SERIALIZE_INTEGER_FIELD (fp_element_obj, "compare", fp_element.compare);
> +  SERIALIZE_INTEGER_FIELD (fp_element_obj, "widen", fp_element.widen);
> +  SERIALIZE_INTEGER_FIELD (fp_element_obj, "narrow", fp_element.narrow);
> +  SERIALIZE_INTEGER_FIELD (fp_element_obj, "toint", fp_element.toint);
> +  SERIALIZE_INTEGER_FIELD (fp_element_obj, "fromint", fp_element.fromint);
> +  SERIALIZE_INTEGER_FIELD (fp_element_obj, "roundint", fp_element.roundint);
> +
> +  return fp_element_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_insn_extra_cost_vect (const T &vect)
> +{
> +  auto vect_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_INTEGER_FIELD (vect_obj, "alu", vect.alu);
> +  SERIALIZE_INTEGER_FIELD (vect_obj, "mult", vect.mult);
> +  SERIALIZE_INTEGER_FIELD (vect_obj, "movi", vect.movi);
> +  SERIALIZE_INTEGER_FIELD (vect_obj, "dup", vect.dup);
> +  SERIALIZE_INTEGER_FIELD (vect_obj, "extract", vect.extract);
> +
> +  return vect_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_addr_cost_addr_scale_costs (const T &addr_scale_costs)
> +{
> +  auto addr_scale_costs_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_INTEGER_FIELD (addr_scale_costs_obj, "hi", addr_scale_costs.hi);
> +  SERIALIZE_INTEGER_FIELD (addr_scale_costs_obj, "si", addr_scale_costs.si);
> +  SERIALIZE_INTEGER_FIELD (addr_scale_costs_obj, "di", addr_scale_costs.di);
> +  SERIALIZE_INTEGER_FIELD (addr_scale_costs_obj, "ti", addr_scale_costs.ti);
> +
> +  return addr_scale_costs_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_regmove_cost (const T &regmove_cost)
> +{
> +  auto regmove_cost_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_INTEGER_FIELD (regmove_cost_obj, "GP2GP", regmove_cost.GP2GP);
> +  SERIALIZE_INTEGER_FIELD (regmove_cost_obj, "GP2FP", regmove_cost.GP2FP);
> +  SERIALIZE_INTEGER_FIELD (regmove_cost_obj, "FP2GP", regmove_cost.FP2GP);
> +  SERIALIZE_INTEGER_FIELD (regmove_cost_obj, "FP2FP", regmove_cost.FP2FP);
> +
> +  return regmove_cost_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_vec_costs_advsimd (const T &advsimd)
> +{
> +  auto advsimd_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "int_stmt_cost", 
> advsimd.int_stmt_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "fp_stmt_cost", 
> advsimd.fp_stmt_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "ld2_st2_permute_cost", 
> advsimd.ld2_st2_permute_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "ld3_st3_permute_cost", 
> advsimd.ld3_st3_permute_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "ld4_st4_permute_cost", 
> advsimd.ld4_st4_permute_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "permute_cost", 
> advsimd.permute_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "reduc_i8_cost", 
> advsimd.reduc_i8_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "reduc_i16_cost", 
> advsimd.reduc_i16_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "reduc_i32_cost", 
> advsimd.reduc_i32_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "reduc_i64_cost", 
> advsimd.reduc_i64_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "reduc_f16_cost", 
> advsimd.reduc_f16_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "reduc_f32_cost", 
> advsimd.reduc_f32_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "reduc_f64_cost", 
> advsimd.reduc_f64_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "store_elt_extra_cost", 
> advsimd.store_elt_extra_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "vec_to_scalar_cost", 
> advsimd.vec_to_scalar_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "scalar_to_vec_cost", 
> advsimd.scalar_to_vec_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "align_load_cost", 
> advsimd.align_load_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "unalign_load_cost", 
> advsimd.unalign_load_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "unalign_store_cost", 
> advsimd.unalign_store_cost);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "store_cost", advsimd.store_cost);
> +
> +  return advsimd_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_vec_costs_sve (const T &sve)
> +{
> +  auto sve_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "clast_cost", sve.clast_cost);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "fadda_f16_cost", sve.fadda_f16_cost);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "fadda_f32_cost", sve.fadda_f32_cost);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "fadda_f64_cost", sve.fadda_f64_cost);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "gather_load_x32_cost", 
> sve.gather_load_x32_cost);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "gather_load_x64_cost", 
> sve.gather_load_x64_cost);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "gather_load_x32_init_cost", 
> sve.gather_load_x32_init_cost);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "gather_load_x64_init_cost", 
> sve.gather_load_x64_init_cost);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "scatter_store_elt_cost", 
> sve.scatter_store_elt_cost);
> +
> +  return sve_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_vec_costs_issue_info_scalar (const T &scalar)
> +{
> +  auto scalar_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_INTEGER_FIELD (scalar_obj, "loads_stores_per_cycle", 
> scalar.loads_stores_per_cycle);
> +  SERIALIZE_INTEGER_FIELD (scalar_obj, "stores_per_cycle", 
> scalar.stores_per_cycle);
> +  SERIALIZE_INTEGER_FIELD (scalar_obj, "general_ops_per_cycle", 
> scalar.general_ops_per_cycle);
> +  SERIALIZE_INTEGER_FIELD (scalar_obj, "fp_simd_load_general_ops", 
> scalar.fp_simd_load_general_ops);
> +  SERIALIZE_INTEGER_FIELD (scalar_obj, "fp_simd_store_general_ops", 
> scalar.fp_simd_store_general_ops);
> +
> +  return scalar_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_vec_costs_issue_info_advsimd (const T &advsimd)
> +{
> +  auto advsimd_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "loads_stores_per_cycle", 
> advsimd.loads_stores_per_cycle);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "stores_per_cycle", 
> advsimd.stores_per_cycle);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "general_ops_per_cycle", 
> advsimd.general_ops_per_cycle);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "fp_simd_load_general_ops", 
> advsimd.fp_simd_load_general_ops);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "fp_simd_store_general_ops", 
> advsimd.fp_simd_store_general_ops);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "ld2_st2_general_ops", 
> advsimd.ld2_st2_general_ops);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "ld3_st3_general_ops", 
> advsimd.ld3_st3_general_ops);
> +  SERIALIZE_INTEGER_FIELD (advsimd_obj, "ld4_st4_general_ops", 
> advsimd.ld4_st4_general_ops);
> +
> +  return advsimd_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_vec_costs_issue_info_sve (const T &sve)
> +{
> +  auto sve_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "loads_stores_per_cycle", 
> sve.loads_stores_per_cycle);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "stores_per_cycle", 
> sve.stores_per_cycle);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "general_ops_per_cycle", 
> sve.general_ops_per_cycle);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "fp_simd_load_general_ops", 
> sve.fp_simd_load_general_ops);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "fp_simd_store_general_ops", 
> sve.fp_simd_store_general_ops);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "ld2_st2_general_ops", 
> sve.ld2_st2_general_ops);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "ld3_st3_general_ops", 
> sve.ld3_st3_general_ops);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "ld4_st4_general_ops", 
> sve.ld4_st4_general_ops);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "pred_ops_per_cycle", 
> sve.pred_ops_per_cycle);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "while_pred_ops", sve.while_pred_ops);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "int_cmp_pred_ops", 
> sve.int_cmp_pred_ops);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "fp_cmp_pred_ops", sve.fp_cmp_pred_ops);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "gather_scatter_pair_general_ops", 
> sve.gather_scatter_pair_general_ops);
> +  SERIALIZE_INTEGER_FIELD (sve_obj, "gather_scatter_pair_pred_ops", 
> sve.gather_scatter_pair_pred_ops);
> +
> +  return sve_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_branch_costs (const T &branch_costs)
> +{
> +  auto branch_costs_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_INTEGER_FIELD (branch_costs_obj, "predictable", 
> branch_costs.predictable);
> +  SERIALIZE_INTEGER_FIELD (branch_costs_obj, "unpredictable", 
> branch_costs.unpredictable);
> +
> +  return branch_costs_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_approx_modes (const T &approx_modes)
> +{
> +  auto approx_modes_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_INTEGER_FIELD (approx_modes_obj, "division", 
> approx_modes.division);
> +  SERIALIZE_INTEGER_FIELD (approx_modes_obj, "sqrt", approx_modes.sqrt);
> +  SERIALIZE_INTEGER_FIELD (approx_modes_obj, "recip_sqrt", 
> approx_modes.recip_sqrt);
> +
> +  return approx_modes_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_memmov_cost (const T &memmov_cost)
> +{
> +  auto memmov_cost_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_INTEGER_FIELD (memmov_cost_obj, "load_int", 
> memmov_cost.load_int);
> +  SERIALIZE_INTEGER_FIELD (memmov_cost_obj, "store_int", 
> memmov_cost.store_int);
> +  SERIALIZE_INTEGER_FIELD (memmov_cost_obj, "load_fp", memmov_cost.load_fp);
> +  SERIALIZE_INTEGER_FIELD (memmov_cost_obj, "store_fp", 
> memmov_cost.store_fp);
> +  SERIALIZE_INTEGER_FIELD (memmov_cost_obj, "load_pred", 
> memmov_cost.load_pred);
> +  SERIALIZE_INTEGER_FIELD (memmov_cost_obj, "store_pred", 
> memmov_cost.store_pred);
> +
> +  return memmov_cost_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_prefetch (const T &prefetch)
> +{
> +  auto prefetch_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_INTEGER_FIELD (prefetch_obj, "num_slots", prefetch.num_slots);
> +  SERIALIZE_INTEGER_FIELD (prefetch_obj, "l1_cache_size", 
> prefetch.l1_cache_size);
> +  SERIALIZE_INTEGER_FIELD (prefetch_obj, "l1_cache_line_size", 
> prefetch.l1_cache_line_size);
> +  SERIALIZE_INTEGER_FIELD (prefetch_obj, "l2_cache_size", 
> prefetch.l2_cache_size);
> +  SERIALIZE_BOOLEAN_FIELD (prefetch_obj, "prefetch_dynamic_strides", 
> prefetch.prefetch_dynamic_strides);
> +  SERIALIZE_INTEGER_FIELD (prefetch_obj, "minimum_stride", 
> prefetch.minimum_stride);
> +  SERIALIZE_INTEGER_FIELD (prefetch_obj, "default_opt_level", 
> prefetch.default_opt_level);
> +
> +  return prefetch_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_insn_extra_cost (const T &insn_extra_cost)
> +{
> +  auto insn_extra_cost_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_OBJECT (insn_extra_cost_obj, "alu", insn_extra_cost.alu, 
> serialize_insn_extra_cost_alu);
> +  SERIALIZE_ARRAY_FIELD (insn_extra_cost_obj, "mult", insn_extra_cost.mult, 
> 2, serialize_insn_extra_cost_mult_element);
> +  SERIALIZE_OBJECT (insn_extra_cost_obj, "ldst", insn_extra_cost.ldst, 
> serialize_insn_extra_cost_ldst);
> +  SERIALIZE_ARRAY_FIELD (insn_extra_cost_obj, "fp", insn_extra_cost.fp, 2, 
> serialize_insn_extra_cost_fp_element);
> +  SERIALIZE_OBJECT (insn_extra_cost_obj, "vect", insn_extra_cost.vect, 
> serialize_insn_extra_cost_vect);
> +
> +  return insn_extra_cost_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_addr_cost (const T &addr_cost)
> +{
> +  auto addr_cost_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_OBJECT (addr_cost_obj, "addr_scale_costs", 
> addr_cost.addr_scale_costs, serialize_addr_cost_addr_scale_costs);
> +  SERIALIZE_INTEGER_FIELD (addr_cost_obj, "pre_modify", 
> addr_cost.pre_modify);
> +  SERIALIZE_INTEGER_FIELD (addr_cost_obj, "post_modify", 
> addr_cost.post_modify);
> +  SERIALIZE_INTEGER_FIELD (addr_cost_obj, "post_modify_ld3_st3", 
> addr_cost.post_modify_ld3_st3);
> +  SERIALIZE_INTEGER_FIELD (addr_cost_obj, "post_modify_ld4_st4", 
> addr_cost.post_modify_ld4_st4);
> +  SERIALIZE_INTEGER_FIELD (addr_cost_obj, "register_offset", 
> addr_cost.register_offset);
> +  SERIALIZE_INTEGER_FIELD (addr_cost_obj, "register_sextend", 
> addr_cost.register_sextend);
> +  SERIALIZE_INTEGER_FIELD (addr_cost_obj, "register_zextend", 
> addr_cost.register_zextend);
> +  SERIALIZE_INTEGER_FIELD (addr_cost_obj, "imm_offset", 
> addr_cost.imm_offset);
> +
> +  return addr_cost_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_vec_costs_issue_info (const T &issue_info)
> +{
> +  auto issue_info_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_OBJECT (issue_info_obj, "scalar", issue_info.scalar, 
> serialize_vec_costs_issue_info_scalar);
> +  SERIALIZE_OBJECT (issue_info_obj, "advsimd", issue_info.advsimd, 
> serialize_vec_costs_issue_info_advsimd);
> +  SERIALIZE_OBJECT (issue_info_obj, "sve", issue_info.sve, 
> serialize_vec_costs_issue_info_sve);
> +
> +  return issue_info_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_vec_costs (const T &vec_costs)
> +{
> +  auto vec_costs_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_INTEGER_FIELD (vec_costs_obj, "scalar_int_stmt_cost", 
> vec_costs.scalar_int_stmt_cost);
> +  SERIALIZE_INTEGER_FIELD (vec_costs_obj, "scalar_fp_stmt_cost", 
> vec_costs.scalar_fp_stmt_cost);
> +  SERIALIZE_INTEGER_FIELD (vec_costs_obj, "scalar_load_cost", 
> vec_costs.scalar_load_cost);
> +  SERIALIZE_INTEGER_FIELD (vec_costs_obj, "scalar_store_cost", 
> vec_costs.scalar_store_cost);
> +  SERIALIZE_INTEGER_FIELD (vec_costs_obj, "cond_taken_branch_cost", 
> vec_costs.cond_taken_branch_cost);
> +  SERIALIZE_INTEGER_FIELD (vec_costs_obj, "cond_not_taken_branch_cost", 
> vec_costs.cond_not_taken_branch_cost);
> +  SERIALIZE_OBJECT (vec_costs_obj, "advsimd", vec_costs.advsimd, 
> serialize_vec_costs_advsimd);
> +  SERIALIZE_OBJECT (vec_costs_obj, "sve", vec_costs.sve, 
> serialize_vec_costs_sve);
> +  SERIALIZE_OBJECT (vec_costs_obj, "issue_info", vec_costs.issue_info, 
> serialize_vec_costs_issue_info);
> +
> +  return vec_costs_obj;
> +}
> +
> +template <typename T>
> +static std::unique_ptr<json::object>
> +serialize_tunings (const T &tunings)
> +{
> +  auto tunings_obj = std::make_unique<json::object> ();
> +
> +  SERIALIZE_OBJECT (tunings_obj, "insn_extra_cost", tunings.insn_extra_cost, 
> serialize_insn_extra_cost);
> +  SERIALIZE_OBJECT (tunings_obj, "addr_cost", tunings.addr_cost, 
> serialize_addr_cost);
> +  SERIALIZE_OBJECT (tunings_obj, "regmove_cost", tunings.regmove_cost, 
> serialize_regmove_cost);
> +  SERIALIZE_OBJECT (tunings_obj, "vec_costs", tunings.vec_costs, 
> serialize_vec_costs);
> +  SERIALIZE_OBJECT (tunings_obj, "branch_costs", tunings.branch_costs, 
> serialize_branch_costs);
> +  SERIALIZE_OBJECT (tunings_obj, "approx_modes", tunings.approx_modes, 
> serialize_approx_modes);
> +  SERIALIZE_INTEGER_FIELD (tunings_obj, "sve_width", tunings.sve_width);
> +  SERIALIZE_OBJECT (tunings_obj, "memmov_cost", tunings.memmov_cost, 
> serialize_memmov_cost);
> +  SERIALIZE_INTEGER_FIELD (tunings_obj, "issue_rate", tunings.issue_rate);
> +  SERIALIZE_INTEGER_FIELD (tunings_obj, "fusible_ops", tunings.fusible_ops);
> +  SERIALIZE_STRING_FIELD (tunings_obj, "function_align", 
> tunings.function_align);
> +  SERIALIZE_STRING_FIELD (tunings_obj, "jump_align", tunings.jump_align);
> +  SERIALIZE_STRING_FIELD (tunings_obj, "loop_align", tunings.loop_align);
> +  SERIALIZE_INTEGER_FIELD (tunings_obj, "int_reassoc_width", 
> tunings.int_reassoc_width);
> +  SERIALIZE_INTEGER_FIELD (tunings_obj, "fp_reassoc_width", 
> tunings.fp_reassoc_width);
> +  SERIALIZE_INTEGER_FIELD (tunings_obj, "fma_reassoc_width", 
> tunings.fma_reassoc_width);
> +  SERIALIZE_INTEGER_FIELD (tunings_obj, "vec_reassoc_width", 
> tunings.vec_reassoc_width);
> +  SERIALIZE_INTEGER_FIELD (tunings_obj, "min_div_recip_mul_sf", 
> tunings.min_div_recip_mul_sf);
> +  SERIALIZE_INTEGER_FIELD (tunings_obj, "min_div_recip_mul_df", 
> tunings.min_div_recip_mul_df);
> +  SERIALIZE_INTEGER_FIELD (tunings_obj, "max_case_values", 
> tunings.max_case_values);
> +  SERIALIZE_ENUM_FIELD (tunings_obj, "autoprefetcher_model", 
> tunings.autoprefetcher_model, autoprefetcher_model_mappings);
> +  SERIALIZE_INTEGER_FIELD (tunings_obj, "extra_tuning_flags", 
> tunings.extra_tuning_flags);
> +  SERIALIZE_OBJECT (tunings_obj, "prefetch", tunings.prefetch, 
> serialize_prefetch);
> +  SERIALIZE_ENUM_FIELD (tunings_obj, "ldp_policy_model", 
> tunings.ldp_policy_model, ldp_policy_model_mappings);
> +  SERIALIZE_ENUM_FIELD (tunings_obj, "stp_policy_model", 
> tunings.stp_policy_model, stp_policy_model_mappings);
> +
> +  return tunings_obj;
> +}
> diff --git a/gcc/config/aarch64/aarch64-json-tunings-printer.cc 
> b/gcc/config/aarch64/aarch64-json-tunings-printer.cc
> index 926829886a4..9b0da3ec303 100644
> --- a/gcc/config/aarch64/aarch64-json-tunings-printer.cc
> +++ b/gcc/config/aarch64/aarch64-json-tunings-printer.cc
> @@ -122,513 +122,8 @@ serialize_enum (EnumType enum_value, const 
> enum_mapping<EnumType> *mappings,
>    return mappings[0].name;
>  }
>  
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_insn_extra_cost_alu (const T &alu)
> -{
> -  auto alu_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_INTEGER_FIELD (alu_obj, "arith", alu.arith);
> -  SERIALIZE_INTEGER_FIELD (alu_obj, "logical", alu.logical);
> -  SERIALIZE_INTEGER_FIELD (alu_obj, "shift", alu.shift);
> -  SERIALIZE_INTEGER_FIELD (alu_obj, "shift_reg", alu.shift_reg);
> -  SERIALIZE_INTEGER_FIELD (alu_obj, "arith_shift", alu.arith_shift);
> -  SERIALIZE_INTEGER_FIELD (alu_obj, "arith_shift_reg", alu.arith_shift_reg);
> -  SERIALIZE_INTEGER_FIELD (alu_obj, "log_shift", alu.log_shift);
> -  SERIALIZE_INTEGER_FIELD (alu_obj, "log_shift_reg", alu.log_shift_reg);
> -  SERIALIZE_INTEGER_FIELD (alu_obj, "extend", alu.extend);
> -  SERIALIZE_INTEGER_FIELD (alu_obj, "extend_arith", alu.extend_arith);
> -  SERIALIZE_INTEGER_FIELD (alu_obj, "bfi", alu.bfi);
> -  SERIALIZE_INTEGER_FIELD (alu_obj, "bfx", alu.bfx);
> -  SERIALIZE_INTEGER_FIELD (alu_obj, "clz", alu.clz);
> -  SERIALIZE_INTEGER_FIELD (alu_obj, "rev", alu.rev);
> -  SERIALIZE_INTEGER_FIELD (alu_obj, "non_exec", alu.non_exec);
> -  SERIALIZE_BOOLEAN_FIELD (alu_obj, "non_exec_costs_exec",
> -                        alu.non_exec_costs_exec);
> -
> -  return alu_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_insn_extra_cost_mult_element (const T &mult_element)
> -{
> -  auto mult_element_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_INTEGER_FIELD (mult_element_obj, "simple", mult_element.simple);
> -  SERIALIZE_INTEGER_FIELD (mult_element_obj, "flag_setting",
> -                        mult_element.flag_setting);
> -  SERIALIZE_INTEGER_FIELD (mult_element_obj, "extend", mult_element.extend);
> -  SERIALIZE_INTEGER_FIELD (mult_element_obj, "add", mult_element.add);
> -  SERIALIZE_INTEGER_FIELD (mult_element_obj, "extend_add",
> -                        mult_element.extend_add);
> -  SERIALIZE_INTEGER_FIELD (mult_element_obj, "idiv", mult_element.idiv);
> -
> -  return mult_element_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_insn_extra_cost_ldst (const T &ldst)
> -{
> -  auto ldst_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "load", ldst.load);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "load_sign_extend", 
> ldst.load_sign_extend);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "ldrd", ldst.ldrd);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "ldm_1st", ldst.ldm_1st);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "ldm_regs_per_insn_1st",
> -                        ldst.ldm_regs_per_insn_1st);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "ldm_regs_per_insn_subsequent",
> -                        ldst.ldm_regs_per_insn_subsequent);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "loadf", ldst.loadf);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "loadd", ldst.loadd);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "load_unaligned", ldst.load_unaligned);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "store", ldst.store);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "strd", ldst.strd);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "stm_1st", ldst.stm_1st);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "stm_regs_per_insn_1st",
> -                        ldst.stm_regs_per_insn_1st);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "stm_regs_per_insn_subsequent",
> -                        ldst.stm_regs_per_insn_subsequent);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "storef", ldst.storef);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "stored", ldst.stored);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "store_unaligned", 
> ldst.store_unaligned);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "loadv", ldst.loadv);
> -  SERIALIZE_INTEGER_FIELD (ldst_obj, "storev", ldst.storev);
> -
> -  return ldst_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_insn_extra_cost_fp_element (const T &fp_element)
> -{
> -  auto fp_element_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_INTEGER_FIELD (fp_element_obj, "div", fp_element.div);
> -  SERIALIZE_INTEGER_FIELD (fp_element_obj, "mult", fp_element.mult);
> -  SERIALIZE_INTEGER_FIELD (fp_element_obj, "mult_addsub",
> -                        fp_element.mult_addsub);
> -  SERIALIZE_INTEGER_FIELD (fp_element_obj, "fma", fp_element.fma);
> -  SERIALIZE_INTEGER_FIELD (fp_element_obj, "addsub", fp_element.addsub);
> -  SERIALIZE_INTEGER_FIELD (fp_element_obj, "fpconst", fp_element.fpconst);
> -  SERIALIZE_INTEGER_FIELD (fp_element_obj, "neg", fp_element.neg);
> -  SERIALIZE_INTEGER_FIELD (fp_element_obj, "compare", fp_element.compare);
> -  SERIALIZE_INTEGER_FIELD (fp_element_obj, "widen", fp_element.widen);
> -  SERIALIZE_INTEGER_FIELD (fp_element_obj, "narrow", fp_element.narrow);
> -  SERIALIZE_INTEGER_FIELD (fp_element_obj, "toint", fp_element.toint);
> -  SERIALIZE_INTEGER_FIELD (fp_element_obj, "fromint", fp_element.fromint);
> -  SERIALIZE_INTEGER_FIELD (fp_element_obj, "roundint", fp_element.roundint);
> -
> -  return fp_element_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_insn_extra_cost_vect (const T &vect)
> -{
> -  auto vect_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_INTEGER_FIELD (vect_obj, "alu", vect.alu);
> -  SERIALIZE_INTEGER_FIELD (vect_obj, "mult", vect.mult);
> -  SERIALIZE_INTEGER_FIELD (vect_obj, "movi", vect.movi);
> -  SERIALIZE_INTEGER_FIELD (vect_obj, "dup", vect.dup);
> -  SERIALIZE_INTEGER_FIELD (vect_obj, "extract", vect.extract);
> -
> -  return vect_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_addr_cost_addr_scale_costs (const T &addr_scale_costs)
> -{
> -  auto addr_scale_costs_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_INTEGER_FIELD (addr_scale_costs_obj, "hi", addr_scale_costs.hi);
> -  SERIALIZE_INTEGER_FIELD (addr_scale_costs_obj, "si", addr_scale_costs.si);
> -  SERIALIZE_INTEGER_FIELD (addr_scale_costs_obj, "di", addr_scale_costs.di);
> -  SERIALIZE_INTEGER_FIELD (addr_scale_costs_obj, "ti", addr_scale_costs.ti);
> -
> -  return addr_scale_costs_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_regmove_cost (const T &regmove_cost)
> -{
> -  auto regmove_cost_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_INTEGER_FIELD (regmove_cost_obj, "GP2GP", regmove_cost.GP2GP);
> -  SERIALIZE_INTEGER_FIELD (regmove_cost_obj, "GP2FP", regmove_cost.GP2FP);
> -  SERIALIZE_INTEGER_FIELD (regmove_cost_obj, "FP2GP", regmove_cost.FP2GP);
> -  SERIALIZE_INTEGER_FIELD (regmove_cost_obj, "FP2FP", regmove_cost.FP2FP);
> -
> -  return regmove_cost_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_vec_costs_advsimd (const T &advsimd)
> -{
> -  auto advsimd_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "int_stmt_cost", 
> advsimd.int_stmt_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "fp_stmt_cost", 
> advsimd.fp_stmt_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "ld2_st2_permute_cost",
> -                        advsimd.ld2_st2_permute_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "ld3_st3_permute_cost",
> -                        advsimd.ld3_st3_permute_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "ld4_st4_permute_cost",
> -                        advsimd.ld4_st4_permute_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "permute_cost", 
> advsimd.permute_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "reduc_i8_cost", 
> advsimd.reduc_i8_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "reduc_i16_cost",
> -                        advsimd.reduc_i16_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "reduc_i32_cost",
> -                        advsimd.reduc_i32_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "reduc_i64_cost",
> -                        advsimd.reduc_i64_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "reduc_f16_cost",
> -                        advsimd.reduc_f16_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "reduc_f32_cost",
> -                        advsimd.reduc_f32_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "reduc_f64_cost",
> -                        advsimd.reduc_f64_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "store_elt_extra_cost",
> -                        advsimd.store_elt_extra_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "vec_to_scalar_cost",
> -                        advsimd.vec_to_scalar_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "scalar_to_vec_cost",
> -                        advsimd.scalar_to_vec_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "align_load_cost",
> -                        advsimd.align_load_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "unalign_load_cost",
> -                        advsimd.unalign_load_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "unalign_store_cost",
> -                        advsimd.unalign_store_cost);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "store_cost", advsimd.store_cost);
> -
> -  return advsimd_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_vec_costs_sve (const T &sve)
> -{
> -  auto sve_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "clast_cost", sve.clast_cost);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "fadda_f16_cost", sve.fadda_f16_cost);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "fadda_f32_cost", sve.fadda_f32_cost);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "fadda_f64_cost", sve.fadda_f64_cost);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "gather_load_x32_cost",
> -                        sve.gather_load_x32_cost);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "gather_load_x64_cost",
> -                        sve.gather_load_x64_cost);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "gather_load_x32_init_cost",
> -                        sve.gather_load_x32_init_cost);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "gather_load_x64_init_cost",
> -                        sve.gather_load_x64_init_cost);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "scatter_store_elt_cost",
> -                        sve.scatter_store_elt_cost);
> -
> -  return sve_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_vec_costs_issue_info_scalar (const T &scalar)
> -{
> -  auto scalar_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_INTEGER_FIELD (scalar_obj, "loads_stores_per_cycle",
> -                        scalar.loads_stores_per_cycle);
> -  SERIALIZE_INTEGER_FIELD (scalar_obj, "stores_per_cycle",
> -                        scalar.stores_per_cycle);
> -  SERIALIZE_INTEGER_FIELD (scalar_obj, "general_ops_per_cycle",
> -                        scalar.general_ops_per_cycle);
> -  SERIALIZE_INTEGER_FIELD (scalar_obj, "fp_simd_load_general_ops",
> -                        scalar.fp_simd_load_general_ops);
> -  SERIALIZE_INTEGER_FIELD (scalar_obj, "fp_simd_store_general_ops",
> -                        scalar.fp_simd_store_general_ops);
> -
> -  return scalar_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_vec_costs_issue_info_advsimd (const T &advsimd)
> -{
> -  auto advsimd_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "loads_stores_per_cycle",
> -                        advsimd.loads_stores_per_cycle);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "stores_per_cycle",
> -                        advsimd.stores_per_cycle);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "general_ops_per_cycle",
> -                        advsimd.general_ops_per_cycle);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "fp_simd_load_general_ops",
> -                        advsimd.fp_simd_load_general_ops);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "fp_simd_store_general_ops",
> -                        advsimd.fp_simd_store_general_ops);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "ld2_st2_general_ops",
> -                        advsimd.ld2_st2_general_ops);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "ld3_st3_general_ops",
> -                        advsimd.ld3_st3_general_ops);
> -  SERIALIZE_INTEGER_FIELD (advsimd_obj, "ld4_st4_general_ops",
> -                        advsimd.ld4_st4_general_ops);
> -
> -  return advsimd_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_vec_costs_issue_info_sve (const T &sve)
> -{
> -  auto sve_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "loads_stores_per_cycle",
> -                        sve.loads_stores_per_cycle);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "stores_per_cycle", 
> sve.stores_per_cycle);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "general_ops_per_cycle",
> -                        sve.general_ops_per_cycle);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "fp_simd_load_general_ops",
> -                        sve.fp_simd_load_general_ops);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "fp_simd_store_general_ops",
> -                        sve.fp_simd_store_general_ops);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "ld2_st2_general_ops",
> -                        sve.ld2_st2_general_ops);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "ld3_st3_general_ops",
> -                        sve.ld3_st3_general_ops);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "ld4_st4_general_ops",
> -                        sve.ld4_st4_general_ops);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "pred_ops_per_cycle",
> -                        sve.pred_ops_per_cycle);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "while_pred_ops", sve.while_pred_ops);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "int_cmp_pred_ops", 
> sve.int_cmp_pred_ops);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "fp_cmp_pred_ops", sve.fp_cmp_pred_ops);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "gather_scatter_pair_general_ops",
> -                        sve.gather_scatter_pair_general_ops);
> -  SERIALIZE_INTEGER_FIELD (sve_obj, "gather_scatter_pair_pred_ops",
> -                        sve.gather_scatter_pair_pred_ops);
> -
> -  return sve_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_branch_costs (const T &branch_costs)
> -{
> -  auto branch_costs_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_INTEGER_FIELD (branch_costs_obj, "predictable",
> -                        branch_costs.predictable);
> -  SERIALIZE_INTEGER_FIELD (branch_costs_obj, "unpredictable",
> -                        branch_costs.unpredictable);
> -
> -  return branch_costs_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_approx_modes (const T &approx_modes)
> -{
> -  auto approx_modes_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_INTEGER_FIELD (approx_modes_obj, "division", 
> approx_modes.division);
> -  SERIALIZE_INTEGER_FIELD (approx_modes_obj, "sqrt", approx_modes.sqrt);
> -  SERIALIZE_INTEGER_FIELD (approx_modes_obj, "recip_sqrt",
> -                        approx_modes.recip_sqrt);
> -
> -  return approx_modes_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_memmov_cost (const T &memmov_cost)
> -{
> -  auto memmov_cost_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_INTEGER_FIELD (memmov_cost_obj, "load_int", 
> memmov_cost.load_int);
> -  SERIALIZE_INTEGER_FIELD (memmov_cost_obj, "store_int", 
> memmov_cost.store_int);
> -  SERIALIZE_INTEGER_FIELD (memmov_cost_obj, "load_fp", memmov_cost.load_fp);
> -  SERIALIZE_INTEGER_FIELD (memmov_cost_obj, "store_fp", 
> memmov_cost.store_fp);
> -  SERIALIZE_INTEGER_FIELD (memmov_cost_obj, "load_pred", 
> memmov_cost.load_pred);
> -  SERIALIZE_INTEGER_FIELD (memmov_cost_obj, "store_pred",
> -                        memmov_cost.store_pred);
> -
> -  return memmov_cost_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_prefetch (const T &prefetch)
> -{
> -  auto prefetch_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_INTEGER_FIELD (prefetch_obj, "num_slots", prefetch.num_slots);
> -  SERIALIZE_INTEGER_FIELD (prefetch_obj, "l1_cache_size",
> -                        prefetch.l1_cache_size);
> -  SERIALIZE_INTEGER_FIELD (prefetch_obj, "l1_cache_line_size",
> -                        prefetch.l1_cache_line_size);
> -  SERIALIZE_INTEGER_FIELD (prefetch_obj, "l2_cache_size",
> -                        prefetch.l2_cache_size);
> -  SERIALIZE_BOOLEAN_FIELD (prefetch_obj, "prefetch_dynamic_strides",
> -                        prefetch.prefetch_dynamic_strides);
> -  SERIALIZE_INTEGER_FIELD (prefetch_obj, "minimum_stride",
> -                        prefetch.minimum_stride);
> -  SERIALIZE_INTEGER_FIELD (prefetch_obj, "default_opt_level",
> -                        prefetch.default_opt_level);
> -
> -  return prefetch_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_insn_extra_cost (const T &insn_extra_cost)
> -{
> -  auto insn_extra_cost_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_OBJECT (insn_extra_cost_obj, "alu", insn_extra_cost.alu,
> -                 serialize_insn_extra_cost_alu);
> -  SERIALIZE_ARRAY_FIELD (insn_extra_cost_obj, "mult", insn_extra_cost.mult, 
> 2,
> -                      serialize_insn_extra_cost_mult_element);
> -  SERIALIZE_OBJECT (insn_extra_cost_obj, "ldst", insn_extra_cost.ldst,
> -                 serialize_insn_extra_cost_ldst);
> -  SERIALIZE_ARRAY_FIELD (insn_extra_cost_obj, "fp", insn_extra_cost.fp, 2,
> -                      serialize_insn_extra_cost_fp_element);
> -  SERIALIZE_OBJECT (insn_extra_cost_obj, "vect", insn_extra_cost.vect,
> -                 serialize_insn_extra_cost_vect);
> -
> -  return insn_extra_cost_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_addr_cost (const T &addr_cost)
> -{
> -  auto addr_cost_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_OBJECT (addr_cost_obj, "addr_scale_costs",
> -                 addr_cost.addr_scale_costs,
> -                 serialize_addr_cost_addr_scale_costs);
> -  SERIALIZE_INTEGER_FIELD (addr_cost_obj, "pre_modify", 
> addr_cost.pre_modify);
> -  SERIALIZE_INTEGER_FIELD (addr_cost_obj, "post_modify", 
> addr_cost.post_modify);
> -  SERIALIZE_INTEGER_FIELD (addr_cost_obj, "post_modify_ld3_st3",
> -                        addr_cost.post_modify_ld3_st3);
> -  SERIALIZE_INTEGER_FIELD (addr_cost_obj, "post_modify_ld4_st4",
> -                        addr_cost.post_modify_ld4_st4);
> -  SERIALIZE_INTEGER_FIELD (addr_cost_obj, "register_offset",
> -                        addr_cost.register_offset);
> -  SERIALIZE_INTEGER_FIELD (addr_cost_obj, "register_sextend",
> -                        addr_cost.register_sextend);
> -  SERIALIZE_INTEGER_FIELD (addr_cost_obj, "register_zextend",
> -                        addr_cost.register_zextend);
> -  SERIALIZE_INTEGER_FIELD (addr_cost_obj, "imm_offset", 
> addr_cost.imm_offset);
> -
> -  return addr_cost_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_vec_costs_issue_info (const T &issue_info)
> -{
> -  auto issue_info_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_OBJECT (issue_info_obj, "scalar", issue_info.scalar,
> -                 serialize_vec_costs_issue_info_scalar);
> -  SERIALIZE_OBJECT (issue_info_obj, "advsimd", issue_info.advsimd,
> -                 serialize_vec_costs_issue_info_advsimd);
> -  SERIALIZE_OBJECT (issue_info_obj, "sve", issue_info.sve,
> -                 serialize_vec_costs_issue_info_sve);
> -
> -  return issue_info_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_vec_costs (const T &vec_costs)
> -{
> -  auto vec_costs_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_INTEGER_FIELD (vec_costs_obj, "scalar_int_stmt_cost",
> -                        vec_costs.scalar_int_stmt_cost);
> -  SERIALIZE_INTEGER_FIELD (vec_costs_obj, "scalar_fp_stmt_cost",
> -                        vec_costs.scalar_fp_stmt_cost);
> -  SERIALIZE_INTEGER_FIELD (vec_costs_obj, "scalar_load_cost",
> -                        vec_costs.scalar_load_cost);
> -  SERIALIZE_INTEGER_FIELD (vec_costs_obj, "scalar_store_cost",
> -                        vec_costs.scalar_store_cost);
> -  SERIALIZE_INTEGER_FIELD (vec_costs_obj, "cond_taken_branch_cost",
> -                        vec_costs.cond_taken_branch_cost);
> -  SERIALIZE_INTEGER_FIELD (vec_costs_obj, "cond_not_taken_branch_cost",
> -                        vec_costs.cond_not_taken_branch_cost);
> -  SERIALIZE_OBJECT (vec_costs_obj, "advsimd", vec_costs.advsimd,
> -                 serialize_vec_costs_advsimd);
> -  SERIALIZE_OBJECT (vec_costs_obj, "sve", vec_costs.sve,
> -                 serialize_vec_costs_sve);
> -  SERIALIZE_OBJECT (vec_costs_obj, "issue_info", vec_costs.issue_info,
> -                 serialize_vec_costs_issue_info);
> -
> -  return vec_costs_obj;
> -}
> -
> -template <typename T>
> -static std::unique_ptr<json::object>
> -serialize_tunings (const T &tunings)
> -{
> -  auto tunings_obj = std::make_unique<json::object> ();
> -
> -  SERIALIZE_OBJECT (tunings_obj, "insn_extra_cost", tunings.insn_extra_cost,
> -                 serialize_insn_extra_cost);
> -  SERIALIZE_OBJECT (tunings_obj, "addr_cost", tunings.addr_cost,
> -                 serialize_addr_cost);
> -  SERIALIZE_OBJECT (tunings_obj, "regmove_cost", tunings.regmove_cost,
> -                 serialize_regmove_cost);
> -  SERIALIZE_OBJECT (tunings_obj, "vec_costs", tunings.vec_costs,
> -                 serialize_vec_costs);
> -  SERIALIZE_OBJECT (tunings_obj, "branch_costs", tunings.branch_costs,
> -                 serialize_branch_costs);
> -  SERIALIZE_OBJECT (tunings_obj, "approx_modes", tunings.approx_modes,
> -                 serialize_approx_modes);
> -  SERIALIZE_INTEGER_FIELD (tunings_obj, "sve_width", tunings.sve_width);
> -  SERIALIZE_OBJECT (tunings_obj, "memmov_cost", tunings.memmov_cost,
> -                 serialize_memmov_cost);
> -  SERIALIZE_INTEGER_FIELD (tunings_obj, "issue_rate", tunings.issue_rate);
> -  SERIALIZE_INTEGER_FIELD (tunings_obj, "fusible_ops", tunings.fusible_ops);
> -  SERIALIZE_STRING_FIELD (tunings_obj, "function_align",
> -                       tunings.function_align);
> -  SERIALIZE_STRING_FIELD (tunings_obj, "jump_align", tunings.jump_align);
> -  SERIALIZE_STRING_FIELD (tunings_obj, "loop_align", tunings.loop_align);
> -  SERIALIZE_INTEGER_FIELD (tunings_obj, "int_reassoc_width",
> -                        tunings.int_reassoc_width);
> -  SERIALIZE_INTEGER_FIELD (tunings_obj, "fp_reassoc_width",
> -                        tunings.fp_reassoc_width);
> -  SERIALIZE_INTEGER_FIELD (tunings_obj, "fma_reassoc_width",
> -                        tunings.fma_reassoc_width);
> -  SERIALIZE_INTEGER_FIELD (tunings_obj, "vec_reassoc_width",
> -                        tunings.vec_reassoc_width);
> -  SERIALIZE_INTEGER_FIELD (tunings_obj, "min_div_recip_mul_sf",
> -                        tunings.min_div_recip_mul_sf);
> -  SERIALIZE_INTEGER_FIELD (tunings_obj, "min_div_recip_mul_df",
> -                        tunings.min_div_recip_mul_df);
> -  SERIALIZE_INTEGER_FIELD (tunings_obj, "max_case_values",
> -                        tunings.max_case_values);
> -  SERIALIZE_ENUM_FIELD (tunings_obj, "autoprefetcher_model",
> -                     tunings.autoprefetcher_model,
> -                     autoprefetcher_model_mappings);
> -  SERIALIZE_INTEGER_FIELD (tunings_obj, "extra_tuning_flags",
> -                        tunings.extra_tuning_flags);
> -  SERIALIZE_OBJECT (tunings_obj, "prefetch", tunings.prefetch,
> -                 serialize_prefetch);
> -  SERIALIZE_ENUM_FIELD (tunings_obj, "ldp_policy_model",
> -                     tunings.ldp_policy_model, ldp_policy_model_mappings);
> -  SERIALIZE_ENUM_FIELD (tunings_obj, "stp_policy_model",
> -                     tunings.stp_policy_model, stp_policy_model_mappings);
> -
> -  return tunings_obj;
> -}
> +/* Include auto-generated printing routines.  */
> +#include "aarch64-json-tunings-printer-generated.inc"
>  
>  /* Print tune_params structure to JSON file.  */
>  void
> diff --git a/gcc/config/aarch64/t-aarch64 b/gcc/config/aarch64/t-aarch64
> index 9f285376e79..83c9134fec2 100644
> --- a/gcc/config/aarch64/t-aarch64
> +++ b/gcc/config/aarch64/t-aarch64
> @@ -212,6 +212,7 @@ aarch64-json-tunings-printer.o: 
> $(srcdir)/config/aarch64/aarch64-json-tunings-pr
>      $(CONFIG_H) $(SYSTEM_H) $(CORETYPES_H) $(TM_H) $(DIAGNOSTIC_CORE_H) \
>      $(PRETTY_PRINT_H) json.h \
>      $(srcdir)/config/aarch64/aarch64-json-tunings-printer.h \
> +    $(srcdir)/config/aarch64/aarch64-json-tunings-printer-generated.inc \
>      $(srcdir)/config/aarch64/aarch64-protos.h \
>      $(srcdir)/config/arm/aarch-common-protos.h
>       $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
> @@ -222,6 +223,7 @@ aarch64-json-tunings-parser.o: 
> $(srcdir)/config/aarch64/aarch64-json-tunings-par
>      json-parsing.h \
>      $(srcdir)/config/aarch64/aarch64-json-schema.h \
>      $(srcdir)/config/aarch64/aarch64-json-tunings-parser.h \
> +    $(srcdir)/config/aarch64/aarch64-json-tunings-parser-generated.inc \
>      $(srcdir)/config/aarch64/aarch64-protos.h \
>      $(srcdir)/config/arm/aarch-common-protos.h
>       $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \

Reply via email to