In the JSON parser's parse_object_helper for const pointer members, we have a
if (!member) return; guard at entry.

This is because the function works by dereferencing the member pointer and
making a non-const copy of the object it points to. The parser can then
override this copy with new values and re-assign the pointer to the new object.

This is problematic if member is NULL in the base tunings, but provided in the
JSON file, which can happen with some combinations of -mcpu and
-muser-provided-CPU.

For example, with no -mcpu, if the generic tunings has issue_info set to
nullptr (eg. generic_armv8_a), then even if the user does provide issue_info
data in the JSON file, parse_object_helper will silently ignore it.

The naive fix for this is to create a zero-initialized copy of the object if
it is NULL, and then override it with the new values from the JSON file.

However, this results in another problem: if the user provides only selective
fields of the strucutre, the rest of the fields will be set to zero and
potentially interfere with costing decisions.

I think at that point the best we can do is emit a warning. With David Malcolm's
improved JSON diagnostics, we can be specific about the problematic structure as
well.

----

Since we potentially zero-initialize objects, I had to add a default constructor
to objects that only had parameterized constructors. Is this OK?

Bootstrapped and regtested on aarch64-linux-gnu, OK for trunk?

Signed-off-by: Soumya AR <[email protected]>

gcc/ChangeLog:

        * config/aarch64/aarch64-json-tunings-parser.cc (parse_object_helper):
        Zero-initialize objects that are NULL in the base tunings, if provided
        in JSON tunings.
        * config/aarch64/aarch64-protos.h (struct sve_vec_cost): Add default
        constructor.
        (struct aarch64_simd_vec_issue_info): Likewise.
        (struct aarch64_sve_vec_issue_info): Likewise.

gcc/testsuite/ChangeLog:

        * gcc.target/aarch64/aarch64-json-tunings/nullptr-issue-info.c:
        New test.
        * gcc.target/aarch64/aarch64-json-tunings/nullptr-issue-info.json:
        New test input.
---
 .../aarch64/aarch64-json-tunings-parser.cc    |  8 ++--
 gcc/config/aarch64/aarch64-protos.h           |  6 +++
 .../aarch64-json-tunings/nullptr-issue-info.c | 20 ++++++++++
 .../nullptr-issue-info.json                   | 38 +++++++++++++++++++
 4 files changed, 68 insertions(+), 4 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/nullptr-issue-info.c
 create mode 100644 
gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/nullptr-issue-info.json

diff --git a/gcc/config/aarch64/aarch64-json-tunings-parser.cc 
b/gcc/config/aarch64/aarch64-json-tunings-parser.cc
index 9b7bdf535c9..19598034761 100644
--- a/gcc/config/aarch64/aarch64-json-tunings-parser.cc
+++ b/gcc/config/aarch64/aarch64-json-tunings-parser.cc
@@ -109,9 +109,6 @@ static std::enable_if_t<std::is_pointer<T>::value
 parse_object_helper (const json::object *field_obj, T &member,
                     parse_func_type<T> parse_func)
 {
-  if (!member)
-    return;
-
   /* Use static storage for the non-const copy.
      This works because tune_params does not have nested structures of the
      same type, but has room for errors if we end up having pointers to the
@@ -125,7 +122,10 @@ parse_object_helper (const json::object *field_obj, T 
&member,
     }
   already_initialized = true;
   using NonConstType = std::remove_const_t<std::remove_pointer_t<T>>;
-  static NonConstType new_obj = *member;
+  if (!member)
+    warning (0, "JSON tuning overrides an unspecified structure in the base "
+               "tuning; fields not provided in JSON will default to 0");
+  static NonConstType new_obj = member ? *member : NonConstType{};
   parse_func (field_obj, new_obj);
   member = &new_obj;
 }
diff --git a/gcc/config/aarch64/aarch64-protos.h 
b/gcc/config/aarch64/aarch64-protos.h
index d1f2873f208..3f359b0069d 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -255,6 +255,8 @@ typedef struct simd_vec_cost advsimd_vec_cost;
 /* SVE-specific extensions to the information provided by simd_vec_cost.  */
 struct sve_vec_cost : simd_vec_cost
 {
+  sve_vec_cost () = default;
+
   CONSTEXPR sve_vec_cost (const simd_vec_cost &base,
                          unsigned int clast_cost,
                          unsigned int fadda_f16_cost,
@@ -365,6 +367,8 @@ using aarch64_scalar_vec_issue_info = 
aarch64_base_vec_issue_info;
    Advanced SIMD and SVE.  */
 struct aarch64_simd_vec_issue_info : aarch64_base_vec_issue_info
 {
+  aarch64_simd_vec_issue_info () = default;
+
   CONSTEXPR aarch64_simd_vec_issue_info (aarch64_base_vec_issue_info base,
                                         unsigned int ld2_st2_general_ops,
                                         unsigned int ld3_st3_general_ops,
@@ -393,6 +397,8 @@ using aarch64_advsimd_vec_issue_info = 
aarch64_simd_vec_issue_info;
    is a concept of "predicate operations".  */
 struct aarch64_sve_vec_issue_info : aarch64_simd_vec_issue_info
 {
+  aarch64_sve_vec_issue_info () = default;
+
   CONSTEXPR aarch64_sve_vec_issue_info
     (aarch64_simd_vec_issue_info base,
      unsigned int pred_ops_per_cycle,
diff --git 
a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/nullptr-issue-info.c 
b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/nullptr-issue-info.c
new file mode 100644
index 00000000000..3984c63b39e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/nullptr-issue-info.c
@@ -0,0 +1,20 @@
+/* Test that a structure provided in JSON is parsed even when the base tuning
+   model has the structure set to NULL.  */
+
+/* { dg-do compile } */
+/* { dg-additional-options 
"-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/nullptr-issue-info.json
 -fdump-tuning-model=temp-nullptr-issue-info.json" } */
+
+/* { dg-warning "JSON tuning overrides an unspecified structure in the base 
tuning; fields not provided in JSON will default to 0" "" { target *-*-* } 0 } 
*/
+/* { dg-warning "JSON tuning file does not contain version information" "" { 
target *-*-* } 0 } */
+
+/* { dg-final { scan-file "temp-nullptr-issue-info.json" 
"\"loads_stores_per_cycle\": 4" } } */
+/* { dg-final { scan-file "temp-nullptr-issue-info.json" 
"\"general_ops_per_cycle\": 8" } } */
+
+/* { dg-final { scan-file "temp-nullptr-issue-info.json" 
"\"ld2_st2_general_ops\": 2" } } */
+/* { dg-final { scan-file "temp-nullptr-issue-info.json" 
"\"ld4_st4_general_ops\": 3" } } */
+
+/* { dg-final { scan-file "temp-nullptr-issue-info.json" 
"\"pred_ops_per_cycle\": 2" } } */
+/* { dg-final { scan-file "temp-nullptr-issue-info.json" "\"while_pred_ops\": 
1" } } */
+/* { dg-final { scan-file "temp-nullptr-issue-info.json" 
"\"gather_scatter_pair_general_ops\": 1" } } */
+
+int main () {}
diff --git 
a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/nullptr-issue-info.json 
b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/nullptr-issue-info.json
new file mode 100644
index 00000000000..b6fefa87544
--- /dev/null
+++ 
b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/nullptr-issue-info.json
@@ -0,0 +1,38 @@
+{
+  "tune_params": {
+    "vec_costs": {
+      "issue_info": {
+        "scalar": {
+          "loads_stores_per_cycle": 4,
+          "stores_per_cycle": 2,
+          "general_ops_per_cycle": 8,
+          "fp_simd_load_general_ops": 0,
+          "fp_simd_store_general_ops": 1
+        },
+        "advsimd": {
+          "loads_stores_per_cycle": 3,
+          "stores_per_cycle": 2,
+          "general_ops_per_cycle": 6,
+          "fp_simd_load_general_ops": 0,
+          "fp_simd_store_general_ops": 1,
+          "ld2_st2_general_ops": 2,
+          "ld3_st3_general_ops": 2,
+          "ld4_st4_general_ops": 3
+        },
+        "sve": {
+          "loads_stores_per_cycle": 3,
+          "stores_per_cycle": 2,
+          "general_ops_per_cycle": 6,
+          "fp_simd_load_general_ops": 0,
+          "fp_simd_store_general_ops": 1,
+          "pred_ops_per_cycle": 2,
+          "while_pred_ops": 1,
+          "int_cmp_pred_ops": 0,
+          "fp_cmp_pred_ops": 0,
+          "gather_scatter_pair_general_ops": 1,
+          "gather_scatter_pair_pred_ops": 1
+        }
+      }
+    }
+  }
+}
-- 
2.43.0

Reply via email to