Re: [PATCH] Avoid excessive function type casts with splay-trees part 2

2018-06-15 Thread Richard Biener
On June 15, 2018 8:07:44 PM GMT+02:00, Bernd Edlinger 
 wrote:
>On 06/15/18 09:07, Richard Biener wrote:
>> On Thu, 14 Jun 2018, Bernd Edlinger wrote:
>> 
>>> On 06/14/18 15:43, Richard Biener wrote:
 On Fri, 8 Jun 2018, Bernd Edlinger wrote:

> Hi!
>
>
> This patch converts the splay-tree internals into a template, and
>makes
> the typed_splay_tree template really type-safe.  Previously
>everything
> would break apart if KEY_TYPE or VALUE_TYPE would not be pointer
>types.
> This limitation is now removed.
>
> I took the freedom to add a remove function which is only for
> completeness and test coverage, but not (yet) used in a productive
>way.
>
>
> Bootstrapped and reg-tested on x86_64-linux-gnu.
> Is it OK for trunk?

 It looks OK to me but I wonder if we can avoid some of the code
 duplication due to template instantiation by deriving from a
>non-templated
 base class somehow?  The cc1* binaries keep growing with more and
 more template use :/

>>>
>>>
>>> No problem.  The first version used an approach where splay-tree
>>> exposes an extended interface with a context pointer.
>>>
>>> See: https://gcc.gnu.org/ml/gcc-patches/2018-05/msg00178.html
>>>
>>> But it has also a limitation when the value or type is a class, it
>will
>>> not be possible to cast to uintptr_t, it will fail to compile, which
>is
>>> still an improvement since the current version just casts
>incompatible
>>> function pointers, and since I had to silence the
>-Wcast-function-type
>>> the warning would not help either.
>>>
>>>
>>> If you like the original patch better than the template, I can
>cleanup
>>> the original patch as an alternative?
>> 
>> No, I like the template more but wondered if we can somehow outline
>> some of the main worker code?
>> 
>
>The major difficulty with that are the splay_tree_compare_fn and 
>splay_tree_delete_key/value_fn callbacks which don't pass a context
>value in addition to the splay_tree_key and splay_tree_value.
>
>I thought about passing a "glue" object which contains a context
>pointer together with the true key and/or value object, but I gave
>up when I saw this in splay_tree_insert:
>
>  if (sp->root)
> comparison = (*sp->comp)(sp->root->key, key);
>
>   if (sp->root && comparison == 0)
> {
>   /* If the root of the tree already has the indicated KEY, just
>  replace the value with VALUE.  */
>   if (sp->delete_value)
> (*sp->delete_value)(sp->root->value);
>   sp->root->value = value;
> }
>
>There is a delete_key callback missing, and sp->root->key will not
>be updated.  So the resource flow of the glue objects will not work.
>
>This code simply assumes that key equality implies pointer equality,
>or the key does not need to be freed after use, but this is not the
>case with glue objects.
>
>
>So, I don't see how to use the old code in a type-safe template without
>changing the C interface.
>
>Or maybe duplicating the C implementation...
>
>Currently there are not more than two or three uses of this
>template, so it will not be a big difference anyways.
>
>But shouldn't different template functions be folded together
>when the resulting code is identical?
>
>Or is there maybe another template where optimizing the code size
>would be more profitable?
>
>
>So, I would still prefer the splay tree template unless there is a
>better idea, how to proceed.

OK, thanks for having another look. 

The patch is OK as-is. 

Richard. 

>
>Thanks
>Bernd.



Re: [PATCH] Avoid excessive function type casts with splay-trees part 2

2018-06-15 Thread Eric Gallager
On 6/15/18, Bernd Edlinger  wrote:
> On 06/15/18 09:07, Richard Biener wrote:
>> On Thu, 14 Jun 2018, Bernd Edlinger wrote:
>>
>>> On 06/14/18 15:43, Richard Biener wrote:
 On Fri, 8 Jun 2018, Bernd Edlinger wrote:

> Hi!
>
>
> This patch converts the splay-tree internals into a template, and
> makes
> the typed_splay_tree template really type-safe.  Previously everything
> would break apart if KEY_TYPE or VALUE_TYPE would not be pointer
> types.
> This limitation is now removed.
>
> I took the freedom to add a remove function which is only for
> completeness and test coverage, but not (yet) used in a productive
> way.
>
>
> Bootstrapped and reg-tested on x86_64-linux-gnu.
> Is it OK for trunk?

 It looks OK to me but I wonder if we can avoid some of the code
 duplication due to template instantiation by deriving from a
 non-templated
 base class somehow?  The cc1* binaries keep growing with more and
 more template use :/

>>>
>>>
>>> No problem.  The first version used an approach where splay-tree
>>> exposes an extended interface with a context pointer.
>>>
>>> See: https://gcc.gnu.org/ml/gcc-patches/2018-05/msg00178.html
>>>
>>> But it has also a limitation when the value or type is a class, it will
>>> not be possible to cast to uintptr_t, it will fail to compile, which is
>>> still an improvement since the current version just casts incompatible
>>> function pointers, and since I had to silence the -Wcast-function-type
>>> the warning would not help either.
>>>
>>>
>>> If you like the original patch better than the template, I can cleanup
>>> the original patch as an alternative?
>>
>> No, I like the template more but wondered if we can somehow outline
>> some of the main worker code?
>>
>
> The major difficulty with that are the splay_tree_compare_fn and
> splay_tree_delete_key/value_fn callbacks which don't pass a context
> value in addition to the splay_tree_key and splay_tree_value.
>
> I thought about passing a "glue" object which contains a context
> pointer together with the true key and/or value object, but I gave
> up when I saw this in splay_tree_insert:
>
>   if (sp->root)
>  comparison = (*sp->comp)(sp->root->key, key);
>
>if (sp->root && comparison == 0)
>  {
>/* If the root of the tree already has the indicated KEY, just
>   replace the value with VALUE.  */
>if (sp->delete_value)
>  (*sp->delete_value)(sp->root->value);
>sp->root->value = value;
>  }
>
> There is a delete_key callback missing, and sp->root->key will not
> be updated.  So the resource flow of the glue objects will not work.
>
> This code simply assumes that key equality implies pointer equality,
> or the key does not need to be freed after use, but this is not the
> case with glue objects.
>
>
> So, I don't see how to use the old code in a type-safe template without
> changing the C interface.
>
> Or maybe duplicating the C implementation...
>
> Currently there are not more than two or three uses of this
> template, so it will not be a big difference anyways.
>
> But shouldn't different template functions be folded together
> when the resulting code is identical?
>
> Or is there maybe another template where optimizing the code size
> would be more profitable?
>
>
> So, I would still prefer the splay tree template unless there is a
> better idea, how to proceed.
>
>

While you're looking at changing splay trees, could you take a look at
bug 30920, too? It's also about splay trees:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=30920
Just an idea.
Thanks!

> Thanks
> Bernd.
>


Re: [PATCH] Avoid excessive function type casts with splay-trees part 2

2018-06-15 Thread Bernd Edlinger
On 06/15/18 09:07, Richard Biener wrote:
> On Thu, 14 Jun 2018, Bernd Edlinger wrote:
> 
>> On 06/14/18 15:43, Richard Biener wrote:
>>> On Fri, 8 Jun 2018, Bernd Edlinger wrote:
>>>
 Hi!


 This patch converts the splay-tree internals into a template, and makes
 the typed_splay_tree template really type-safe.  Previously everything
 would break apart if KEY_TYPE or VALUE_TYPE would not be pointer types.
 This limitation is now removed.

 I took the freedom to add a remove function which is only for
 completeness and test coverage, but not (yet) used in a productive way.


 Bootstrapped and reg-tested on x86_64-linux-gnu.
 Is it OK for trunk?
>>>
>>> It looks OK to me but I wonder if we can avoid some of the code
>>> duplication due to template instantiation by deriving from a non-templated
>>> base class somehow?  The cc1* binaries keep growing with more and
>>> more template use :/
>>>
>>
>>
>> No problem.  The first version used an approach where splay-tree
>> exposes an extended interface with a context pointer.
>>
>> See: https://gcc.gnu.org/ml/gcc-patches/2018-05/msg00178.html
>>
>> But it has also a limitation when the value or type is a class, it will
>> not be possible to cast to uintptr_t, it will fail to compile, which is
>> still an improvement since the current version just casts incompatible
>> function pointers, and since I had to silence the -Wcast-function-type
>> the warning would not help either.
>>
>>
>> If you like the original patch better than the template, I can cleanup
>> the original patch as an alternative?
> 
> No, I like the template more but wondered if we can somehow outline
> some of the main worker code?
> 

The major difficulty with that are the splay_tree_compare_fn and 
splay_tree_delete_key/value_fn callbacks which don't pass a context
value in addition to the splay_tree_key and splay_tree_value.

I thought about passing a "glue" object which contains a context
pointer together with the true key and/or value object, but I gave
up when I saw this in splay_tree_insert:

  if (sp->root)
 comparison = (*sp->comp)(sp->root->key, key);

   if (sp->root && comparison == 0)
 {
   /* If the root of the tree already has the indicated KEY, just
  replace the value with VALUE.  */
   if (sp->delete_value)
 (*sp->delete_value)(sp->root->value);
   sp->root->value = value;
 }

There is a delete_key callback missing, and sp->root->key will not
be updated.  So the resource flow of the glue objects will not work.

This code simply assumes that key equality implies pointer equality,
or the key does not need to be freed after use, but this is not the
case with glue objects.


So, I don't see how to use the old code in a type-safe template without
changing the C interface.

Or maybe duplicating the C implementation...

Currently there are not more than two or three uses of this
template, so it will not be a big difference anyways.

But shouldn't different template functions be folded together
when the resulting code is identical?

Or is there maybe another template where optimizing the code size
would be more profitable?


So, I would still prefer the splay tree template unless there is a
better idea, how to proceed.


Thanks
Bernd.


Re: [PATCH] Avoid excessive function type casts with splay-trees part 2

2018-06-15 Thread Richard Biener
On Thu, 14 Jun 2018, Bernd Edlinger wrote:

> On 06/14/18 15:43, Richard Biener wrote:
> > On Fri, 8 Jun 2018, Bernd Edlinger wrote:
> > 
> >> Hi!
> >>
> >>
> >> This patch converts the splay-tree internals into a template, and makes
> >> the typed_splay_tree template really type-safe.  Previously everything
> >> would break apart if KEY_TYPE or VALUE_TYPE would not be pointer types.
> >> This limitation is now removed.
> >>
> >> I took the freedom to add a remove function which is only for
> >> completeness and test coverage, but not (yet) used in a productive way.
> >>
> >>
> >> Bootstrapped and reg-tested on x86_64-linux-gnu.
> >> Is it OK for trunk?
> > 
> > It looks OK to me but I wonder if we can avoid some of the code
> > duplication due to template instantiation by deriving from a non-templated
> > base class somehow?  The cc1* binaries keep growing with more and
> > more template use :/
> > 
> 
> 
> No problem.  The first version used an approach where splay-tree
> exposes an extended interface with a context pointer.
> 
> See: https://gcc.gnu.org/ml/gcc-patches/2018-05/msg00178.html
> 
> But it has also a limitation when the value or type is a class, it will
> not be possible to cast to uintptr_t, it will fail to compile, which is
> still an improvement since the current version just casts incompatible
> function pointers, and since I had to silence the -Wcast-function-type
> the warning would not help either.
> 
> 
> If you like the original patch better than the template, I can cleanup
> the original patch as an alternative?

No, I like the template more but wondered if we can somehow outline
some of the main worker code?

Thanks,
Richard.


Re: [PATCH] Avoid excessive function type casts with splay-trees part 2

2018-06-14 Thread Bernd Edlinger
On 06/14/18 15:43, Richard Biener wrote:
> On Fri, 8 Jun 2018, Bernd Edlinger wrote:
> 
>> Hi!
>>
>>
>> This patch converts the splay-tree internals into a template, and makes
>> the typed_splay_tree template really type-safe.  Previously everything
>> would break apart if KEY_TYPE or VALUE_TYPE would not be pointer types.
>> This limitation is now removed.
>>
>> I took the freedom to add a remove function which is only for
>> completeness and test coverage, but not (yet) used in a productive way.
>>
>>
>> Bootstrapped and reg-tested on x86_64-linux-gnu.
>> Is it OK for trunk?
> 
> It looks OK to me but I wonder if we can avoid some of the code
> duplication due to template instantiation by deriving from a non-templated
> base class somehow?  The cc1* binaries keep growing with more and
> more template use :/
> 


No problem.  The first version used an approach where splay-tree
exposes an extended interface with a context pointer.

See: https://gcc.gnu.org/ml/gcc-patches/2018-05/msg00178.html

But it has also a limitation when the value or type is a class, it will
not be possible to cast to uintptr_t, it will fail to compile, which is
still an improvement since the current version just casts incompatible
function pointers, and since I had to silence the -Wcast-function-type
the warning would not help either.


If you like the original patch better than the template, I can cleanup
the original patch as an alternative?


Thanks
Bernd.


Re: [PATCH] Avoid excessive function type casts with splay-trees part 2

2018-06-14 Thread Richard Biener
On Fri, 8 Jun 2018, Bernd Edlinger wrote:

> Hi!
> 
> 
> This patch converts the splay-tree internals into a template, and makes
> the typed_splay_tree template really type-safe.  Previously everything
> would break apart if KEY_TYPE or VALUE_TYPE would not be pointer types.
> This limitation is now removed.
> 
> I took the freedom to add a remove function which is only for
> completeness and test coverage, but not (yet) used in a productive way.
> 
> 
> Bootstrapped and reg-tested on x86_64-linux-gnu.
> Is it OK for trunk?

It looks OK to me but I wonder if we can avoid some of the code 
duplication due to template instantiation by deriving from a non-templated
base class somehow?  The cc1* binaries keep growing with more and
more template use :/

Thanks,
Richard.


Re: [PATCH] Avoid excessive function type casts with splay-trees part 2

2018-06-11 Thread David Malcolm
On Fri, 2018-06-08 at 20:41 +, Bernd Edlinger wrote:
> On 06/08/18 16:28, David Malcolm wrote:
> > On Fri, 2018-06-08 at 14:03 +, Bernd Edlinger wrote:
> > > Hi!
> > > 
> > > 
> > > This patch converts the splay-tree internals into a template, and
> > > makes
> > > the typed_splay_tree template really type-safe.  Previously
> > > everything
> > > would break apart if KEY_TYPE or VALUE_TYPE would not be pointer
> > > types.
> > > This limitation is now removed.
> > > 
> > > I took the freedom to add a remove function which is only for
> > > completeness and test coverage, but not (yet) used in a
> > > productive
> > > way.
> > > 
> > > 
> > > Bootstrapped and reg-tested on x86_64-linux-gnu.
> > > Is it OK for trunk?
> > 
> > Was this testing done with "jit" enabled? (there's some usage of
> > typed_splay_tree there, for jit's equivalent of switch statements)
> > 
> > Note that the jit frontend isn't covered by "all"  in --enable-
> > languages; it has to be added manually, iirc since it requires --
> > enable-host-shared.
> > 
> 
> Yes, good point.  I repeated the test with --enable-host-shared
> and all jit tests did pass.

Thanks!
Dave


Re: [PATCH] Avoid excessive function type casts with splay-trees part 2

2018-06-08 Thread Bernd Edlinger
On 06/08/18 16:28, David Malcolm wrote:
> On Fri, 2018-06-08 at 14:03 +, Bernd Edlinger wrote:
>> Hi!
>>
>>
>> This patch converts the splay-tree internals into a template, and
>> makes
>> the typed_splay_tree template really type-safe.  Previously
>> everything
>> would break apart if KEY_TYPE or VALUE_TYPE would not be pointer
>> types.
>> This limitation is now removed.
>>
>> I took the freedom to add a remove function which is only for
>> completeness and test coverage, but not (yet) used in a productive
>> way.
>>
>>
>> Bootstrapped and reg-tested on x86_64-linux-gnu.
>> Is it OK for trunk?
> 
> Was this testing done with "jit" enabled? (there's some usage of
> typed_splay_tree there, for jit's equivalent of switch statements)
> 
> Note that the jit frontend isn't covered by "all"  in --enable-
> languages; it has to be added manually, iirc since it requires --
> enable-host-shared.
> 

Yes, good point.  I repeated the test with --enable-host-shared
and all jit tests did pass.


Thanks
Bernd.


> Thanks
> Dave
> 


Re: [PATCH] Avoid excessive function type casts with splay-trees part 2

2018-06-08 Thread David Malcolm
On Fri, 2018-06-08 at 14:03 +, Bernd Edlinger wrote:
> Hi!
> 
> 
> This patch converts the splay-tree internals into a template, and
> makes
> the typed_splay_tree template really type-safe.  Previously
> everything
> would break apart if KEY_TYPE or VALUE_TYPE would not be pointer
> types.
> This limitation is now removed.
> 
> I took the freedom to add a remove function which is only for
> completeness and test coverage, but not (yet) used in a productive
> way.
> 
> 
> Bootstrapped and reg-tested on x86_64-linux-gnu.
> Is it OK for trunk?

Was this testing done with "jit" enabled? (there's some usage of
typed_splay_tree there, for jit's equivalent of switch statements)  

Note that the jit frontend isn't covered by "all"  in --enable-
languages; it has to be added manually, iirc since it requires --
enable-host-shared.

Thanks
Dave


[PATCH] Avoid excessive function type casts with splay-trees part 2

2018-06-08 Thread Bernd Edlinger
Hi!


This patch converts the splay-tree internals into a template, and makes
the typed_splay_tree template really type-safe.  Previously everything
would break apart if KEY_TYPE or VALUE_TYPE would not be pointer types.
This limitation is now removed.

I took the freedom to add a remove function which is only for
completeness and test coverage, but not (yet) used in a productive way.


Bootstrapped and reg-tested on x86_64-linux-gnu.
Is it OK for trunk?


Thanks
Bernd.
2018-06-08  Bernd Edlinger  

* typed-splay-tree.h (typed_splay_tree::remove): New function.
(typed_splay_tree::closure,
typed_splay_tree::inner_foreach_fn, typed_splay_tree::m_inner): Deleted.
(typed_splay_tree::typed_splay_tree,
typed_splay_tree::operator =): Declared private.
(typed_splay_tree::splay_tree_key, typed_splay_tree::splay_tree_value,
typed_splay_tree::splay_tree_node_s, typed_splay_tree::KDEL,
typed_splay_tree::VDEL, typed_splay_tree::splay_tree_delete_helper,
typed_splay_tree::rotate_left, typed_splay_tree::rotate_right,
typed_splay_tree::splay_tree_splay,
typed_splay_tree::splay_tree_foreach_helper,
typed_splay_tree::splay_tree_insert,
typed_splay_tree::splay_tree_remove,
typed_splay_tree::splay_tree_lookup,
typed_splay_tree::splay_tree_predecessor,
typed_splay_tree::splay_tree_successor,
typed_splay_tree::splay_tree_min,
typed_splay_tree::splay_tree_max): Took over from splay-tree.c/.h.
(typed_splay_tree::root, typed_splay_tree::comp,
typed_splay_tree::delete_key,
typed_splay_tree::delete_value): New data members.
* typed-splay-tree.c (selftest::test_str_to_int): Add a test for
typed_splay_tree::remove.
Index: gcc/typed-splay-tree.c
===
--- gcc/typed-splay-tree.c	(revision 260952)
+++ gcc/typed-splay-tree.c	(working copy)
@@ -47,7 +47,10 @@ test_str_to_int ()
   t.insert ("a", 1);
   t.insert ("b", 2);
   t.insert ("c", 3);
+  t.insert ("d", 4);
 
+  t.remove ("d");
+
   ASSERT_EQ (1, t.lookup ("a"));
   ASSERT_EQ (2, t.lookup ("b"));
   ASSERT_EQ (3, t.lookup ("c"));
Index: gcc/typed-splay-tree.h
===
--- gcc/typed-splay-tree.h	(revision 260952)
+++ gcc/typed-splay-tree.h	(working copy)
@@ -20,8 +20,6 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_TYPED_SPLAY_TREE_H
 #define GCC_TYPED_SPLAY_TREE_H
 
-#include "splay-tree.h"
-
 /* Typesafe wrapper around libiberty's splay-tree.h.  */
 template 
 class typed_splay_tree
@@ -44,27 +42,66 @@ class typed_splay_tree
   value_type predecessor (key_type k);
   value_type successor (key_type k);
   void insert (key_type k, value_type v);
+  void remove (key_type k);
   value_type max ();
   value_type min ();
   int foreach (foreach_fn, void *);
 
  private:
-  /* Helper type for typed_splay_tree::foreach.  */
-  struct closure
-  {
-closure (foreach_fn outer_cb, void *outer_user_data)
-: m_outer_cb (outer_cb), m_outer_user_data (outer_user_data) {}
+  /* Copy and assignment ops are not supported.  */
+  typed_splay_tree (const typed_splay_tree &);
+  typed_splay_tree & operator = (const typed_splay_tree &);
 
-foreach_fn m_outer_cb;
-void *m_outer_user_data;
+  typedef key_type splay_tree_key;
+  typedef value_type splay_tree_value;
+
+  /* The nodes in the splay tree.  */
+  struct splay_tree_node_s {
+/* The key.  */
+splay_tree_key key;
+
+/* The value.  */
+splay_tree_value value;
+
+/* The left and right children, respectively.  */
+splay_tree_node_s *left, *right;
+
+/* Used as temporary value for tree traversals.  */
+splay_tree_node_s *back;
   };
+  typedef splay_tree_node_s *splay_tree_node;
 
-  static int inner_foreach_fn (splay_tree_node node, void *user_data);
+  inline void KDEL (splay_tree_key);
+  inline void VDEL (splay_tree_value);
+  void splay_tree_delete_helper (splay_tree_node);
+  static inline void rotate_left (splay_tree_node *,
+  splay_tree_node, splay_tree_node);
+  static inline void rotate_right (splay_tree_node *,
+   splay_tree_node, splay_tree_node);
+  void splay_tree_splay (splay_tree_key);
+  static int splay_tree_foreach_helper (splay_tree_node,
+	foreach_fn, void*);
+  splay_tree_node splay_tree_insert (splay_tree_key, splay_tree_value);
+  void splay_tree_remove (splay_tree_key key);
+  splay_tree_node splay_tree_lookup (splay_tree_key key);
+  splay_tree_node splay_tree_predecessor (splay_tree_key);
+  splay_tree_node splay_tree_successor (splay_tree_key);
+  splay_tree_node splay_tree_max ();
+  splay_tree_node splay_tree_min ();
 
   static value_type node_to_value (splay_tree_node node);
 
- private:
-  ::splay_tree m_inner;
+  /* The root of the tree.  */
+  splay_tree_node root;
+
+  /* The comparision function.  */
+  compare_fn comp;
+
+  /* The