This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gc-improv] Patch: generate typed allocators
- From: "Laurynas Biveinis" <laurynas dot biveinis at gmail dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 13 Sep 2007 18:38:34 -0700
- Subject: [gc-improv] Patch: generate typed allocators
Hello,
This patch, based on Steven Bosscher's
http://gcc.gnu.org/ml/gcc/2004-01/msg01081.html, does several things:
- adds new GTY option "variable_size" (renamed from Steven's
"size_not_fixed", IMHO positive sounds better than negative);
- annotates rtx_def and tree_node with this option;
- adds a few convenience macros to ggc.h
- make gengtype output allocator definitions for every GC-used
GTY-annotated type, without type tag for now. Simple example on how
they look:
#define ggc_alloc_alias_set_entry() (ggc_internal_alloc (struct
alias_set_entry))
#define ggc_alloc_cleared_alias_set_entry()
(ggc_internal_cleared_alloc (struct alias_set_entry))
#define ggc_alloc_vec_alias_set_entry(n) (ggc_internal_vec_alloc
(struct alias_set_entry, n))
#define ggc_alloc_cleared_vec_alias_set_entry(n)
(ggc_internal_cleared_vec_alloc (struct alias_set_entry, n))
And for variable_size case:
#define ggc_alloc_rtx_def(SIZE) (ggc_internal_sized_alloc (struct
rtx_def, SIZE))
#define ggc_alloc_cleared_rtx_def(SIZE)
(ggc_internal_cleared_sized_alloc (struct rtx_def, SIZE))
#define ggc_alloc_vec_rtx_def(SIZE, n) (ggc_internal_vec_sized_alloc
(struct rtx_def, SIZE, n))
#define ggc_alloc_cleared_vec_rtx_def(SIZE, n)
(ggc_internal_cleared_vec_sized_alloc (struct rtx_def, SIZE, n))
Tested by building stage1 and inspecting gtype-desc.h on
i686-pc-linux-gnu. I am commiting this to gc-improv.
2007-09-13 Laurynas Biveinis <laurynas.biveinis@gmail.com>
* gengtype.c (walk_type): Handle "variable_size" option.
(variable_size_p): New.
(get_tag_string): New.
(write_typed_alloc_end): New.
(write_typed_struct_alloc_def): New.
(write_typed_typedef_alloc_def): New.
(write_typed_alloc_defns): New.
(main): Call write_typed_alloc_defns.
* tree.h (union tree_node): Add GTY option variable_size.
* ggc.h (ggc_internal_alloc): New.
(ggc_internal_cleared_alloc): New.
(ggc_internal_vec_alloc): New.
(ggc_internal_cleared_vec_alloc): New.
(ggc_internal_sized_alloc): New.
(ggc_internal_cleared_sized_alloc): New.
(ggc_internal_cleared_vec_sized_alloc): New.
* rtl.h (struct rtx_def): Add GTY option variable_size.
Index: gengtype.c
===================================================================
--- gengtype.c (revision 128389)
+++ gengtype.c (working copy)
@@ -1940,6 +1940,8 @@
;
else if (strcmp (oo->name, "reorder") == 0)
;
+ else if (strcmp (oo->name, "variable_size") == 0)
+ ;
else
error_at_line (d->line, "unknown option `%s'\n", oo->name);
@@ -2854,6 +2856,101 @@
oprintf (header_file, "};\n");
}
+static bool
+variable_size_p (const type_p s)
+{
+ options_p o;
+ for (o = s->u.s.opt; o; o = o->next)
+ if (strcmp (o->name, "variable_size") == 0)
+ return true;
+ return false;
+}
+
+static const char *
+get_tag_string (const type_p s)
+{
+ if (s->kind == TYPE_STRUCT || s->kind == TYPE_LANG_STRUCT)
+ return "struct ";
+ if (s->kind == TYPE_UNION)
+ return "union ";
+ return "";
+}
+
+static void
+write_typed_alloc_end (const type_p s,
+ const char * const allocator_type,
+ bool is_vector)
+{
+ const bool variable_size = variable_size_p (s);
+ const char * const type_tag = get_tag_string (s);
+
+ oprintf (header_file, "(ggc_internal_%s%salloc (", allocator_type,
+ (variable_size ? "sized_" : ""));
+ oprintf (header_file, "%s%s", type_tag, s->u.s.tag);
+ oprintf (header_file, "%s", variable_size ? ", SIZE" : "");
+ oprintf (header_file, "%s", is_vector ? ", n" : "");
+ oprintf (header_file, "))\n");
+}
+
+static void
+write_typed_struct_alloc_def (const type_p s,
+ const char * const allocator_type,
+ bool is_vector)
+{
+ const bool variable_size = variable_size_p (s);
+ const bool two_args = variable_size && is_vector;
+
+ oprintf (header_file, "#define ggc_alloc_%s%s", allocator_type, s->u.s.tag);
+ oprintf (header_file, "(%s%s%s) ", (variable_size ? "SIZE" : ""),
+ (two_args ? ", " : ""), (is_vector ? "n" : ""));
+ write_typed_alloc_end (s, allocator_type, is_vector);
+}
+
+static void
+write_typed_typedef_alloc_def (const pair_p p,
+ const char * const allocator_type,
+ bool is_vector)
+{
+ const type_p s = p->type;
+
+ oprintf (header_file, "#define ggc_alloc_%s%s ", allocator_type, p->name);
+ oprintf (header_file, "(%s) ", is_vector ? "n" : "");
+ write_typed_alloc_end (s, allocator_type, is_vector);
+}
+
+static void
+write_typed_alloc_defns (const type_p structures, const pair_p typedefs)
+{
+ type_p s;
+ pair_p p;
+
+ oprintf (header_file, "\n/* Allocators for known structs and unions. */\n");
+ for (s = structures; s; s = s->next)
+ {
+ if (s->gc_used != GC_POINTED_TO && s->gc_used != GC_MAYBE_POINTED_TO)
+ continue;
+ write_typed_struct_alloc_def (s, "", false);
+ write_typed_struct_alloc_def (s, "cleared_", false);
+ write_typed_struct_alloc_def (s, "vec_", true);
+ write_typed_struct_alloc_def (s, "cleared_vec_", true);
+ }
+ oprintf (header_file, "\n/* Allocators for known typedefs. */\n");
+ for (p = typedefs; p; p = p->next)
+ {
+ s = p->type;
+ if (s->gc_used != GC_POINTED_TO && s->gc_used != GC_MAYBE_POINTED_TO)
+ continue;
+ if (!UNION_OR_STRUCT_P (s))
+ continue;
+ if (strcmp (p->name, s->u.s.tag) == 0)
+ continue;
+ write_typed_typedef_alloc_def (p, "", false);
+ write_typed_typedef_alloc_def (p, "cleared_", false);
+ write_typed_typedef_alloc_def (p, "vec_", true);
+ write_typed_typedef_alloc_def (p, "cleared_vec_", true);
+ }
+}
+
/* Might T contain any non-pointer elements? */
static int
@@ -3552,6 +3649,7 @@
open_base_files ();
write_enum_defn (structures, param_structs);
+ write_typed_alloc_defns (structures, typedefs);
write_types (structures, param_structs, &ggc_wtd);
write_types (structures, param_structs, &pch_wtd);
write_local (structures, param_structs);
Index: tree.h
===================================================================
--- tree.h (revision 128389)
+++ tree.h (working copy)
@@ -3410,7 +3410,7 @@
for various types of node. */
union tree_node GTY ((ptr_alias (union lang_tree_node),
- desc ("tree_node_structure (&%h)")))
+ desc ("tree_node_structure (&%h)"), variable_size))
{
struct tree_base GTY ((tag ("TS_BASE"))) base;
struct tree_common GTY ((tag ("TS_COMMON"))) common;
Index: ggc.h
===================================================================
--- ggc.h (revision 128389)
+++ ggc.h (working copy)
@@ -232,6 +232,17 @@
#define GGC_CNEWVAR(T, S) ((T *) ggc_alloc_cleared ((S)))
#define GGC_RESIZEVEC(T, P, N) ((T *) ggc_realloc ((P), (N) * sizeof (T)))
+#define ggc_internal_alloc(T) ((T *) ggc_alloc (sizeof (T)))
+#define ggc_internal_cleared_alloc(T) ((T *) ggc_alloc_cleared (sizeof (T)))
+#define ggc_internal_vec_alloc(T, c) ((T *) ggc_alloc (sizeof (T) * c))
+#define ggc_internal_cleared_vec_alloc(T, c) \
+ ((T *) ggc_alloc_cleared (sizeof (T) * c))
+#define ggc_internal_sized_alloc(T, n) ((T *) ggc_alloc (n))
+#define ggc_internal_cleared_sized_alloc(T, n) ((T *) ggc_alloc_cleared (n))
+#define ggc_internal_cleared_vec_sized_alloc(T, n, c) ((T *) \
+ ggc_alloc_cleared ((n) * (c)))
+
#define ggc_alloc_rtvec(NELT) \
((rtvec) ggc_alloc_zone (sizeof (struct rtvec_def) + ((NELT) - 1) \
* sizeof (rtx), &rtl_zone))
Index: rtl.h
===================================================================
--- rtl.h (revision 128389)
+++ rtl.h (working copy)
@@ -234,7 +234,7 @@
/* RTL expression ("rtx"). */
struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"),
- chain_prev ("RTX_PREV (&%h)")))
+ chain_prev ("RTX_PREV (&%h)"), variable_size))
{
/* The kind of expression this is. */
ENUM_BITFIELD(rtx_code) code: 16;
--
Laurynas