public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Patch: New GTY ((atomic)) option
@ 2011-05-16  9:01 Nicola Pero
  2011-05-16  9:11 ` Gabriel Dos Reis
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Nicola Pero @ 2011-05-16  9:01 UTC (permalink / raw)
  To: gcc-patches

This patch adds a new GTY option, "atomic", which is similar to the identical option you have with Boehm GC
and which can be used with pointers to inform the GC/PCH machinery that they point to an area of memory that
contains no pointers (and hence needs no scanning).

The reason for adding this option is that, without it, it seems to be (surprisingly) impossible
to write code that keeps a GC pointer to a plain array of C stuff such as integers.  In my case,
I was experimenting with hash tables that can automatically cache hash values.  So I needed a plain
C array to store the cached hash values, but found that it is currently unsupported by GC/PCH! :-(

That is, at the moment you can't have a struct such as the following one --

struct GTY(()) my_struct {
  ...
  unsigned int * some_ints;
  size_t count;
  ...
};

because gengtype rejects it with the error "field `(*x).some_ints' is pointer to unimplemented type".

This patch basically implements it, but at this stage requires you to explicitly tell gengtype that the
pointer is atomic (and that is safe for gengtype to ignore the memory it points to).  So, the following
now works as expected --

struct GTY(()) my_struct {
  ...
  unsigned int * GTY((atomic)) some_ints;
  size_t count;
  ...
};

A next, nice step would be to have gengtype automatically mark as "atomic" any pointers that gengtype can safely determine
point to an area of memory that never contains any pointers.  But that's slightly more complicated (eg, currently
gengtype makes no difference between "unsigned int" and "void", hence "unsigned int *" and "void *" would be treated
the same, while you'd want the first one to be automatically marked as atomic, and the second one to generate an error
as gengtype has no way to determine if it's atomic or not - unless it's explicitly marked as atomic of course), so for now
I haven't implemented it; it could be a follow-up patch (even after implementing it, the explicit "atomic" option
would remain useful for "void *" pointers and such like, so it's a good starting point).

Btw, there are a few existing pointers in GCC that could be marked as atomic, for example the field "su" of struct
function in function.h.  The advantage of marking them as atomic would be a slight speedup of the GC marking by saving
a function call each time one of these structs is being walked; I suspect that alone wouldn't make any visibile difference
in practice, but I haven't done any profiling or benchmarking to know for sure.

I have done some testing of this patch, and I want to do some more before I commit.  If anyone has good ideas on how
to perform throughout testing, they are welcome. :-)

Ok to commit ?

Thanks

PS: This patch does not include support for marking root/global variables with "atomic" (neither manually nor automatically);
only fields in a struct.  That would be useful too, but I'm leaving it for yet another patch.

2011-05-16  Nicola Pero  <nicola.pero@meta-innovation.com>

        * gengtype.c (walk_type): Implemented "atomic" GTY option.
        * doc/gty.texi (GTY Options): Document "atomic" GTY option.

Index: doc/gty.texi
===================================================================
--- doc/gty.texi        (revision 173768)
+++ doc/gty.texi        (working copy)
@@ -383,6 +383,42 @@ could be calculated as follows:
   size_t size = sizeof (struct sorted_fields_type) + n * sizeof (tree);
 @end smallexample
 
+@findex atomic
+@item atomic
+
+The @code{atomic} option can only be used with pointers.  It informs
+the GC machinery that the memory that the pointer points to does not
+contain any pointers, and hence it should be treated by the GC and PCH
+machinery as an ``atomic'' block of memory that does not need to be
+examined.  In particular, the machinery will not scan that memory for
+pointers to mark them as reachable (when marking pointers for GC) or
+to relocate them (when writing a PCH file).
+
+The @code{atomic} option must be used with great care, because all
+sorts of problem can occur if used incorrectly, that is, if the memory
+the pointer points to does actually contain a pointer.
+
+Here is an example of how to use it:
+@smallexample
+struct GTY(()) my_struct @{
+  int number_of_elements;
+  unsigned int GTY ((atomic)) * elements;
+@};
+@end smallexample
+In this case, @code{elements} is a pointer under GC, and the memory it
+points to needs to be allocated using the Garbage Collector, and will
+be freed automatically by the Garbage Collector when it is no longer
+referenced.  But the memory that the pointer points to is an array of
+@code{unsigned int} elements, and the GC does not need, and indeed
+must not, try to scan it to find pointers to mark or relocate, which
+is why it is marked with the @code{atomic} option.
+
+Note that, currently, global variables can not be marked with
+@code{atomic}; only fields of a struct can.  This is a known
+limitation.  It would be useful to be able to mark global pointers
+with @code{atomic} to make the PCH machinery aware of them so that
+they are saved and restored correctly to PCH files.
+
 @findex special
 @item special ("@var{name}")
 

Index: gengtype.c
===================================================================
--- gengtype.c  (revision 173768)
+++ gengtype.c  (working copy)
@@ -2386,6 +2386,7 @@ walk_type (type_p t, struct walk_type_data *d)
   int maybe_undef_p = 0;
   int use_param_num = -1;
   int use_params_p = 0;
+  int atomic_p = 0;
   options_p oo;
   const struct nested_ptr_data *nested_ptr_d = NULL;
 
@@ -2415,6 +2416,8 @@ walk_type (type_p t, struct walk_type_data *d)
       ;
     else if (strcmp (oo->name, "skip") == 0)
       ;
+    else if (strcmp (oo->name, "atomic") == 0)
+      atomic_p = 1;
     else if (strcmp (oo->name, "default") == 0)
       ;
     else if (strcmp (oo->name, "param_is") == 0)
@@ -2480,6 +2483,12 @@ walk_type (type_p t, struct walk_type_data *d)
       return;
     }
 
+  if (atomic_p && (t->kind != TYPE_POINTER))
+    {
+      error_at_line (d->line, "field `%s' has invalid option `atomic'\n", d->val);
+      return;
+    }
+
   switch (t->kind)
     {
     case TYPE_SCALAR:
@@ -2495,6 +2504,25 @@ walk_type (type_p t, struct walk_type_data *d)
            break;
          }
 
+       /* If a pointer type is marked as "atomic", we process the
+          field itself, but we don't walk the data that they point to.
+          
+          There are two main cases where we walk types: to mark
+          pointers that are reachable, and to relocate pointers when
+          writing a PCH file.  In both cases, an atomic pointer is
+          itself marked or relocated, but the memory that it points
+          to is left untouched.  In the case of PCH, that memory will
+          be read/written unchanged to the PCH file.  */
+       if (atomic_p)
+         {
+           oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
+           d->indent += 2;
+           d->process_field (t, d);
+           d->indent -= 2;
+           oprintf (d->of, "%*s}\n", d->indent, "");
+           break;
+         }
+
        if (!length)
          {
            if (!UNION_OR_STRUCT_P (t->u.p)


^ permalink raw reply	[flat|nested] 15+ messages in thread
[parent not found: <4dd0e5bb.072f440a.7c5a.417d@mx.google.com>]
* Re: Patch: New GTY ((atomic)) option
@ 2011-05-20 11:42 Nicola Pero
  2011-05-23  9:29 ` Laurynas Biveinis
  0 siblings, 1 reply; 15+ messages in thread
From: Nicola Pero @ 2011-05-20 11:42 UTC (permalink / raw)
  To: Basile Starynkevitch; +Cc: Laurynas Biveinis, gcc-patches

> However, did you check that the atomic qualifier is correctly written &
> re-read in the state (I believe you did, otherwise it probably won't
> work). This is needed for plugins using it, or using atomic qualified
> fields of existing (or future) structures.

Yes.  String options are written as they are, no particular changes are
needed. ;-)

I'd like to show you a testcase, but, as you discuss in your other email, we can't
really write GTY testcases at this stage.  So here is a walked tour of how to test
the new atomic option --

 * apply the GTY ((atomic)) patch (obviously)

 * add the "GTY ((atomic))" option to field 'su' of struct 'function' in function.h
(that field is atomic, so you can mark it "atomic" and it should work)

 * rebuild everything from scratch (bootstrap the compiler)

 * gtype.state now contains, some time after (!pair "su", the lines

(!srcfileloc  "function.h" 516)

(!options
(!option atomic string  "")
)

btw, we should probably improve gtype.state; indentation would be nice :-) ...

 * gtype-desc.c now contains

void
gt_ggc_mx_function (void *x_p)
{
  struct function * const x = (struct function *)x_p;
  if (ggc_test_and_set_mark (x))
    {
      gt_ggc_m_9eh_status ((*x).eh);
      gt_ggc_m_18control_flow_graph ((*x).cfg);
      gt_ggc_m_12gimple_seq_d ((*x).gimple_body);
      gt_ggc_m_9gimple_df ((*x).gimple_df);
      gt_ggc_m_5loops ((*x).x_current_loops);
      if ((*x).su != NULL) {
        ggc_mark ((*x).su);
      }
      gt_ggc_m_9tree_node ((*x).decl);
      gt_ggc_m_9tree_node ((*x).static_chain_decl);
      gt_ggc_m_9tree_node ((*x).nonlocal_goto_save_area);
      gt_ggc_m_11VEC_tree_gc ((*x).local_decls);
      gt_ggc_m_16machine_function ((*x).machine);
      gt_ggc_m_17language_function ((*x).language);
      gt_ggc_m_P9tree_node4htab ((*x).used_types_hash);
    }
}

as you notice, the "su" field is only marked, but not followed.  Normally that same marking
function would be

void
gt_ggc_mx_function (void *x_p)
{
  struct function * const x = (struct function *)x_p;
  if (ggc_test_and_set_mark (x))
    {
      gt_ggc_m_9eh_status ((*x).eh);
      gt_ggc_m_18control_flow_graph ((*x).cfg);
      gt_ggc_m_12gimple_seq_d ((*x).gimple_body);
      gt_ggc_m_9gimple_df ((*x).gimple_df);
      gt_ggc_m_5loops ((*x).x_current_loops);
      gt_ggc_m_11stack_usage ((*x).su);
      gt_ggc_m_9tree_node ((*x).decl);
      gt_ggc_m_9tree_node ((*x).static_chain_decl);
      gt_ggc_m_9tree_node ((*x).nonlocal_goto_save_area);
      gt_ggc_m_11VEC_tree_gc ((*x).local_decls);
      gt_ggc_m_16machine_function ((*x).machine);
      gt_ggc_m_17language_function ((*x).language);
      gt_ggc_m_P9tree_node4htab ((*x).used_types_hash);
    }
}

which would call the gt_ggc_mx_stack_usage() function, which does nothing but mark the pointer in this case
(since the field actually is atomic), but would in other cases mark the children as well.  So, in this case
marking the field as "atomic" results in a small optimization when doing the GC marking stage.  In other cases,
when gengtype doesn't know how to inspect the memory pointed to (eg, "unsigned int *"), then it would make it
possible to use GC for the pointer.

PCH traversing is similar.

To test that the GC marking actually works, I mostly bootstrap the compiler first, then test compiling a few
testcases using --param ggc-min-expand=0 --param ggc-min-heapsize=0.  This is by no means a full test; if you
or Laurynas have any suggestions on how to test better, they'd be welcome. :-)

Thanks

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2023-07-06  6:07 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-16  9:01 Patch: New GTY ((atomic)) option Nicola Pero
2011-05-16  9:11 ` Gabriel Dos Reis
2011-05-16  9:45   ` Nathan Froyd
2011-05-16 10:00     ` Gabriel Dos Reis
2011-05-16 12:14       ` Nicola Pero
2011-05-16 13:05 ` Laurynas Biveinis
2011-05-19 19:46   ` Nicola Pero
2011-05-20  2:06     ` Basile Starynkevitch
2011-05-20  3:03       ` Basile Starynkevitch
2011-05-20  9:47     ` Laurynas Biveinis
2023-07-05 16:24 ` GGC, GTY: No pointer walking for 'atomic' in PCH 'gt_pch_note_object' (was: Patch: New GTY ((atomic)) option) Thomas Schwinge
2023-07-06  6:07   ` Richard Biener
     [not found] <4dd0e5bb.072f440a.7c5a.417d@mx.google.com>
2011-05-16 12:21 ` Patch: New GTY ((atomic)) option Nicola Pero
2011-05-20 11:42 Nicola Pero
2011-05-23  9:29 ` Laurynas Biveinis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).