aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Oliva <oliva@adacore.com>2023-12-12 01:12:04 -0300
committerAlexandre Oliva <oliva@gnu.org>2023-12-12 01:12:04 -0300
commitd96533559e26dd0c86f0708fa46eef65c35f7b90 (patch)
tree4d7b816ddbbc18c702c90a73e85655ef6948ecee /gcc
parent07dcb39e08aa52f166e8d74420364757002ad756 (diff)
downloadgcc-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.cc16
-rw-r--r--gcc/builtins.h7
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;