untyped calls: enable target switching [PR112334]

Message ID oredg6yn48.fsf@lxoliva.fsfla.org
State New
Headers
Series untyped calls: enable target switching [PR112334] |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Testing passed

Commit Message

Alexandre Oliva Dec. 1, 2023, 3:10 p.m. UTC
  On Dec  1, 2023, Alexandre Oliva <oliva@adacore.com> wrote:

> Also tested on arm-eabi, but it's *not* enough (or needed) to fix the
> PR, there's another bug lurking there, with a separate patch coming
> up.

Here it is.

----

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.

Regstrapped on x86_64-linux-gnu, tested on arm-eabi with and without the
upthread patch.  It fixes the hardcfr fails either way.  As for the
ugliness, there's a follow up patch below that attempts to alleviate it
a little (also regstrapped and tested), but I'm not sure we want to go
down that path.  WDYT?


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.
---
 gcc/builtins.cc |   16 ++++++++++++++--
 gcc/builtins.h  |    7 +++++++
 2 files changed, 21 insertions(+), 2 deletions(-)
  

Comments

Jeff Law Dec. 11, 2023, 4:02 p.m. UTC | #1
On 12/1/23 08:10, Alexandre Oliva wrote:
> On Dec  1, 2023, Alexandre Oliva <oliva@adacore.com> wrote:
> 
>> Also tested on arm-eabi, but it's *not* enough (or needed) to fix the
>> PR, there's another bug lurking there, with a separate patch coming
>> up.
> 
> Here it is.
> 
> ----
> 
> 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.
> 
> Regstrapped on x86_64-linux-gnu, tested on arm-eabi with and without the
> upthread patch.  It fixes the hardcfr fails either way.  As for the
> ugliness, there's a follow up patch below that attempts to alleviate it
> a little (also regstrapped and tested), but I'm not sure we want to go
> down that path.  WDYT?
It's a wart, but doesn't seem too bad to me.

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


> 
> untyped calls: use wrapper class type for implicit plus_one
> 
> Instead of get and set macros to apply a delta, use a single macro
> that resorts to a temporary wrapper class to apply it.
> 
> To be combined (or not) with the previous patch.
I'd be OK with this as well.

jeff
  
Alexandre Oliva Dec. 12, 2023, 4:44 a.m. UTC | #2
On Dec 11, 2023, Jeff Law <jeffreyalaw@gmail.com> wrote:

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

Thanks, I put this bit in.

>> untyped calls: use wrapper class type for implicit plus_one
>> Instead of get and set macros to apply a delta, use a single macro
>> that resorts to a temporary wrapper class to apply it.
>> To be combined (or not) with the previous patch.

> I'd be OK with this as well.

That conditional made me doubt that this was meant as approval, so I did
*not* put this one in ;-)

If there's firmer/broader buy-in, I'd be glad to put it in as well.
  
Jeff Law Dec. 20, 2023, 5:08 a.m. UTC | #3
On 12/11/23 21:44, Alexandre Oliva wrote:

> 
>>> untyped calls: use wrapper class type for implicit plus_one
>>> Instead of get and set macros to apply a delta, use a single macro
>>> that resorts to a temporary wrapper class to apply it.
>>> To be combined (or not) with the previous patch.
> 
>> I'd be OK with this as well.
> 
> That conditional made me doubt that this was meant as approval, so I did
> *not* put this one in ;-)
> 
> If there's firmer/broader buy-in, I'd be glad to put it in as well.
Sorry it was meant to be an ACK for the trunk for both patches.

jeff
>
  
Alexandre Oliva Dec. 21, 2023, 1:01 a.m. UTC | #4
On Dec 20, 2023, Jeff Law <jeffreyalaw@gmail.com> wrote:

> Sorry it was meant to be an ACK for the trunk for both patches.

Aah, I see.  So this is what I installed last night, upon seeing your
message.


untyped calls: use wrapper class type for implicit plus_one

Instead of get and set macros to apply a delta, use a single macro
that resorts to a temporary wrapper class to apply it.


for  gcc/ChangeLog

	* builtins.cc (delta_type): New template class.
	(set_apply_args_size, get_apply_args_size): Replace with...
	(saved_apply_args_size): ... this.
	(set_apply_result_size, get_apply_result_size): Replace with...
	(saved_apply_result_size): ... this.
	(apply_args_size, apply_result_size): Adjust.
---
 gcc/builtins.cc |   32 ++++++++++++++++++++------------
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 7c2732ab79e6f..23cc6b6838a01 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -1403,16 +1403,24 @@ 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)
+/* Wrapper that implicitly applies a delta when getting or setting the
+   enclosed value.  */
+template <typename T>
+class delta_type
+{
+  T &value; T const delta;
+public:
+  delta_type (T &val, T dlt) : value (val), delta (dlt) {}
+  operator T () const { return value + delta; }
+  T operator = (T val) const { value = val - delta; return val; }
+};
+
+#define saved_apply_args_size \
+  (delta_type<int> (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 saved_apply_result_size \
+  (delta_type<int> (this_target_builtins->x_apply_result_size_plus_one, -1))
 #define apply_result_mode \
   (this_target_builtins->x_apply_result_mode)
 
@@ -1422,7 +1430,7 @@ get_memory_rtx (tree exp, tree len)
 static int
 apply_args_size (void)
 {
-  int size = get_apply_args_size ();
+  int size = saved_apply_args_size;
   int align;
   unsigned int regno;
 
@@ -1456,7 +1464,7 @@ apply_args_size (void)
 	else
 	  apply_args_mode[regno] = as_a <fixed_size_mode> (VOIDmode);
 
-      set_apply_args_size (size);
+      saved_apply_args_size = size;
     }
   return size;
 }
@@ -1467,7 +1475,7 @@ apply_args_size (void)
 static int
 apply_result_size (void)
 {
-  int size = get_apply_result_size ();
+  int size = saved_apply_result_size;
   int align, regno;
 
   /* The values computed by this function never change.  */
@@ -1500,7 +1508,7 @@ apply_result_size (void)
       size = APPLY_RESULT_SIZE;
 #endif
 
-      set_apply_result_size (size);
+      saved_apply_result_size = size;
     }
   return size;
 }
  

Patch

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 4fc58a0bda9b8..039bb5e997a2c 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -1398,8 +1398,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)
 
@@ -1409,7 +1417,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;
 
@@ -1442,6 +1450,8 @@  apply_args_size (void)
 	  }
 	else
 	  apply_args_mode[regno] = as_a <fixed_size_mode> (VOIDmode);
+
+      set_apply_args_size (size);
     }
   return size;
 }
@@ -1452,7 +1462,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.  */
@@ -1484,6 +1494,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 88a26d70cd5a8..1a26fc63a6d10 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;


----

untyped calls: use wrapper class type for implicit plus_one

Instead of get and set macros to apply a delta, use a single macro
that resorts to a temporary wrapper class to apply it.

To be combined (or not) with the previous patch.
---
 gcc/builtins.cc |   32 ++++++++++++++++++++------------
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 039bb5e997a2c..a60e0a7084513 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -1398,16 +1398,24 @@  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)
+/* Wrapper that implicitly applies a delta when getting or setting the
+   enclosed value.  */
+template <typename T>
+class delta_type
+{
+  T &value; T const delta;
+public:
+  delta_type (T &val, T dlt) : value (val), delta (dlt) {}
+  operator T () const { return value + delta; }
+  T operator = (T val) const { value = val - delta; return val; }
+};
+
+#define saved_apply_args_size \
+  (delta_type<int> (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 saved_apply_result_size \
+  (delta_type<int> (this_target_builtins->x_apply_result_size_plus_one, -1))
 #define apply_result_mode \
   (this_target_builtins->x_apply_result_mode)
 
@@ -1417,7 +1425,7 @@  get_memory_rtx (tree exp, tree len)
 static int
 apply_args_size (void)
 {
-  int size = get_apply_args_size ();
+  int size = saved_apply_args_size;
   int align;
   unsigned int regno;
 
@@ -1451,7 +1459,7 @@  apply_args_size (void)
 	else
 	  apply_args_mode[regno] = as_a <fixed_size_mode> (VOIDmode);
 
-      set_apply_args_size (size);
+      saved_apply_args_size = size;
     }
   return size;
 }
@@ -1462,7 +1470,7 @@  apply_args_size (void)
 static int
 apply_result_size (void)
 {
-  int size = get_apply_result_size ();
+  int size = saved_apply_result_size;
   int align, regno;
 
   /* The values computed by this function never change.  */
@@ -1495,7 +1503,7 @@  apply_result_size (void)
       size = APPLY_RESULT_SIZE;
 #endif
 
-      set_apply_result_size (size);
+      saved_apply_result_size = size;
     }
   return size;
 }