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