[C] Add a target hook that allows targets to verify type usage

Programming / Compilers / GCC - rsandifo [138bc75d-0d04-0410-961f-82ee72b054a4] - 30 November 2019 18:50 EST

This patch adds a new target hook to check whether there are any target-specific reasons why a type cannot be used in a certain source-language context. It works in a similar way to existing hooks like TARGET_INVALID_CONVERSION and TARGET_INVALID_UNARY_OP.

The reason for adding the hook is to report invalid uses of SVE types. Throughout a TU, the SVE vector and predicate types represent values that can be stored in an SVE vector or predicate register. At certain points in the TU we might be able to generate code that assumes the registers have a particular size, but often we can't. In some cases we might even make multiple different assumptions in the same TU (e.g. when implementing an ifunc for multiple vector lengths).

But SVE types themselves are the same type throughout. The register size assumptions change how we generate code, but they don't change the definition of the types.

This means that the types do not have a fixed size at the C level even when -msve-vector-bits=N is in effect. It also means that the size does not work in the same way as for C VLAs, where the abstract machine evaluates the size at a particular point and then carries that size forward to later code.

The SVE ACLE deals with this by making it invalid to use C and C++ constructs that depend on the size or layout of SVE types. The spec refers to the types as "sizeless" types and defines their semantics as edits to the standards. See:

https://gcc.gnu.org/ml/gcc-patches/2018-10/msg00868.html

for a fuller description and:

https://gcc.gnu.org/ml/gcc/2019-11/msg00088.html

for a recent update on the status.

However, since all current sizeless types are target-specific built-in types, there's no real reason for the frontends to handle them directly. They can just hand off the checks to target code instead. It's then possible for the errors to refer to "SVE types" rather than "sizeless types", which is likely to be more meaningful to users.

There is a slight overlap between the new tests and the ones for gnu_vector_type_p in r277950, but here the emphasis is on testing sizelessness.

2019-11-30 Richard Sandiford

gcc/
- target.h (type_context_kind): New enum. (verify_type_context): Declare.
- target.def (verify_type_context): New target hook.
- doc/tm.texi.in (TARGET_VERIFY_TYPE_CONTEXT): Likewise.
- doc/tm.texi: Regenerate.
- tree.c (verify_type_context): New function.
- config/aarch64/aarch64-protos.h (aarch64_sve::verify_type_context): Declare.
- config/aarch64/aarch64-sve-builtins.cc (verify_type_context): New function.
- config/aarch64/aarch64.c (aarch64_verify_type_context): Likewise. (TARGET_VERIFY_TYPE_CONTEXT): Define.

gcc/c-family/
- c-common.c (pointer_int_sum): Use verify_type_context to check whether the target allows pointer arithmetic for the types involved. (c_sizeof_or_alignof_type, c_alignof_expr): Use verify_type_context to check whether the target allows sizeof and alignof operations for the types involved.

gcc/c/
- c-decl.c (start_decl): Allow initialization of variables whose size is a POLY_INT_CST. (finish_decl): Use verify_type_context to check whether the target allows variables with a particular type to have static or thread-local storage duration. Don't raise a second error if such variables do not have a constant size. (grokdeclarator): Use verify_type_context to check whether the target allows fields or array elements to have a particular type.
- c-typeck.c (pointer_diff): Use verify_type_context to test whether the target allows pointer difference for the types involved. (build_unary_op): Likewise for pointer increment and decrement.

gcc/testsuite/
- gcc.target/aarch64/sve/acle/general-c/sizeless-1.c: New test.
- gcc.target/aarch64/sve/acle/general-c/sizeless-2.c: Likewise.

bb3c9a3bb5d [C] Add a target hook that allows targets to verify type usage
gcc/ChangeLog | 15 ++
gcc/c-family/ChangeLog | 8 +
gcc/c-family/c-common.c | 15 +-
gcc/c/ChangeLog | 14 ++
gcc/c/c-decl.c | 29 ++-
gcc/c/c-typeck.c | 8 +
gcc/config/aarch64/aarch64-protos.h | 3 +
gcc/config/aarch64/aarch64-sve-builtins.cc | 49 +++++
gcc/config/aarch64/aarch64.c | 12 ++
gcc/doc/tm.texi | 13 ++
gcc/doc/tm.texi.in | 2 +
gcc/target.def | 16 ++
gcc/target.h | 29 +++
gcc/testsuite/ChangeLog | 5 +
.../aarch64/sve/acle/general-c/sizeless-1.c | 217 +++++++++++++++++++++
.../aarch64/sve/acle/general-c/sizeless-2.c | 217 +++++++++++++++++++++
gcc/tree.c | 15 ++
17 files changed, 664 insertions(+), 3 deletions(-)

Upstream: gcc.gnu.org


  • Share