diff options
author | Alexandre Oliva <oliva@adacore.com> | 2023-12-12 01:12:04 -0300 |
---|---|---|
committer | Alexandre Oliva <oliva@gnu.org> | 2023-12-12 01:12:04 -0300 |
commit | d96533559e26dd0c86f0708fa46eef65c35f7b90 (patch) | |
tree | 4d7b816ddbbc18c702c90a73e85655ef6948ecee /gcc | |
parent | 07dcb39e08aa52f166e8d74420364757002ad756 (diff) | |
download | gcc-d96533559e26dd0c86f0708fa46eef65c35f7b90.zip gcc-d96533559e26dd0c86f0708fa46eef65c35f7b90.tar.gz gcc-d96533559e26dd0c86f0708fa46eef65c35f7b90.tar.bz2 |
untyped calls: enable target switching [PR112334]
The computation of apply_args_size and apply_result_size is saved in a
static variable, so that the corresponding _mode arrays are
initialized only once. That is not compatible with switchable
targets, and ARM's arm_set_current_function, by saving and restoring
target globals, exercises this problem with a testcase such as that in
the PR, in which more than one function in the translation unit calls
__builtin_apply or __builtin_return, respectively.
This patch moves the _size statics into the target_builtins array,
with a bit of ugliness over _plus_one so that zero initialization of
the struct does the right thing.
for gcc/ChangeLog
PR target/112334
* builtins.h (target_builtins): Add fields for apply_args_size
and apply_result_size.
* builtins.cc (apply_args_size, apply_result_size): Cache
results in fields rather than in static variables.
(get_apply_args_size, set_apply_args_size): New.
(get_apply_result_size, set_apply_result_size): New.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/builtins.cc | 16 | ||||
-rw-r--r-- | gcc/builtins.h | 7 |
2 files changed, 21 insertions, 2 deletions
diff --git a/gcc/builtins.cc b/gcc/builtins.cc index f6c9649..7c2732a 100644 --- a/gcc/builtins.cc +++ b/gcc/builtins.cc @@ -1403,8 +1403,16 @@ get_memory_rtx (tree exp, tree len) /* Built-in functions to perform an untyped call and return. */ +#define set_apply_args_size(x) \ + (this_target_builtins->x_apply_args_size_plus_one = 1 + (x)) +#define get_apply_args_size() \ + (this_target_builtins->x_apply_args_size_plus_one - 1) #define apply_args_mode \ (this_target_builtins->x_apply_args_mode) +#define set_apply_result_size(x) \ + (this_target_builtins->x_apply_result_size_plus_one = 1 + (x)) +#define get_apply_result_size() \ + (this_target_builtins->x_apply_result_size_plus_one - 1) #define apply_result_mode \ (this_target_builtins->x_apply_result_mode) @@ -1414,7 +1422,7 @@ get_memory_rtx (tree exp, tree len) static int apply_args_size (void) { - static int size = -1; + int size = get_apply_args_size (); int align; unsigned int regno; @@ -1447,6 +1455,8 @@ apply_args_size (void) } else apply_args_mode[regno] = as_a <fixed_size_mode> (VOIDmode); + + set_apply_args_size (size); } return size; } @@ -1457,7 +1467,7 @@ apply_args_size (void) static int apply_result_size (void) { - static int size = -1; + int size = get_apply_result_size (); int align, regno; /* The values computed by this function never change. */ @@ -1489,6 +1499,8 @@ apply_result_size (void) #ifdef APPLY_RESULT_SIZE size = APPLY_RESULT_SIZE; #endif + + set_apply_result_size (size); } return size; } diff --git a/gcc/builtins.h b/gcc/builtins.h index 88a26d7..1a26fc6 100644 --- a/gcc/builtins.h +++ b/gcc/builtins.h @@ -37,6 +37,13 @@ struct target_builtins { register windows, this gives only the outbound registers. INCOMING_REGNO gives the corresponding inbound register. */ fixed_size_mode_pod x_apply_result_mode[FIRST_PSEUDO_REGISTER]; + + /* Nonzero iff the arrays above have been initialized. The _plus_one suffix + is for zero initialization to make it an unreasonable size, used to signal + that the size and the corresponding mode array has not been + initialized. */ + int x_apply_args_size_plus_one; + int x_apply_result_size_plus_one; }; extern struct target_builtins default_target_builtins; |