> On 14 Feb 2026, at 9:22 PM, David Malcolm <[email protected]> wrote: > > External email: Use caution opening links or attachments > > > Use json-diagnostic.{h,cc} to improve the diagnostics issued > for malformed and invalid JSON tuning inputs: report the > file/line/column and, if possible, the JSON Pointer of the > problematic input. > > Before > ------ > > $ ./xgcc -B. -S test.c -muser-provided-CPU=malformed.json > cc1: error: error parsing JSON data: expected ':'; got number > > $ ./xgcc -B. -S test.c -muser-provided-CPU=unsigned-3.json > cc1: warning: JSON tuning file does not contain version information; > compatibility cannot be verified > cc1: error: key ‘tune_params.sve_width’ value 5000000000 is out of range for > ‘uint’ type [0, 4294967295] > cc1: error: validation failed for the provided JSON data > > After > ----- > > $ ./xgcc -B. -S test.c -muser-provided-CPU=malformed.json > malformed.json:3:17: error: error parsing JSON data: expected ':'; got number > 3 | "sve_width" 128 > | ^~~ > > $ ./xgcc -B. -S test.c -muser-provided-CPU=unsigned-3.json > cc1: warning: JSON tuning file does not contain version information; > compatibility cannot be verified > unsigned-3.json: In JSON value ‘/tune_params/sve_width’ > unsigned-3.json:3:18: error: key ‘tune_params.sve_width’ value 5000000000 is > out of range for ‘uint’ type [0, 4294967295] > 3 | "sve_width": 5000000000 > | ^~~~~~~~~~ > cc1: error: validation failed for the provided JSON data
Hi Dave, Thanks a lot for doing this, it’s much cleaner now. FYI, I added a fix for sve_vec_cost missing its inherited fields, you will have to rebase and regenerate the files on top of that. Best, Soumya > > gcc/ChangeLog: > PR target/124094 > * config/aarch64/aarch64-generate-json-tuning-routines.py > (generate_field_code): Add "ctxt, " arg to function call when > operation is "parse". > (generate_function): Add "gcc_json_context &ctxt, " param to > function decl when operation is "parse". > * config/aarch64/aarch64-json-tunings-parser-generated.inc: > Regenerate, passing around a gcc_json_context &. > * config/aarch64/aarch64-json-tunings-parser.cc: Include > "json-diagnostic.h". > (WARNING_OPT) New macro. > (PARSE_INTEGER_FIELD): Add "ctxt" param and pass it around. > (PARSE_UNSIGNED_INTEGER_FIELD): Likewise. > (PARSE_BOOLEAN_FIELD): Likewise. > (PARSE_STRING_FIELD): Likewise. > (PARSE_OBJECT): Likewise. > (PARSE_ARRAY_FIELD): Likewise. > (PARSE_ENUM_FIELD): Likewise. > (parse_func_type): Likewise. > (parse_object_helper): Likewise. Use json_error rather than error. > (inform_about_wrong_kind_of_json_value): New. > (extract_string): Add "ctxt" param. Replace "warning" with a pair > of calls to json_warning and > inform_about_wrong_kind_of_json_value, tweaking wording > accordingly. > (extract_integer): Likewise. > (extract_unsigned_integer): Likewise. > (parse_enum_field): Likewise. > (validate_and_traverse): Replace "warning" and "error" with > "json_warning" and "json_error". > (check_version_compatibility): Use WARNING_OPT. Add > auto_diagnostic_group to group the error and note. > (aarch64_load_tuning_params_from_json_string): Add "js_filename" > param. Use gcc_json_context to capture location info. Use it > when reporting errors to get file/line/column info. Replace check > on root being non-null with assertion, as this is guaranteed if > error is non-null. Replace warning with json_warning. > (aarch64_load_tuning_params_from_json): Pass data_filename to > aarch64_load_tuning_params_from_json_string for use when reporting > diagnostics. > (selftest::test_json_integers): Add a placeholder filename. > (selftest::test_json_boolean): Likewise. > (selftest::test_json_strings): Likewise. > (selftest::test_json_enums): Likewise. > > gcc/testsuite/ChangeLog: > PR target/124094 > * gcc.target/aarch64/aarch64-json-tunings/boolean-2.c: Add options > -fdiagnostics-show-caret -fdiagnostics-show-line-numbers. Replace > dg-error with a pair of dg-regexps to verify that we report the > filename and JSON Pointer of where the error occurs, and then > the filename and location within the JSON file. Verify that we > quote and underline the pertinent part of the JSON file. > * gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c: Likewise. > * gcc.target/aarch64/aarch64-json-tunings/enum-2.c: Likewise. > * gcc.target/aarch64/aarch64-json-tunings/integer-2.c: Likewise. > * gcc.target/aarch64/aarch64-json-tunings/integer-3.c: Likewise. > * gcc.target/aarch64/aarch64-json-tunings/string-2.c: Likewise. > * gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c: Likewise. > * gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c: Likewise. > * gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c: Likewise. > * gcc.target/aarch64/aarch64-json-tunings/malformed.c: New test, > to verify behavior on a malformed JSON input file. > * gcc.target/aarch64/aarch64-json-tunings/malformed.json: New > test file. This is malformed JSON, due to a missing ':" between > key and value. > > Signed-off-by: David Malcolm <[email protected]> > --- > .../aarch64-generate-json-tuning-routines.py | 17 +- > .../aarch64-json-tunings-parser-generated.inc | 428 +++++++++--------- > .../aarch64/aarch64-json-tunings-parser.cc | 276 +++++++---- > .../aarch64/aarch64-json-tunings/boolean-2.c | 12 +- > .../aarch64-json-tunings/empty-brackets.c | 9 +- > .../aarch64/aarch64-json-tunings/enum-2.c | 19 +- > .../aarch64/aarch64-json-tunings/integer-2.c | 14 +- > .../aarch64/aarch64-json-tunings/integer-3.c | 13 +- > .../aarch64/aarch64-json-tunings/malformed.c | 11 + > .../aarch64-json-tunings/malformed.json | 5 + > .../aarch64/aarch64-json-tunings/string-2.c | 12 +- > .../aarch64-json-tunings/unidentified-key.c | 12 +- > .../aarch64/aarch64-json-tunings/unsigned-2.c | 10 +- > .../aarch64/aarch64-json-tunings/unsigned-3.c | 10 +- > 14 files changed, 517 insertions(+), 331 deletions(-) > create mode 100644 > gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.c > create mode 100644 > gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.json > > diff --git a/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py > b/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py > index a4f9e4ece71a3..9253cf58cdfa1 100755 > --- a/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py > +++ b/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py > @@ -85,15 +85,20 @@ def generate_field_code( > ) -> List[str]: > lines = [] > > + if operation == 'parse': > + ctxt = 'ctxt, ' > + else: > + ctxt = '' > + > if isinstance(value, str): > 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});' > + f'{indent}{macro} ({ctxt}{obj_name}, "{key}", > {struct_name}.{key}, {enum_mapping});' > ) > else: > - lines.append(f'{indent}{macro} ({obj_name}, "{key}", > {struct_name}.{key});') > + lines.append(f'{indent}{macro} ({ctxt}{obj_name}, "{key}", > {struct_name}.{key});') > > elif isinstance(value, dict): > # Nested object - find function name based on current context + key > @@ -102,7 +107,7 @@ def generate_field_code( > 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});' > + f'{indent}{macro_name} ({ctxt}{obj_name}, "{key}", > {struct_name}.{key}, {func_name});' > ) > > elif isinstance(value, list) and len(value) > 0: > @@ -117,11 +122,11 @@ def generate_field_code( > > if operation.lower() == "serialize": > lines.append( > - f'{indent}{macro_name} ({obj_name}, "{key}", > {struct_name}.{key}, ARRAY_SIZE ({struct_name}.{key}), {func_name});' > + f'{indent}{macro_name} ({ctxt}{obj_name}, "{key}", > {struct_name}.{key}, ARRAY_SIZE ({struct_name}.{key}), {func_name});' > ) > else: > lines.append( > - f'{indent}{macro_name} ({obj_name}, "{key}", > {struct_name}.{key}, {func_name});' > + f'{indent}{macro_name} ({ctxt}{obj_name}, "{key}", > {struct_name}.{key}, {func_name});' > ) > else: > raise ValueError(f"Arrays of non-object types are not yet > supported: {key}") > @@ -175,7 +180,7 @@ def generate_function( > > if operation.lower() == "parse": > lines.append("static void") > - lines.append(f"parse_{full_name} (const json::object *jo, T > &{local_name})") > + lines.append(f"parse_{full_name} (gcc_json_context &ctxt, const > json::object &jo, T &{local_name})") > lines.append("{") > > for key, value in schema.items(): > diff --git a/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc > b/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc > index 882d8f799755a..3908a4f1a3114 100644 > --- a/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc > +++ b/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc > @@ -38,319 +38,319 @@ static const enum_mapping<aarch64_ldp_stp_policy> > stp_policy_model_mappings[] = > > template <typename T> > static void > -parse_insn_extra_cost_alu (const json::object *jo, T &alu) > +parse_insn_extra_cost_alu (gcc_json_context &ctxt, 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); > + PARSE_INTEGER_FIELD (ctxt, jo, "arith", alu.arith); > + PARSE_INTEGER_FIELD (ctxt, jo, "logical", alu.logical); > + PARSE_INTEGER_FIELD (ctxt, jo, "shift", alu.shift); > + PARSE_INTEGER_FIELD (ctxt, jo, "shift_reg", alu.shift_reg); > + PARSE_INTEGER_FIELD (ctxt, jo, "arith_shift", alu.arith_shift); > + PARSE_INTEGER_FIELD (ctxt, jo, "arith_shift_reg", alu.arith_shift_reg); > + PARSE_INTEGER_FIELD (ctxt, jo, "log_shift", alu.log_shift); > + PARSE_INTEGER_FIELD (ctxt, jo, "log_shift_reg", alu.log_shift_reg); > + PARSE_INTEGER_FIELD (ctxt, jo, "extend", alu.extend); > + PARSE_INTEGER_FIELD (ctxt, jo, "extend_arith", alu.extend_arith); > + PARSE_INTEGER_FIELD (ctxt, jo, "bfi", alu.bfi); > + PARSE_INTEGER_FIELD (ctxt, jo, "bfx", alu.bfx); > + PARSE_INTEGER_FIELD (ctxt, jo, "clz", alu.clz); > + PARSE_INTEGER_FIELD (ctxt, jo, "rev", alu.rev); > + PARSE_INTEGER_FIELD (ctxt, jo, "non_exec", alu.non_exec); > + PARSE_BOOLEAN_FIELD (ctxt, 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_insn_extra_cost_mult_element (gcc_json_context &ctxt, 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); > + PARSE_INTEGER_FIELD (ctxt, jo, "simple", mult_element.simple); > + PARSE_INTEGER_FIELD (ctxt, jo, "flag_setting", mult_element.flag_setting); > + PARSE_INTEGER_FIELD (ctxt, jo, "extend", mult_element.extend); > + PARSE_INTEGER_FIELD (ctxt, jo, "add", mult_element.add); > + PARSE_INTEGER_FIELD (ctxt, jo, "extend_add", mult_element.extend_add); > + PARSE_INTEGER_FIELD (ctxt, jo, "idiv", mult_element.idiv); > } > > template <typename T> > static void > -parse_insn_extra_cost_ldst (const json::object *jo, T &ldst) > +parse_insn_extra_cost_ldst (gcc_json_context &ctxt, 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); > + PARSE_INTEGER_FIELD (ctxt, jo, "load", ldst.load); > + PARSE_INTEGER_FIELD (ctxt, jo, "load_sign_extend", ldst.load_sign_extend); > + PARSE_INTEGER_FIELD (ctxt, jo, "ldrd", ldst.ldrd); > + PARSE_INTEGER_FIELD (ctxt, jo, "ldm_1st", ldst.ldm_1st); > + PARSE_INTEGER_FIELD (ctxt, jo, "ldm_regs_per_insn_1st", > ldst.ldm_regs_per_insn_1st); > + PARSE_INTEGER_FIELD (ctxt, jo, "ldm_regs_per_insn_subsequent", > ldst.ldm_regs_per_insn_subsequent); > + PARSE_INTEGER_FIELD (ctxt, jo, "loadf", ldst.loadf); > + PARSE_INTEGER_FIELD (ctxt, jo, "loadd", ldst.loadd); > + PARSE_INTEGER_FIELD (ctxt, jo, "load_unaligned", ldst.load_unaligned); > + PARSE_INTEGER_FIELD (ctxt, jo, "store", ldst.store); > + PARSE_INTEGER_FIELD (ctxt, jo, "strd", ldst.strd); > + PARSE_INTEGER_FIELD (ctxt, jo, "stm_1st", ldst.stm_1st); > + PARSE_INTEGER_FIELD (ctxt, jo, "stm_regs_per_insn_1st", > ldst.stm_regs_per_insn_1st); > + PARSE_INTEGER_FIELD (ctxt, jo, "stm_regs_per_insn_subsequent", > ldst.stm_regs_per_insn_subsequent); > + PARSE_INTEGER_FIELD (ctxt, jo, "storef", ldst.storef); > + PARSE_INTEGER_FIELD (ctxt, jo, "stored", ldst.stored); > + PARSE_INTEGER_FIELD (ctxt, jo, "store_unaligned", ldst.store_unaligned); > + PARSE_INTEGER_FIELD (ctxt, jo, "loadv", ldst.loadv); > + PARSE_INTEGER_FIELD (ctxt, jo, "storev", ldst.storev); > } > > template <typename T> > static void > -parse_insn_extra_cost_fp_element (const json::object *jo, T &fp_element) > +parse_insn_extra_cost_fp_element (gcc_json_context &ctxt, 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); > + PARSE_INTEGER_FIELD (ctxt, jo, "div", fp_element.div); > + PARSE_INTEGER_FIELD (ctxt, jo, "mult", fp_element.mult); > + PARSE_INTEGER_FIELD (ctxt, jo, "mult_addsub", fp_element.mult_addsub); > + PARSE_INTEGER_FIELD (ctxt, jo, "fma", fp_element.fma); > + PARSE_INTEGER_FIELD (ctxt, jo, "addsub", fp_element.addsub); > + PARSE_INTEGER_FIELD (ctxt, jo, "fpconst", fp_element.fpconst); > + PARSE_INTEGER_FIELD (ctxt, jo, "neg", fp_element.neg); > + PARSE_INTEGER_FIELD (ctxt, jo, "compare", fp_element.compare); > + PARSE_INTEGER_FIELD (ctxt, jo, "widen", fp_element.widen); > + PARSE_INTEGER_FIELD (ctxt, jo, "narrow", fp_element.narrow); > + PARSE_INTEGER_FIELD (ctxt, jo, "toint", fp_element.toint); > + PARSE_INTEGER_FIELD (ctxt, jo, "fromint", fp_element.fromint); > + PARSE_INTEGER_FIELD (ctxt, jo, "roundint", fp_element.roundint); > } > > template <typename T> > static void > -parse_insn_extra_cost_vect (const json::object *jo, T &vect) > +parse_insn_extra_cost_vect (gcc_json_context &ctxt, 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); > + PARSE_INTEGER_FIELD (ctxt, jo, "alu", vect.alu); > + PARSE_INTEGER_FIELD (ctxt, jo, "mult", vect.mult); > + PARSE_INTEGER_FIELD (ctxt, jo, "movi", vect.movi); > + PARSE_INTEGER_FIELD (ctxt, jo, "dup", vect.dup); > + PARSE_INTEGER_FIELD (ctxt, jo, "extract", vect.extract); > } > > template <typename T> > static void > -parse_addr_cost_addr_scale_costs (const json::object *jo, T > &addr_scale_costs) > +parse_addr_cost_addr_scale_costs (gcc_json_context &ctxt, 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); > + PARSE_INTEGER_FIELD (ctxt, jo, "hi", addr_scale_costs.hi); > + PARSE_INTEGER_FIELD (ctxt, jo, "si", addr_scale_costs.si); > + PARSE_INTEGER_FIELD (ctxt, jo, "di", addr_scale_costs.di); > + PARSE_INTEGER_FIELD (ctxt, jo, "ti", addr_scale_costs.ti); > } > > template <typename T> > static void > -parse_regmove_cost (const json::object *jo, T ®move_cost) > +parse_regmove_cost (gcc_json_context &ctxt, const json::object &jo, T > ®move_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); > + PARSE_INTEGER_FIELD (ctxt, jo, "GP2GP", regmove_cost.GP2GP); > + PARSE_INTEGER_FIELD (ctxt, jo, "GP2FP", regmove_cost.GP2FP); > + PARSE_INTEGER_FIELD (ctxt, jo, "FP2GP", regmove_cost.FP2GP); > + PARSE_INTEGER_FIELD (ctxt, jo, "FP2FP", regmove_cost.FP2FP); > } > > template <typename T> > static void > -parse_vec_costs_advsimd (const json::object *jo, T &advsimd) > +parse_vec_costs_advsimd (gcc_json_context &ctxt, 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); > + PARSE_INTEGER_FIELD (ctxt, jo, "int_stmt_cost", advsimd.int_stmt_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "fp_stmt_cost", advsimd.fp_stmt_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "ld2_st2_permute_cost", > advsimd.ld2_st2_permute_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "ld3_st3_permute_cost", > advsimd.ld3_st3_permute_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "ld4_st4_permute_cost", > advsimd.ld4_st4_permute_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "permute_cost", advsimd.permute_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "reduc_i8_cost", advsimd.reduc_i8_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "reduc_i16_cost", advsimd.reduc_i16_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "reduc_i32_cost", advsimd.reduc_i32_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "reduc_i64_cost", advsimd.reduc_i64_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "reduc_f16_cost", advsimd.reduc_f16_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "reduc_f32_cost", advsimd.reduc_f32_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "reduc_f64_cost", advsimd.reduc_f64_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "store_elt_extra_cost", > advsimd.store_elt_extra_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "vec_to_scalar_cost", > advsimd.vec_to_scalar_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "scalar_to_vec_cost", > advsimd.scalar_to_vec_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "align_load_cost", advsimd.align_load_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "unalign_load_cost", > advsimd.unalign_load_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "unalign_store_cost", > advsimd.unalign_store_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "store_cost", advsimd.store_cost); > } > > template <typename T> > static void > -parse_vec_costs_sve (const json::object *jo, T &sve) > +parse_vec_costs_sve (gcc_json_context &ctxt, 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_UNSIGNED_INTEGER_FIELD (jo, "gather_load_x32_cost", > sve.gather_load_x32_cost); > - PARSE_UNSIGNED_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); > + PARSE_INTEGER_FIELD (ctxt, jo, "clast_cost", sve.clast_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "fadda_f16_cost", sve.fadda_f16_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "fadda_f32_cost", sve.fadda_f32_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "fadda_f64_cost", sve.fadda_f64_cost); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "gather_load_x32_cost", > sve.gather_load_x32_cost); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "gather_load_x64_cost", > sve.gather_load_x64_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "gather_load_x32_init_cost", > sve.gather_load_x32_init_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "gather_load_x64_init_cost", > sve.gather_load_x64_init_cost); > + PARSE_INTEGER_FIELD (ctxt, 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_vec_costs_issue_info_scalar (gcc_json_context &ctxt, const > json::object &jo, T &scalar) > { > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "loads_stores_per_cycle", > scalar.loads_stores_per_cycle); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "stores_per_cycle", > scalar.stores_per_cycle); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "general_ops_per_cycle", > scalar.general_ops_per_cycle); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_load_general_ops", > scalar.fp_simd_load_general_ops); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_store_general_ops", > scalar.fp_simd_store_general_ops); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "loads_stores_per_cycle", > scalar.loads_stores_per_cycle); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "stores_per_cycle", > scalar.stores_per_cycle); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "general_ops_per_cycle", > scalar.general_ops_per_cycle); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_simd_load_general_ops", > scalar.fp_simd_load_general_ops); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, 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_vec_costs_issue_info_advsimd (gcc_json_context &ctxt, const > json::object &jo, T &advsimd) > { > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "loads_stores_per_cycle", > advsimd.loads_stores_per_cycle); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "stores_per_cycle", > advsimd.stores_per_cycle); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "general_ops_per_cycle", > advsimd.general_ops_per_cycle); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_load_general_ops", > advsimd.fp_simd_load_general_ops); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_store_general_ops", > advsimd.fp_simd_store_general_ops); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld2_st2_general_ops", > advsimd.ld2_st2_general_ops); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld3_st3_general_ops", > advsimd.ld3_st3_general_ops); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld4_st4_general_ops", > advsimd.ld4_st4_general_ops); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "loads_stores_per_cycle", > advsimd.loads_stores_per_cycle); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "stores_per_cycle", > advsimd.stores_per_cycle); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "general_ops_per_cycle", > advsimd.general_ops_per_cycle); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_simd_load_general_ops", > advsimd.fp_simd_load_general_ops); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_simd_store_general_ops", > advsimd.fp_simd_store_general_ops); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "ld2_st2_general_ops", > advsimd.ld2_st2_general_ops); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "ld3_st3_general_ops", > advsimd.ld3_st3_general_ops); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, 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_vec_costs_issue_info_sve (gcc_json_context &ctxt, const json::object > &jo, T &sve) > { > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "loads_stores_per_cycle", > sve.loads_stores_per_cycle); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "stores_per_cycle", > sve.stores_per_cycle); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "general_ops_per_cycle", > sve.general_ops_per_cycle); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_load_general_ops", > sve.fp_simd_load_general_ops); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_store_general_ops", > sve.fp_simd_store_general_ops); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld2_st2_general_ops", > sve.ld2_st2_general_ops); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld3_st3_general_ops", > sve.ld3_st3_general_ops); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld4_st4_general_ops", > sve.ld4_st4_general_ops); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "pred_ops_per_cycle", > sve.pred_ops_per_cycle); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "while_pred_ops", sve.while_pred_ops); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "int_cmp_pred_ops", > sve.int_cmp_pred_ops); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_cmp_pred_ops", sve.fp_cmp_pred_ops); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "gather_scatter_pair_general_ops", > sve.gather_scatter_pair_general_ops); > - PARSE_UNSIGNED_INTEGER_FIELD (jo, "gather_scatter_pair_pred_ops", > sve.gather_scatter_pair_pred_ops); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "loads_stores_per_cycle", > sve.loads_stores_per_cycle); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "stores_per_cycle", > sve.stores_per_cycle); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "general_ops_per_cycle", > sve.general_ops_per_cycle); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_simd_load_general_ops", > sve.fp_simd_load_general_ops); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_simd_store_general_ops", > sve.fp_simd_store_general_ops); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "ld2_st2_general_ops", > sve.ld2_st2_general_ops); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "ld3_st3_general_ops", > sve.ld3_st3_general_ops); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "ld4_st4_general_ops", > sve.ld4_st4_general_ops); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "pred_ops_per_cycle", > sve.pred_ops_per_cycle); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "while_pred_ops", > sve.while_pred_ops); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "int_cmp_pred_ops", > sve.int_cmp_pred_ops); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_cmp_pred_ops", > sve.fp_cmp_pred_ops); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "gather_scatter_pair_general_ops", > sve.gather_scatter_pair_general_ops); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, 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_branch_costs (gcc_json_context &ctxt, const json::object &jo, T > &branch_costs) > { > - PARSE_INTEGER_FIELD (jo, "predictable", branch_costs.predictable); > - PARSE_INTEGER_FIELD (jo, "unpredictable", branch_costs.unpredictable); > - PARSE_INTEGER_FIELD (jo, "br_mispredict_factor", > branch_costs.br_mispredict_factor); > + PARSE_INTEGER_FIELD (ctxt, jo, "predictable", branch_costs.predictable); > + PARSE_INTEGER_FIELD (ctxt, jo, "unpredictable", > branch_costs.unpredictable); > + PARSE_INTEGER_FIELD (ctxt, jo, "br_mispredict_factor", > branch_costs.br_mispredict_factor); > } > > template <typename T> > static void > -parse_approx_modes (const json::object *jo, T &approx_modes) > +parse_approx_modes (gcc_json_context &ctxt, 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); > + PARSE_INTEGER_FIELD (ctxt, jo, "division", approx_modes.division); > + PARSE_INTEGER_FIELD (ctxt, jo, "sqrt", approx_modes.sqrt); > + PARSE_INTEGER_FIELD (ctxt, jo, "recip_sqrt", approx_modes.recip_sqrt); > } > > template <typename T> > static void > -parse_memmov_cost (const json::object *jo, T &memmov_cost) > +parse_memmov_cost (gcc_json_context &ctxt, 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); > + PARSE_INTEGER_FIELD (ctxt, jo, "load_int", memmov_cost.load_int); > + PARSE_INTEGER_FIELD (ctxt, jo, "store_int", memmov_cost.store_int); > + PARSE_INTEGER_FIELD (ctxt, jo, "load_fp", memmov_cost.load_fp); > + PARSE_INTEGER_FIELD (ctxt, jo, "store_fp", memmov_cost.store_fp); > + PARSE_INTEGER_FIELD (ctxt, jo, "load_pred", memmov_cost.load_pred); > + PARSE_INTEGER_FIELD (ctxt, jo, "store_pred", memmov_cost.store_pred); > } > > template <typename T> > static void > -parse_prefetch (const json::object *jo, T &prefetch) > +parse_prefetch (gcc_json_context &ctxt, 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); > + PARSE_INTEGER_FIELD (ctxt, jo, "num_slots", prefetch.num_slots); > + PARSE_INTEGER_FIELD (ctxt, jo, "l1_cache_size", prefetch.l1_cache_size); > + PARSE_INTEGER_FIELD (ctxt, jo, "l1_cache_line_size", > prefetch.l1_cache_line_size); > + PARSE_INTEGER_FIELD (ctxt, jo, "l2_cache_size", prefetch.l2_cache_size); > + PARSE_BOOLEAN_FIELD (ctxt, jo, "prefetch_dynamic_strides", > prefetch.prefetch_dynamic_strides); > + PARSE_INTEGER_FIELD (ctxt, jo, "minimum_stride", prefetch.minimum_stride); > + PARSE_INTEGER_FIELD (ctxt, 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_insn_extra_cost (gcc_json_context &ctxt, 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); > + PARSE_OBJECT (ctxt, jo, "alu", insn_extra_cost.alu, > parse_insn_extra_cost_alu); > + PARSE_ARRAY_FIELD (ctxt, jo, "mult", insn_extra_cost.mult, > parse_insn_extra_cost_mult_element); > + PARSE_OBJECT (ctxt, jo, "ldst", insn_extra_cost.ldst, > parse_insn_extra_cost_ldst); > + PARSE_ARRAY_FIELD (ctxt, jo, "fp", insn_extra_cost.fp, > parse_insn_extra_cost_fp_element); > + PARSE_OBJECT (ctxt, 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_addr_cost (gcc_json_context &ctxt, 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); > + PARSE_OBJECT (ctxt, jo, "addr_scale_costs", addr_cost.addr_scale_costs, > parse_addr_cost_addr_scale_costs); > + PARSE_INTEGER_FIELD (ctxt, jo, "pre_modify", addr_cost.pre_modify); > + PARSE_INTEGER_FIELD (ctxt, jo, "post_modify", addr_cost.post_modify); > + PARSE_INTEGER_FIELD (ctxt, jo, "post_modify_ld3_st3", > addr_cost.post_modify_ld3_st3); > + PARSE_INTEGER_FIELD (ctxt, jo, "post_modify_ld4_st4", > addr_cost.post_modify_ld4_st4); > + PARSE_INTEGER_FIELD (ctxt, jo, "register_offset", > addr_cost.register_offset); > + PARSE_INTEGER_FIELD (ctxt, jo, "register_sextend", > addr_cost.register_sextend); > + PARSE_INTEGER_FIELD (ctxt, jo, "register_zextend", > addr_cost.register_zextend); > + PARSE_INTEGER_FIELD (ctxt, 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_vec_costs_issue_info (gcc_json_context &ctxt, 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); > + PARSE_OBJECT (ctxt, jo, "scalar", issue_info.scalar, > parse_vec_costs_issue_info_scalar); > + PARSE_OBJECT (ctxt, jo, "advsimd", issue_info.advsimd, > parse_vec_costs_issue_info_advsimd); > + PARSE_OBJECT (ctxt, 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_vec_costs (gcc_json_context &ctxt, 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); > + PARSE_INTEGER_FIELD (ctxt, jo, "scalar_int_stmt_cost", > vec_costs.scalar_int_stmt_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "scalar_fp_stmt_cost", > vec_costs.scalar_fp_stmt_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "scalar_load_cost", > vec_costs.scalar_load_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "scalar_store_cost", > vec_costs.scalar_store_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "cond_taken_branch_cost", > vec_costs.cond_taken_branch_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "cond_not_taken_branch_cost", > vec_costs.cond_not_taken_branch_cost); > + PARSE_OBJECT (ctxt, jo, "advsimd", vec_costs.advsimd, > parse_vec_costs_advsimd); > + PARSE_OBJECT (ctxt, jo, "sve", vec_costs.sve, parse_vec_costs_sve); > + PARSE_OBJECT (ctxt, 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_tunings (gcc_json_context &ctxt, 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_UNSIGNED_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_UNSIGNED_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_UNSIGNED_INTEGER_FIELD (jo, "max_case_values", > tunings.max_case_values); > - PARSE_ENUM_FIELD (jo, "autoprefetcher_model", > tunings.autoprefetcher_model, autoprefetcher_model_mappings); > - PARSE_UNSIGNED_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); > + PARSE_OBJECT (ctxt, jo, "insn_extra_cost", tunings.insn_extra_cost, > parse_insn_extra_cost); > + PARSE_OBJECT (ctxt, jo, "addr_cost", tunings.addr_cost, parse_addr_cost); > + PARSE_OBJECT (ctxt, jo, "regmove_cost", tunings.regmove_cost, > parse_regmove_cost); > + PARSE_OBJECT (ctxt, jo, "vec_costs", tunings.vec_costs, parse_vec_costs); > + PARSE_OBJECT (ctxt, jo, "branch_costs", tunings.branch_costs, > parse_branch_costs); > + PARSE_OBJECT (ctxt, jo, "approx_modes", tunings.approx_modes, > parse_approx_modes); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "sve_width", tunings.sve_width); > + PARSE_OBJECT (ctxt, jo, "memmov_cost", tunings.memmov_cost, > parse_memmov_cost); > + PARSE_INTEGER_FIELD (ctxt, jo, "issue_rate", tunings.issue_rate); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fusible_ops", > tunings.fusible_ops); > + PARSE_STRING_FIELD (ctxt, jo, "function_align", tunings.function_align); > + PARSE_STRING_FIELD (ctxt, jo, "jump_align", tunings.jump_align); > + PARSE_STRING_FIELD (ctxt, jo, "loop_align", tunings.loop_align); > + PARSE_INTEGER_FIELD (ctxt, jo, "int_reassoc_width", > tunings.int_reassoc_width); > + PARSE_INTEGER_FIELD (ctxt, jo, "fp_reassoc_width", > tunings.fp_reassoc_width); > + PARSE_INTEGER_FIELD (ctxt, jo, "fma_reassoc_width", > tunings.fma_reassoc_width); > + PARSE_INTEGER_FIELD (ctxt, jo, "vec_reassoc_width", > tunings.vec_reassoc_width); > + PARSE_INTEGER_FIELD (ctxt, jo, "min_div_recip_mul_sf", > tunings.min_div_recip_mul_sf); > + PARSE_INTEGER_FIELD (ctxt, jo, "min_div_recip_mul_df", > tunings.min_div_recip_mul_df); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "max_case_values", > tunings.max_case_values); > + PARSE_ENUM_FIELD (ctxt, jo, "autoprefetcher_model", > tunings.autoprefetcher_model, autoprefetcher_model_mappings); > + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "extra_tuning_flags", > tunings.extra_tuning_flags); > + PARSE_OBJECT (ctxt, jo, "prefetch", tunings.prefetch, parse_prefetch); > + PARSE_ENUM_FIELD (ctxt, jo, "ldp_policy_model", tunings.ldp_policy_model, > ldp_policy_model_mappings); > + PARSE_ENUM_FIELD (ctxt, jo, "stp_policy_model", tunings.stp_policy_model, > stp_policy_model_mappings); > } > \ No newline at end of file > diff --git a/gcc/config/aarch64/aarch64-json-tunings-parser.cc > b/gcc/config/aarch64/aarch64-json-tunings-parser.cc > index 326d52e02d1ce..40a1cbb41cd71 100644 > --- a/gcc/config/aarch64/aarch64-json-tunings-parser.cc > +++ b/gcc/config/aarch64/aarch64-json-tunings-parser.cc > @@ -27,6 +27,7 @@ > #include "tm.h" > #include "diagnostic-core.h" > #include "json-parsing.h" > +#include "json-diagnostic.h" > #include "aarch64-json-schema.h" > #include "aarch64-json-tunings-parser.h" > #include "aarch64-protos.h" > @@ -34,45 +35,47 @@ > #include "selftest.h" > #include "version.h" > > -#define PARSE_INTEGER_FIELD(obj, key, member) > \ > +#define WARNING_OPT (0) > + > +#define PARSE_INTEGER_FIELD(ctxt, obj, key, member) > \ > { > \ > - const json::value *val = obj->get (key); > \ > + const json::value *val = obj.get (key); > \ > if (val) > \ > - member = extract_integer (val); > \ > + member = extract_integer (ctxt, *val, WARNING_OPT); > \ > } > > -#define PARSE_UNSIGNED_INTEGER_FIELD(obj, key, member) > \ > +#define PARSE_UNSIGNED_INTEGER_FIELD(ctxt, obj, key, member) > \ > { > \ > - const json::value *val = obj->get (key); > \ > + const json::value *val = obj.get (key); > \ > if (val) > \ > - member = extract_unsigned_integer (val); > \ > + member = extract_unsigned_integer (ctxt, *val, WARNING_OPT); > \ > } > > -#define PARSE_BOOLEAN_FIELD(obj, key, member) > \ > +#define PARSE_BOOLEAN_FIELD(ctxt, obj, key, member) > \ > { > \ > - const json::value *val = obj->get (key); > \ > + const json::value *val = obj.get (key); > \ > if (val) > \ > - member = extract_boolean (val); > \ > + member = extract_boolean (ctxt, *val, WARNING_OPT); > \ > } > > -#define PARSE_STRING_FIELD(obj, key, member) > \ > +#define PARSE_STRING_FIELD(ctxt, obj, key, member) > \ > { > \ > - const json::value *val = obj->get (key); > \ > + const json::value *val = obj.get (key); > \ > if (val) > \ > - member = extract_string (val); > \ > + member = extract_string (ctxt, *val, WARNING_OPT); > \ > } > > -#define PARSE_OBJECT(obj, key, member, parse_func) > \ > +#define PARSE_OBJECT(ctxt, obj, key, member, parse_func) > \ > { > \ > - const json::value *field_value = obj->get (key); > \ > + const json::value *field_value = obj.get (key); > \ > if (field_value) > \ > if (auto *field_obj = dyn_cast<const json::object *> (field_value)) > \ > - parse_object_helper (field_obj, (member), (parse_func)); > \ > + parse_object_helper (ctxt, *field_obj, (member), (parse_func)); > \ > } > > -#define PARSE_ARRAY_FIELD(obj, key, member, parse_func) > \ > +#define PARSE_ARRAY_FIELD(ctxt, obj, key, member, parse_func) > \ > { > \ > - const json::value *field_value = obj->get (key); > \ > + const json::value *field_value = obj.get (key); > \ > if (field_value) > \ > if (auto *field_array = dyn_cast<const json::array *> (field_value)) > \ > for (size_t i = 0; i < field_array->size (); ++i) > \ > @@ -80,34 +83,37 @@ > const json::value *elem = field_array->get (i); > \ > if (elem) > \ > if (auto *array_obj = dyn_cast<const json::object *> (elem)) > \ > - parse_func (array_obj, member[i]); > \ > + parse_func (ctxt, *array_obj, member[i]); > \ > } > \ > } > > -#define PARSE_ENUM_FIELD(obj, key, member, mappings) > \ > - parse_enum_field (obj, key, member, mappings, > \ > - sizeof (mappings) / sizeof (mappings[0])) > +#define PARSE_ENUM_FIELD(ctxt, obj, key, member, mappings) > \ > + parse_enum_field (ctxt, obj, key, member, mappings, > \ > + sizeof (mappings) / sizeof (mappings[0]), WARNING_OPT) > > /* Type alias for parse function pointer. */ > template <typename T> > using parse_func_type > - = void (*) (const json::object *, > + = void (*) (gcc_json_context &, > + const json::object &, > std::remove_const_t<std::remove_pointer_t<T>> &); > > /* Parse JSON object into non-pointer member type. */ > template <typename T> > static std::enable_if_t<!std::is_pointer<T>::value> > -parse_object_helper (const json::object *field_obj, T &member, > +parse_object_helper (gcc_json_context &ctxt, > + const json::object &field_obj, T &member, > parse_func_type<T> parse_func) > { > - parse_func (field_obj, member); > + parse_func (ctxt, field_obj, member); > } > > /* Parse JSON object into a const pointer member by creating a temp copy. */ > template <typename T> > static std::enable_if_t<std::is_pointer<T>::value > && std::is_const<std::remove_pointer_t<T>>::value> > -parse_object_helper (const json::object *field_obj, T &member, > +parse_object_helper (gcc_json_context &ctxt, > + const json::object &field_obj, T &member, > parse_func_type<T> parse_func) > { > if (!member) > @@ -120,67 +126,121 @@ parse_object_helper (const json::object *field_obj, T > &member, > static bool already_initialized = false; > if (already_initialized) > { > - error ("static storage conflict - multiple pointer members of the " > - "same type cannot be parsed"); > + json_error (ctxt, field_obj, > + "static storage conflict - multiple pointer members of " > + "the same type cannot be parsed"); > return; > } > already_initialized = true; > using NonConstType = std::remove_const_t<std::remove_pointer_t<T>>; > static NonConstType new_obj = *member; > - parse_func (field_obj, new_obj); > + parse_func (ctxt, field_obj, new_obj); > member = &new_obj; > } > > +/* Issue a note about the kind of json value we encountered. */ > + > +static void > +inform_about_wrong_kind_of_json_value (gcc_json_context &ctxt, > + const json::value &val) > +{ > + switch (val.get_kind ()) > + { > + default: > + gcc_unreachable (); > + case json::JSON_OBJECT: > + json_note (ctxt, val, "...but got an object instead"); > + break; > + case json::JSON_ARRAY: > + json_note (ctxt, val, "...but got an array instead"); > + break; > + case json::JSON_INTEGER: > + json_note (ctxt, val, "...but got an integer instead"); > + break; > + case json::JSON_FLOAT: > + json_note (ctxt, val, "...but got a floating-point value instead"); > + break; > + case json::JSON_STRING: > + json_note (ctxt, val, "...but got a string instead"); > + break; > + case json::JSON_TRUE: > + json_note (ctxt, val, "...but got %qs instead", "true"); > + break; > + case json::JSON_FALSE: > + json_note (ctxt, val, "...but got %qs instead", "false"); > + break; > + case json::JSON_NULL: > + json_note (ctxt, val, "...but got %qs instead", "null"); > + break; > + } > +} > + > /* Extract string value from JSON, returning allocated C string. */ > char * > -extract_string (const json::value *val) > +extract_string (gcc_json_context &ctxt, > + const json::value &val, > + diagnostics::option_id warning_opt) > { > - if (auto *string_val = dyn_cast<const json::string *> (val)) > + if (auto *string_val = dyn_cast<const json::string *> (&val)) > return xstrdup (string_val->get_string ()); > - warning (0, "expected a string but got something else or NULL"); > + auto_diagnostic_group d; > + if (json_warning (ctxt, val, warning_opt, "expected a string...")) > + inform_about_wrong_kind_of_json_value (ctxt, val); > return nullptr; > } > > /* Extract signed integer value from JSON. */ > int > -extract_integer (const json::value *val) > +extract_integer (gcc_json_context &ctxt, > + const json::value &val, > + diagnostics::option_id warning_opt) > { > - if (auto *int_val = dyn_cast<const json::integer_number *> (val)) > + if (auto *int_val = dyn_cast<const json::integer_number *> (&val)) > { > long value = int_val->get (); > gcc_assert (value >= INT_MIN && value <= INT_MAX); > return static_cast<int> (value); > } > - warning (0, "expected an integer value but got something else or NULL"); > + auto_diagnostic_group d; > + if (json_warning (ctxt, val, warning_opt, "expected an integer value...")) > + inform_about_wrong_kind_of_json_value (ctxt, val); > return 0; > } > > /* Extract unsigned integer value from JSON. */ > unsigned int > -extract_unsigned_integer (const json::value *val) > +extract_unsigned_integer (gcc_json_context &ctxt, > + const json::value &val, > + diagnostics::option_id warning_opt) > { > - if (auto *int_val = dyn_cast<const json::integer_number *> (val)) > + if (auto *int_val = dyn_cast<const json::integer_number *> (&val)) > { > long value = int_val->get (); > gcc_assert (value >= 0 && value <= UINT_MAX); > return static_cast<unsigned int> (value); > } > - warning (0, > - "expected an unsigned integer value but got something else or > NULL"); > + auto_diagnostic_group d; > + if (json_warning (ctxt, val, warning_opt, > + "expected an unsigned integer value...")) > + inform_about_wrong_kind_of_json_value (ctxt, val); > return 0; > } > > /* Extract boolean value from JSON literal. */ > bool > -extract_boolean (const json::value *val) > +extract_boolean (gcc_json_context &ctxt, > + const json::value &val, > + diagnostics::option_id warning_opt) > { > - if (auto *literal_val = dyn_cast<const json::literal *> (val)) > + if (auto *literal_val = dyn_cast<const json::literal *> (&val)) > { > json::kind kind = literal_val->get_kind (); > if (kind == json::JSON_TRUE || kind == json::JSON_FALSE) > return (kind == json::JSON_TRUE); > } > - warning (0, "expected a boolean value but got something else or NULL"); > + auto_diagnostic_group d; > + if (json_warning (ctxt, val, warning_opt, "expected a boolean value...")) > + inform_about_wrong_kind_of_json_value (ctxt, val); > return false; > } > > @@ -193,18 +253,21 @@ template <typename EnumType> struct enum_mapping > /* Parse JSON string field into enum value using string-to-enum mappings. */ > template <typename EnumType> > static void > -parse_enum_field (const json::object *jo, const std::string &key, > +parse_enum_field (gcc_json_context &ctxt, > + const json::object &jo, const std::string &key, > EnumType &enum_var, const enum_mapping<EnumType> *mappings, > - size_t num_mappings) > + size_t num_mappings, > + diagnostics::option_id warning_opt) > { > - const json::value *field_value = jo->get (key.c_str ()); > + const json::value *field_value = jo.get (key.c_str ()); > if (!field_value) > return; > > auto *string_val = dyn_cast<const json::string *> (field_value); > if (!string_val) > { > - warning (0, "expected string for enum field %s", key.c_str ()); > + json_warning (ctxt, *field_value, warning_opt, > + "expected string for enum field %s", key.c_str ()); > enum_var = mappings[0].value; > return; > } > @@ -219,8 +282,9 @@ parse_enum_field (const json::object *jo, const > std::string &key, > } > } > > - warning (0, "%s not recognized, defaulting to %qs", key.c_str (), > - mappings[0].name); > + json_warning (ctxt, *field_value, 0, > + "%s not recognized, defaulting to %qs", key.c_str (), > + mappings[0].name); > enum_var = mappings[0].value; > } > > @@ -230,7 +294,8 @@ parse_enum_field (const json::object *jo, const > std::string &key, > /* Validate the user provided JSON data against the present schema. > Checks for correct types, fields, and expected format. */ > static bool > -validate_and_traverse (const json::object *json_obj, > +validate_and_traverse (gcc_json_context &ctxt, > + const json::object *json_obj, > const json::object *schema_obj, > const std::string &parent_key = "") > { > @@ -244,8 +309,9 @@ validate_and_traverse (const json::object *json_obj, > const json::value *schema_value = schema_obj->get (key.c_str ()); > if (!schema_value) > { > - warning (0, "key %qs is not a tuning parameter, skipping", > - full_key.c_str ()); > + json_warning (ctxt, *json_value, WARNING_OPT, > + "key %qs is not a tuning parameter, skipping", > + full_key.c_str ()); > continue; > } > > @@ -253,13 +319,15 @@ validate_and_traverse (const json::object *json_obj, > { > if (auto *sub_json_obj = dyn_cast<const json::object *> (json_value)) > { > - if (!validate_and_traverse (sub_json_obj, sub_schema_obj, > + if (!validate_and_traverse (ctxt, sub_json_obj, sub_schema_obj, > full_key)) > return false; > } > else > { > - error ("key %qs expected to be an object", full_key.c_str ()); > + json_error (ctxt, *json_value, > + "key %qs expected to be an object", > + full_key.c_str ()); > return false; > } > } > @@ -267,7 +335,8 @@ validate_and_traverse (const json::object *json_obj, > { > if (json_value->get_kind () != json::JSON_ARRAY) > { > - error ("key %qs expected to be an array", full_key.c_str ()); > + json_error (ctxt, *json_value, > + "key %qs expected to be an array", full_key.c_str > ()); > return false; > } > } > @@ -280,8 +349,9 @@ validate_and_traverse (const json::object *json_obj, > { > if (json_value->get_kind () != json::JSON_INTEGER) > { > - error ("key %qs expected to be an integer", > - full_key.c_str ()); > + json_error (ctxt, *json_value, > + "key %qs expected to be an integer", > + full_key.c_str ()); > return false; > } > // Check if the value is valid for signed integer > @@ -291,9 +361,10 @@ validate_and_traverse (const json::object *json_obj, > long value = int_val->get (); > if (value > INT_MAX || value < INT_MIN) > { > - error ("key %qs value %ld is out of range for %<int%> " > - "type [%d, %d]", > - full_key.c_str (), value, INT_MIN, INT_MAX); > + json_error (ctxt, *json_value, > + "key %qs value %ld is out of range for " > + "%<int%> type [%d, %d]", > + full_key.c_str (), value, INT_MIN, INT_MAX); > return false; > } > } > @@ -302,8 +373,9 @@ validate_and_traverse (const json::object *json_obj, > { > if (json_value->get_kind () != json::JSON_INTEGER) > { > - error ("key %qs expected to be an unsigned integer", > - full_key.c_str ()); > + json_error (ctxt, *json_value, > + "key %qs expected to be an unsigned integer", > + full_key.c_str ()); > return false; > } > // Check if the value is valid for unsigned integer > @@ -313,9 +385,10 @@ validate_and_traverse (const json::object *json_obj, > long value = int_val->get (); > if (value < 0 || value > UINT_MAX) > { > - error ("key %qs value %ld is out of range for %<uint%> " > - "type [0, %u]", > - full_key.c_str (), value, UINT_MAX); > + json_error (ctxt, *json_value, > + "key %qs value %ld is out of range for " > + "%<uint%> type [0, %u]", > + full_key.c_str (), value, UINT_MAX); > return false; > } > } > @@ -324,7 +397,9 @@ validate_and_traverse (const json::object *json_obj, > { > if (json_value->get_kind () != json::JSON_STRING) > { > - error ("key %qs expected to be a string", full_key.c_str > ()); > + json_error (ctxt, *json_value, > + "key %qs expected to be a string", > + full_key.c_str ()); > return false; > } > } > @@ -333,8 +408,9 @@ validate_and_traverse (const json::object *json_obj, > if (json_value->get_kind () != json::JSON_TRUE > && json_value->get_kind () != json::JSON_FALSE) > { > - error ("key %qs expected to be a boolean (true/false)", > - full_key.c_str ()); > + json_error (ctxt, *json_value, > + "key %qs expected to be a boolean (true/false)", > + full_key.c_str ()); > return false; > } > } > @@ -342,20 +418,24 @@ validate_and_traverse (const json::object *json_obj, > { > if (json_value->get_kind () != json::JSON_STRING) > { > - error ("key %qs expected to be an enum (string)", > - full_key.c_str ()); > + json_error (ctxt, *json_value, > + "key %qs expected to be an enum (string)", > + full_key.c_str ()); > return false; > } > } > else > { > - error ("key %qs has unsupported type", full_key.c_str ()); > + json_error (ctxt, *json_value, > + "key %qs has unsupported type", full_key.c_str ()); > return false; > } > } > else > { > - error ("key %qs has unexpected format in schema", full_key.c_str > ()); > + json_error (ctxt, *json_value, > + "key %qs has unexpected format in schema", > + full_key.c_str ()); > return false; > } > } > @@ -413,13 +493,15 @@ check_version_compatibility (const json::object > *root_obj) > > if (json_gcc_major_version == -1) > { > - warning (0, "JSON tuning file does not contain version information; " > - "compatibility cannot be verified"); > + warning (WARNING_OPT, > + "JSON tuning file does not contain version information; " > + "compatibility cannot be verified"); > return true; > } > > if (json_gcc_major_version != GCC_major_version) > { > + auto_diagnostic_group d; > error ("JSON tuning file was created with GCC version %d " > "but current GCC version is %d", > json_gcc_major_version, GCC_major_version); > @@ -433,31 +515,32 @@ check_version_compatibility (const json::object > *root_obj) > > /* Main routine for setting up the parsing of JSON data. */ > static void > -aarch64_load_tuning_params_from_json_string (const char *json_string, > +aarch64_load_tuning_params_from_json_string (const char *js_filename, > + const char *json_string, > const char *schema_string, > struct tune_params *tune) > { > /* Try parsing the JSON string. */ > + gcc_json_context ctxt (js_filename); > json::parser_result_t data_result > = json::parse_utf8_string (strlen (json_string), json_string, true, > - nullptr); > + &ctxt); > > if (auto json_err = data_result.m_err.get ()) > { > - error ("error parsing JSON data: %s", json_err->get_msg ()); > + location_t js_loc = ctxt.make_location_for_range (json_err->get_range > ()); > + error_at (js_loc, "error parsing JSON data: %s", json_err->get_msg ()); > return; > } > > - const std::unique_ptr<json::value> &root = data_result.m_val; > - if (!root) > - { > - error ("JSON parsing returned null data"); > - return; > - } > - auto *root_obj = dyn_cast<const json::object *> (root.get ()); > + const json::value* root = data_result.m_val.get (); > + gcc_assert (root); > + > + auto *root_obj = dyn_cast<const json::object *> (root); > if (!root_obj) > { > - warning (0, "no JSON object found in the provided data"); > + json_warning (ctxt, *root, WARNING_OPT, > + "no JSON object found in the provided data"); > return; > } > > @@ -479,24 +562,26 @@ aarch64_load_tuning_params_from_json_string (const char > *json_string, > const json::value *tune_params_value = root_obj->get ("tune_params"); > if (!tune_params_value) > { > - warning (0, "key %<tune_params%> not found in JSON data"); > + json_warning (ctxt, *root_obj, WARNING_OPT, > + "key %<tune_params%> not found in JSON data"); > return; > } > > auto *jo = dyn_cast<const json::object *> (tune_params_value); > if (!jo) > { > - error ("key %<tune_params%> is not a JSON object"); > + json_error (ctxt, *tune_params_value, > + "key %<tune_params%> is not a JSON object"); > return; > } > > - if (!validate_and_traverse (root_obj, schema_obj)) > + if (!validate_and_traverse (ctxt, root_obj, schema_obj)) > { > error ("validation failed for the provided JSON data"); > return; > } > > - parse_tunings (jo, *tune); > + parse_tunings (ctxt, *jo, *tune); > return; > } > > @@ -511,8 +596,9 @@ aarch64_load_tuning_params_from_json (const char > *data_filename, > error ("cannot read JSON data in %s", data_filename); > return; > } > - aarch64_load_tuning_params_from_json_string ( > - (const char *) json_data->data (), schema_json, tune); > + aarch64_load_tuning_params_from_json_string > + (data_filename, > + (const char *) json_data->data (), schema_json, tune); > } > > #if CHECKING_P > @@ -536,7 +622,8 @@ test_json_integers () > > tune_params params; > > - aarch64_load_tuning_params_from_json_string (test_json, schema_json, > ¶ms); > + aarch64_load_tuning_params_from_json_string > + ("test.json", test_json, schema_json, ¶ms); > > ASSERT_EQ (params.sve_width, 256); > ASSERT_EQ (params.issue_rate, 4); > @@ -563,7 +650,8 @@ test_json_boolean () > tune_params params; > params.insn_extra_cost = &default_cost_table; > > - aarch64_load_tuning_params_from_json_string (test_json, schema_json, > ¶ms); > + aarch64_load_tuning_params_from_json_string > + ("test.json", test_json, schema_json, ¶ms); > > ASSERT_EQ (params.insn_extra_cost->alu.non_exec_costs_exec, false); > } > @@ -584,7 +672,8 @@ test_json_strings () > > tune_params params; > > - aarch64_load_tuning_params_from_json_string (test_json, schema_json, > ¶ms); > + aarch64_load_tuning_params_from_json_string > + ("test.json", test_json, schema_json, ¶ms); > > ASSERT_STREQ (params.function_align, "16"); > ASSERT_STREQ (params.jump_align, "2"); > @@ -607,7 +696,8 @@ test_json_enums () > > tune_params params; > > - aarch64_load_tuning_params_from_json_string (test_json, schema_json, > ¶ms); > + aarch64_load_tuning_params_from_json_string > + ("test.json", test_json, schema_json, ¶ms); > > ASSERT_EQ (params.autoprefetcher_model, tune_params::AUTOPREFETCHER_OFF); > ASSERT_EQ (params.ldp_policy_model, AARCH64_LDP_STP_POLICY_NEVER); > diff --git > a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/boolean-2.c > b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/boolean-2.c > index aef632f1d0423..0ed8f71b775d0 100644 > --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/boolean-2.c > +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/boolean-2.c > @@ -1,8 +1,16 @@ > /* { dg-do compile } */ > /* { dg-additional-options > "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/boolean-2.json > -fdump-tuning-model=temp.json" } */ > +/* { dg-additional-options "-fdiagnostics-show-caret > -fdiagnostics-show-line-numbers" } */ > > /* { dg-warning "JSON tuning file does not contain version information" "" { > target *-*-* } 0 } */ > -/* { dg-error "key .* expected to be a boolean" "" { target *-*-* } 0 } */ > + > +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/boolean-2.json: In > JSON value '/tune_params/insn_extra_cost/alu/non_exec_costs_exec'" } */ > +/* { dg-regexp > ".*gcc.target/aarch64/aarch64-json-tunings/boolean-2.json:5:32: error: key .* > expected to be a boolean \\\(true/false\\\)" } */ > +/* { dg-begin-multiline-output "" } > + 5 | "non_exec_costs_exec": 0 > + | ^ > + { dg-end-multiline-output "" } */ > + > /* { dg-error "validation failed for the provided JSON data" "" { target > *-*-* } 0 } */ > > -int main () {} > \ No newline at end of file > +int main () {} > diff --git > a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c > b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c > index 4df72dbaf7ab4..cbbe8afe760ec 100644 > --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c > +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c > @@ -1,7 +1,12 @@ > /* { dg-do compile } */ > /* { dg-additional-options > "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.json > -fdump-tuning-model=temp.json" } */ > +/* { dg-additional-options "-fdiagnostics-show-caret > -fdiagnostics-show-line-numbers" } */ > > /* { dg-warning "JSON tuning file does not contain version information" "" { > target *-*-* } 0 } */ > -/* { dg-warning "key 'tune_params' not found in JSON data" "" { target > *-*-* } 0 } */ > +/* { dg-regexp > ".*gcc.target/aarch64/aarch64-json-tunings/empty-brackets.json:1:1: warning: > key 'tune_params' not found in JSON data" } */ > +/* { dg-begin-multiline-output "" } > + 1 | {} > + | ^~ > + { dg-end-multiline-output "" } */ > > -int main () {} > \ No newline at end of file > +int main () {} > diff --git a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/enum-2.c > b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/enum-2.c > index c53bc5292d52f..30e0fd47d7946 100644 > --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/enum-2.c > +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/enum-2.c > @@ -1,8 +1,21 @@ > /* { dg-do compile } */ > /* { dg-additional-options > "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/enum-2.json > -fdump-tuning-model=temp.json" } */ > +/* { dg-additional-options "-fdiagnostics-show-caret > -fdiagnostics-show-line-numbers" } */ > > /* { dg-warning "JSON tuning file does not contain version information" "" { > target *-*-* } 0 } */ > -/* { dg-warning "autoprefetcher_model not recognized, defaulting to > 'AUTOPREFETCHER_OFF'" "" { target *-*-* } 0 } */ > -/* { dg-warning "ldp_policy_model not recognized, defaulting to > 'AARCH64_LDP_STP_POLICY_DEFAULT'" "" { target *-*-* } 0 } */ > > -int main () {} > \ No newline at end of file > +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/enum-2.json: In > JSON value '/tune_params/autoprefetcher_model'" } */ > +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/enum-2.json:3:29: > warning: autoprefetcher_model not recognized, defaulting to > 'AUTOPREFETCHER_OFF'" } */ > +/* { dg-begin-multiline-output "" } > + 3 | "autoprefetcher_model": "null", > + | ^~~~~~ > + { dg-end-multiline-output "" } */ > + > +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/enum-2.json: In > JSON value '/tune_params/ldp_policy_model'" } */ > +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/enum-2.json:4:25: > warning: ldp_policy_model not recognized, defaulting to > 'AARCH64_LDP_STP_POLICY_DEFAULT'" } */ > +/* { dg-begin-multiline-output "" } > + 4 | "ldp_policy_model": "null", > + | ^~~~~~ > + { dg-end-multiline-output "" } */ > + > +int main () {} > diff --git > a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-2.c > b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-2.c > index 093c86048ce95..4e9de75a7aa7d 100644 > --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-2.c > +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-2.c > @@ -1,8 +1,16 @@ > /* { dg-do compile } */ > -/* { dg-additional-options > "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/integer-2.json > -fdump-tuning-model=temp.json" } */ > +/* { dg-additional-options > "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/integer-2.json > -fdump-tuning-model=temp.json " } */ > +/* { dg-additional-options "-fdiagnostics-show-caret > -fdiagnostics-show-line-numbers" } */ > > /* { dg-warning "JSON tuning file does not contain version information" "" { > target *-*-* } 0 } */ > -/* { dg-error "key .* value .* is out of range for 'int' type" "" { target > *-*-* } 0 } */ > + > +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/integer-2.json: In > JSON value '/tune_params/int_reassoc_width'" } */ > +/* { dg-regexp > ".*gcc.target/aarch64/aarch64-json-tunings/integer-2.json:3:26: error: key .* > value .* is out of range for 'int' type \\\[.*, .*\\\]" } */ > +/* { dg-begin-multiline-output "" } > + 3 | "int_reassoc_width": 12097307449014 > + | ^~~~~~~~~~~~~~ > + { dg-end-multiline-output "" } */ > + > /* { dg-error "validation failed for the provided JSON data" "" { target > *-*-* } 0 } */ > > -int main () {} > \ No newline at end of file > +int main () {} > diff --git > a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-3.c > b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-3.c > index 438685c6002c6..bab713b35d03f 100644 > --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-3.c > +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-3.c > @@ -1,8 +1,17 @@ > /* { dg-do compile } */ > /* { dg-additional-options > "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/integer-3.json > -fdump-tuning-model=temp.json" } */ > +/* { dg-additional-options "-fdiagnostics-show-caret > -fdiagnostics-show-line-numbers" } */ > > /* { dg-warning "JSON tuning file does not contain version information" "" { > target *-*-* } 0 } */ > -/* { dg-error "key .* expected to be an integer" "" { target *-*-* } 0 } */ > + > +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/integer-3.json: In > JSON value '/tune_params/issue_rate'" } */ > +/* { dg-regexp > ".*gcc.target/aarch64/aarch64-json-tunings/integer-3.json:3:19: error: key .* > expected to be an integer" } */ > +/* { dg-begin-multiline-output "" } > + 3 | "issue_rate": "10" > + | ^~~~ > + { dg-end-multiline-output "" } */ > + > + > /* { dg-error "validation failed for the provided JSON data" "" { target > *-*-* } 0 } */ > > -int main () {} > \ No newline at end of file > +int main () {} > diff --git > a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.c > b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.c > new file mode 100644 > index 0000000000000..f4d6bc0a1376c > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.c > @@ -0,0 +1,11 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options > "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/malformed.json > -fdump-tuning-model=temp.json" } */ > +/* { dg-additional-options "-fdiagnostics-show-caret > -fdiagnostics-show-line-numbers" } */ > + > +/* { dg-regexp > ".*gcc.target/aarch64/aarch64-json-tunings/malformed.json:3:17: error: error > parsing JSON data: expected ':'; got number" } */ > +/* { dg-begin-multiline-output "" } > + 3 | "sve_width" 128 > + | ^~~ > + { dg-end-multiline-output "" } */ > + > +int main () {} > diff --git > a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.json > b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.json > new file mode 100644 > index 0000000000000..541b721faccde > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.json > @@ -0,0 +1,5 @@ > +{ > + "tune_params": { > + "sve_width" 128 > + } > +} > diff --git a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/string-2.c > b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/string-2.c > index ad3ea1422bade..ae6e265c514ac 100644 > --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/string-2.c > +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/string-2.c > @@ -1,8 +1,16 @@ > /* { dg-do compile } */ > /* { dg-additional-options > "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/string-2.json > -fdump-tuning-model=temp.json" } */ > +/* { dg-additional-options "-fdiagnostics-show-caret > -fdiagnostics-show-line-numbers" } */ > > /* { dg-warning "JSON tuning file does not contain version information" "" { > target *-*-* } 0 } */ > -/* { dg-error "key .* expected to be a string" "" { target *-*-* } 0 } */ > + > +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/string-2.json: In > JSON value '/tune_params/function_align'" } */ > +/* { dg-regexp > ".*gcc.target/aarch64/aarch64-json-tunings/string-2.json:3:23: error: key .* > expected to be a string" "" { target *-*-* } 0 } */ > +/* { dg-begin-multiline-output "" } > + 3 | "function_align": 16 > + | ^~ > + { dg-end-multiline-output "" } */ > + > /* { dg-error "validation failed for the provided JSON data" "" { target > *-*-* } 0 } */ > > -int main () {} > \ No newline at end of file > +int main () {} > diff --git > a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c > b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c > index bafbda8a1ef57..27bfacc40203d 100644 > --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c > +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c > @@ -1,7 +1,15 @@ > /* { dg-do compile } */ > /* { dg-additional-options > "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.json > -fdump-tuning-model=temp.json" } */ > +/* { dg-additional-options "-fdiagnostics-show-caret > -fdiagnostics-show-line-numbers" } */ > > /* { dg-warning "JSON tuning file does not contain version information" "" { > target *-*-* } 0 } */ > -/* { dg-warning "key .* is not a tuning parameter, skipping" "" { target > *-*-* } 0 } */ > > -int main () {} > \ No newline at end of file > +/* { dg-regexp > ".*gcc.target/aarch64/aarch64-json-tunings/unidentified-key.json: In JSON > value '/tune_params/unidentified_key'" } */ > +/* { dg-regexp > ".*gcc.target/aarch64/aarch64-json-tunings/unidentified-key.json:3:25: > warning: key .* is not a tuning parameter, skipping" "" { target *-*-* } 0 } > */ > + > +/* { dg-begin-multiline-output "" } > + 3 | "unidentified_key": "10" > + | ^~~~ > + { dg-end-multiline-output "" } */ > + > +int main () {} > diff --git > a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c > b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c > index ce1989d8e31df..88848e406cc0a 100644 > --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c > +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c > @@ -1,8 +1,16 @@ > /* { dg-do compile } */ > /* { dg-additional-options > "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.json > -fdump-tuning-model=temp.json" } */ > +/* { dg-additional-options "-fdiagnostics-show-caret > -fdiagnostics-show-line-numbers" } */ > > /* { dg-warning "JSON tuning file does not contain version information" "" { > target *-*-* } 0 } */ > -/* { dg-error "key .* value .* is out of range for 'uint' type" "" { target > *-*-* } 0 } */ > + > +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/unsigned-2.json: > In JSON value '/tune_params/sve_width'" } */ > +/* { dg-regexp > ".*gcc.target/aarch64/aarch64-json-tunings/unsigned-2.json:3:18: error: key > .* value .* is out of range for 'uint' type \\\[.*, .*\\\]" } */ > +/* { dg-begin-multiline-output "" } > + 3 | "sve_width": -128, > + | ^~~~ > + { dg-end-multiline-output "" } */ > + > /* { dg-error "validation failed for the provided JSON data" "" { target > *-*-* } 0 } */ > > int main () {} > diff --git > a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c > b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c > index 20a661f557026..0e808009810ef 100644 > --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c > +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c > @@ -1,8 +1,16 @@ > /* { dg-do compile } */ > /* { dg-additional-options > "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.json > -fdump-tuning-model=temp.json" } */ > +/* { dg-additional-options "-fdiagnostics-show-caret > -fdiagnostics-show-line-numbers" } */ > > /* { dg-warning "JSON tuning file does not contain version information" "" { > target *-*-* } 0 } */ > -/* { dg-error "key .* value .* is out of range for 'uint' type" "" { target > *-*-* } 0 } */ > + > +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/unsigned-3.json: > In JSON value '/tune_params/sve_width'" } */ > +/* { dg-regexp > ".*gcc.target/aarch64/aarch64-json-tunings/unsigned-3.json:3:18: error: key > .* value .* is out of range for 'uint' type \\\[.*, .*\\\]" } */ > +/* { dg-begin-multiline-output "" } > + 3 | "sve_width": 5000000000 > + | ^~~~~~~~~~ > + { dg-end-multiline-output "" } */ > + > /* { dg-error "validation failed for the provided JSON data" "" { target > *-*-* } 0 } */ > > int main () {} > -- > 2.26.3 >
