diff options
author | geoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-16 18:33:23 +0000 |
---|---|---|
committer | geoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-16 18:33:23 +0000 |
commit | c849df63447c7b03c27d991e60a26e9b98b57013 (patch) | |
tree | c61dabe0ee2f12a433921e41d3b1799e3b26b2f5 /gcc | |
parent | 7d89a8eb42b1ab1ce5a769e32eec2e0a4eefc081 (diff) | |
download | gcc-c849df63447c7b03c27d991e60a26e9b98b57013.tar.gz |
Index: gcc/ChangeLog
2002-09-12 Geoffrey Keating <geoffk@apple.com>
* ggc-common.c (ggc_mark_rtx_children_1): Update for changed name
mangling.
The following changes are merged from pch-branch:
* doc/gty.texi (GTY Options): Document %a.
* gengtype.c (do_scalar_typedef): New function.
(process_gc_options): Handle `length' option.
(set_gc_used_type): A pointer to an array of structures doesn't
qualify as a pointer to a structure.
(output_escaped_param): Add `%a' escape.
(write_gc_structure_fields): Allow 'desc' on array of unions.
(main): Define `uint8', `jword' and `JCF_u2' as scalars; use
do_scalar_typedef.
* gengtype.c (enum rtx_code): Make global.
(rtx_format): Make global.
(rtx_next): New.
(gen_rtx_next): New.
(write_rtx_next): New.
(adjust_field_rtx_def): Skip fields marked by chain_next.
(open_base_files): Delete redundant prototype.
(write_enum_defn): New.
(output_mangled_typename): Correct abort call.
(write_gc_marker_routine_for_structure): Handle chain_next and
chain_prev options.
(finish_root_table): Don't output redundant \n.
(main): Call gen_rtx_next, write_rtx_next, write_enum_defn.
* c-tree.h (union lang_tree_node): Add chain_next option.
* gengtype.h (NUM_PARAM): New definition.
(struct type): For TYPE_PARAM_STRUCT, allow multiple parameters.
* gengtype.c (find_param_structure): New.
(adjust_field_type): Handle param<n>_is option.
(process_gc_options): Detect use_params option. Update callers.
(set_gc_used_type): Add 'param' parameter, update callers. Handle
'use_params' option.
(open_base_files): Add splay-tree.h to list of files included.
(output_mangled_typename): New.
(write_gc_structure_fields): Update 'param' parameter to support
multiple parameters. Change name mangling. Allow parameterized
fields to have an apparent scalar type. Handle param<n>_is options,
use_param option.
(write_gc_marker_routine_for_structure): Update for change to name
mangling. Better guess the output file for parameterized types.
(write_gc_types): Update for change to name mangling.
(write_gc_root): Update for change to name mangling. Handle (ignore)
param<n>_is options.
* doc/gty.texi (GTY Options): Add description of param<n>_is
options, use_params option.
* ggc.h (ggc_mark_rtx): Update for changed name mangling.
* gengtype-lex.l: Produce token for param<n>_is.
* gengtype-yacc.y: Parse param<n>_is.
* gengtype.c (adjust_field_tree_exp): Don't name a variable 'rindex'.
* rtl.c: Update comment describing rtx_format.
* rtl.h (union rtunion): Separate definition and typedef.
(struct rtx_def): Use gengtype to mark.
* Makefile.in (gengtype.o): Also depend on rtl.def.
* ggc.h (ggc_mark_rtx_children): Delete prototype.
(ggc_mark_rtx): Change to alias of gengtype-generated routine.
* ggc-common.c (ggc_mark_rtx_children): Delete.
(ggc_mark_rtx_children_1): Delete.
(gt_ggc_m_rtx_def): Delete.
* gengtype.c (adjust_field_rtx_def): New.
(adjust_field_type): Call adjust_field_rtx_def.
(write_gc_structure_fields): Add 'default' case to switch if none
is specified; remove unused code.
* tree.h (struct tree_exp): Update for change to meaning
of special.
* gengtype.c (adjust_field_tree_exp): New function.
(adjust_field_type): Handle `tree_exp' special here.
(write_gc_structure_fields): Don't handle `tree_exp' special here.
Handle new `dot' option.
* gengtype.h: Make `info' a pointer-to-const.
* gengtype-yacc.y (yacc_ids): Use xasprintf.
* gengtype.c (write_gc_structure_fields): Remove implementation
of `always' option, add `default' option.
* doc/gty.texi (GTY Options): Remove documentation of `always',
add `default'.
Index: gcc/cp/ChangeLog
2002-09-12 Geoffrey Keating <geoffk@apple.com>
* cp-tree.h (union lang_tree_node): Add chain_next option.
Index: gcc/f/ChangeLog
2002-09-12 Geoffrey Keating <geoffk@apple.com>
* com.c (union lang_tree_node): Add chain_next option.
Index: gcc/java/ChangeLog
2002-09-12 Geoffrey Keating <geoffk@apple.com>
* java-tree.h (union lang_tree_node): Add chain_next option.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@57206 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 87 | ||||
-rw-r--r-- | gcc/Makefile.in | 3 | ||||
-rw-r--r-- | gcc/c-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/doc/gty.texi | 42 | ||||
-rw-r--r-- | gcc/f/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/f/com.c | 3 | ||||
-rw-r--r-- | gcc/gengtype-lex.l | 5 | ||||
-rw-r--r-- | gcc/gengtype-yacc.y | 9 | ||||
-rw-r--r-- | gcc/gengtype.c | 1081 | ||||
-rw-r--r-- | gcc/gengtype.h | 6 | ||||
-rw-r--r-- | gcc/ggc-common.c | 135 | ||||
-rw-r--r-- | gcc/ggc.h | 14 | ||||
-rw-r--r-- | gcc/java/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 3 | ||||
-rw-r--r-- | gcc/rtl.c | 1 | ||||
-rw-r--r-- | gcc/rtl.h | 30 | ||||
-rw-r--r-- | gcc/tree.h | 2 |
19 files changed, 1054 insertions, 385 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9efa47f3cff..47c56942e7e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,90 @@ +2002-09-16 Geoffrey Keating <geoffk@apple.com> + + * ggc-common.c (ggc_mark_rtx_children_1): Update for changed name + mangling. + + The following changes are merged from pch-branch: + + * doc/gty.texi (GTY Options): Document %a. + * gengtype.c (do_scalar_typedef): New function. + (process_gc_options): Handle `length' option. + (set_gc_used_type): A pointer to an array of structures doesn't + qualify as a pointer to a structure. + (output_escaped_param): Add `%a' escape. + (write_gc_structure_fields): Allow 'desc' on array of unions. + (main): Define `uint8', `jword' and `JCF_u2' as scalars; use + do_scalar_typedef. + + * gengtype.c (enum rtx_code): Make global. + (rtx_format): Make global. + (rtx_next): New. + (gen_rtx_next): New. + (write_rtx_next): New. + (adjust_field_rtx_def): Skip fields marked by chain_next. + (open_base_files): Delete redundant prototype. + (write_enum_defn): New. + (output_mangled_typename): Correct abort call. + (write_gc_marker_routine_for_structure): Handle chain_next and + chain_prev options. + (finish_root_table): Don't output redundant \n. + (main): Call gen_rtx_next, write_rtx_next, write_enum_defn. + * c-tree.h (union lang_tree_node): Add chain_next option. + + * gengtype.h (NUM_PARAM): New definition. + (struct type): For TYPE_PARAM_STRUCT, allow multiple parameters. + * gengtype.c (find_param_structure): New. + (adjust_field_type): Handle param<n>_is option. + (process_gc_options): Detect use_params option. Update callers. + (set_gc_used_type): Add 'param' parameter, update callers. Handle + 'use_params' option. + (open_base_files): Add splay-tree.h to list of files included. + (output_mangled_typename): New. + (write_gc_structure_fields): Update 'param' parameter to support + multiple parameters. Change name mangling. Allow parameterized + fields to have an apparent scalar type. Handle param<n>_is options, + use_param option. + (write_gc_marker_routine_for_structure): Update for change to name + mangling. Better guess the output file for parameterized types. + (write_gc_types): Update for change to name mangling. + (write_gc_root): Update for change to name mangling. Handle (ignore) + param<n>_is options. + * doc/gty.texi (GTY Options): Add description of param<n>_is + options, use_params option. + * ggc.h (ggc_mark_rtx): Update for changed name mangling. + * gengtype-lex.l: Produce token for param<n>_is. + * gengtype-yacc.y: Parse param<n>_is. + + * gengtype.c (adjust_field_tree_exp): Don't name a variable 'rindex'. + + * rtl.c: Update comment describing rtx_format. + * rtl.h (union rtunion): Separate definition and typedef. + (struct rtx_def): Use gengtype to mark. + * Makefile.in (gengtype.o): Also depend on rtl.def. + * ggc.h (ggc_mark_rtx_children): Delete prototype. + (ggc_mark_rtx): Change to alias of gengtype-generated routine. + * ggc-common.c (ggc_mark_rtx_children): Delete. + (ggc_mark_rtx_children_1): Delete. + (gt_ggc_m_rtx_def): Delete. + * gengtype.c (adjust_field_rtx_def): New. + (adjust_field_type): Call adjust_field_rtx_def. + (write_gc_structure_fields): Add 'default' case to switch if none + is specified; remove unused code. + + * tree.h (struct tree_exp): Update for change to meaning + of special. + * gengtype.c (adjust_field_tree_exp): New function. + (adjust_field_type): Handle `tree_exp' special here. + (write_gc_structure_fields): Don't handle `tree_exp' special here. + Handle new `dot' option. + + * gengtype.h: Make `info' a pointer-to-const. + * gengtype-yacc.y (yacc_ids): Use xasprintf. + + * gengtype.c (write_gc_structure_fields): Remove implementation + of `always' option, add `default' option. + * doc/gty.texi (GTY Options): Remove documentation of `always', + add `default'. + 2002-09-16 Hans-Peter Nilsson <hp@bitrange.com> * output.h: Remove #ifdef RTX_CODE and #ifdef TREE_CODE. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index df9ba312cc3..d95232419f6 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2053,7 +2053,8 @@ gengtype$(build_exeext) : gengtype.o gengtype-lex.o gengtype-yacc.o \ $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \ gengtype.o gengtype-lex.o gengtype-yacc.o $(HOST_LIBS) -gengtype.o : gengtype.c gengtype.h $(HCONFIG_H) $(SYSTEM_H) real.h gtyp-gen.h +gengtype.o : gengtype.c gengtype.h $(HCONFIG_H) $(SYSTEM_H) real.h rtl.def \ + gtyp-gen.h $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \ $(srcdir)/gengtype.c $(OUTPUT_OPTION) diff --git a/gcc/c-tree.h b/gcc/c-tree.h index 531cc284559..159c235224e 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -48,7 +48,8 @@ struct lang_identifier GTY(()) /* The resulting tree type. */ union lang_tree_node - GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"))) + GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"), + chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)"))) { union tree_node GTY ((tag ("0"), desc ("tree_node_structure (&%h)"))) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a4ddb5a6dc8..4a480412cf5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,7 @@ +2002-09-16 Geoffrey Keating <geoffk@apple.com> + + * cp-tree.h (union lang_tree_node): Add chain_next option. + 2002-09-16 Nathan Sidwell <nathan@codesourcery.com> * parse.y (parse_finish_call_expr): Check lookup_member result. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 96c615d5643..bbfdd3a889c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -505,7 +505,8 @@ enum cp_tree_node_structure_enum { }; /* The resulting tree type. */ -union lang_tree_node GTY((desc ("cp_tree_node_structure (&%h)"))) +union lang_tree_node GTY((desc ("cp_tree_node_structure (&%h)"), + chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)"))) { struct tree_common GTY ((tag ("TS_CP_COMMON"))) common; union tree_node GTY ((tag ("TS_CP_GENERIC"), diff --git a/gcc/doc/gty.texi b/gcc/doc/gty.texi index cbd9caa516c..e0d9a33cde6 100644 --- a/gcc/doc/gty.texi +++ b/gcc/doc/gty.texi @@ -72,6 +72,10 @@ immediately contains the current structure. @item %0 This expands to an expression that evaluates to the outermost structure that contains the current structure. +@item %a +This expands to the string of the form @code{[i1][i2]...} that indexes +the array item currently being marked. For instance, if the field +being marked is @code{foo}, then @code{%1.foo%a} is the same as @code{%h}. @end table The available options are: @@ -121,10 +125,10 @@ field really isn't ever used. @findex desc @findex tag -@findex always +@findex default @item desc @itemx tag -@itemx always +@itemx default The type machinery needs to be told which field of a @code{union} is currently active. This is done by giving each field a constant @code{tag} @@ -146,7 +150,9 @@ it discriminates. Use @code{%1} to mean the structure containing it. (There are no escapes available to the @code{tag} option, since it's supposed to be a constant.) -You can use @code{always} to mean that this field is always used. +Each @code{tag} should be different. If no @code{tag} is matched, +the field marked with @code{default} is used if there is one, otherwise +no field in the union will be marked. @findex param_is @findex use_param @@ -154,15 +160,39 @@ You can use @code{always} to mean that this field is always used. @itemx use_param Sometimes it's convenient to define some data structure to work on -generic pointers (that is, @code{PTR}), and then use it with specific types. -@code{param_is} specifies the real type pointed to, and @code{use_param} -says where in the generic data structure that type should be put. +generic pointers (that is, @code{PTR}) and then use it with a specific +type. @code{param_is} specifies the real type pointed to, and +@code{use_param} says where in the generic data structure that type +should be put. For instance, to have a @code{htab_t} that points to trees, one should write @verbatim htab_t GTY ((param_is (union tree_node))) ict; @end verbatim +@findex param@var{n}_is +@findex use_param@var{n} +@item param@var{n}_is +@itemx use_param@var{n} + +In more complicated cases, the data structure might need to work on +several different types, which might not necessarily all be pointers. +For this, @code{param1_is} through @code{param9_is} may be used to +specify the real type of a field identified by @code{use_param1} through +@code{use_param9}. + +@findex use_params +@item use_params + +When a structure contains another structure that is parameterised, +there's no need to do anything special, the inner stucture inherits the +parameters of the outer one. When a structure contains a pointer to a +parameterised structure, the type machinery won't automatically detect +this (it could, it just doesn't yet), so it's necessary to tell it that +the pointed-to structure should use the same parameters as the outer +structure. This is done by marking the pointer with the +@code{use_params} option. + @findex deletable @item deletable diff --git a/gcc/f/ChangeLog b/gcc/f/ChangeLog index 658babde4cb..e71c8c72e32 100644 --- a/gcc/f/ChangeLog +++ b/gcc/f/ChangeLog @@ -1,3 +1,7 @@ +2002-09-16 Geoffrey Keating <geoffk@apple.com> + + * com.c (union lang_tree_node): Add chain_next option. + 2002-09-16 Richard Henderson <rth@redhat.com> * target.c (ffetarget_real1): Don't pass FFETARGET_ATOF_ diff --git a/gcc/f/com.c b/gcc/f/com.c index 5a6bc7e8d28..931858afac1 100644 --- a/gcc/f/com.c +++ b/gcc/f/com.c @@ -605,7 +605,8 @@ struct lang_identifier GTY(()) /* The resulting tree type. */ union lang_tree_node - GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"))) + GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"), + chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)"))) { union tree_node GTY ((tag ("0"), desc ("tree_node_structure (&%h)"))) diff --git a/gcc/gengtype-lex.l b/gcc/gengtype-lex.l index bd848a7da0d..91cdde29580 100644 --- a/gcc/gengtype-lex.l +++ b/gcc/gengtype-lex.l @@ -203,8 +203,11 @@ ITYPE {IWORD}({WS}{IWORD})* "struct"/[^[:alnum:]_] { return STRUCT; } "enum"/[^[:alnum:]_] { return ENUM; } "ptr_alias"/[^[:alnum:]_] { return ALIAS; } -"param_is"/[^[:alnum:]_] { return PARAM_IS; } [0-9]+ { return NUM; } +"param"[0-9]*"_is"/[^[:alnum:]_] { + yylval.s = xmemdup (yytext, yyleng, yyleng+1); + return PARAM_IS; +} {IWORD}({WS}{IWORD})*/[^[:alnum:]_] | "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" { diff --git a/gcc/gengtype-yacc.y b/gcc/gengtype-yacc.y index 3ff92d345ef..87837b407be 100644 --- a/gcc/gengtype-yacc.y +++ b/gcc/gengtype-yacc.y @@ -42,7 +42,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA %token STRUCT "struct" %token ENUM "enum" %token ALIAS "ptr_alias" -%token PARAM_IS "param_is" +%token <s>PARAM_IS %token NUM %token PERCENTPERCENT "%%" %token <t>SCALAR @@ -174,8 +174,7 @@ yacc_ids: /* empty */ p->opt = xmalloc (sizeof (*(p->opt))); p->opt->name = "tag"; p->opt->next = NULL; - p->opt->info = xmalloc (3 + strlen ($2)); - sprintf (p->opt->info, "'%s'", $2); + p->opt->info = xasprintf ("'%s'", $2); $$ = p; } ; @@ -263,14 +262,14 @@ options: GTY_TOKEN '(' '(' optionseqopt ')' ')' type_option : ALIAS { $$ = "ptr_alias"; } | PARAM_IS - { $$ = "param_is"; } + { $$ = $1; } ; option: type_option '(' type ')' { options_p o = xmalloc (sizeof (*o)); o->name = $1; - o->info = $3; + o->info = adjust_field_type ($3, NULL); $$ = o; } | ID '(' STRING ')' diff --git a/gcc/gengtype.c b/gcc/gengtype.c index f180a1fd41e..9ec9863de8c 100644 --- a/gcc/gengtype.c +++ b/gcc/gengtype.c @@ -26,10 +26,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA /* Nonzero iff an error has occurred. */ static int hit_error = 0; +static void gen_rtx_next PARAMS ((void)); +static void write_rtx_next PARAMS ((void)); static void open_base_files PARAMS ((void)); static void close_output_files PARAMS ((void)); - /* Report an error at POS, printing MSG. */ void @@ -89,6 +90,12 @@ static type_p structures; static type_p param_structs; static pair_p variables; +static void do_scalar_typedef PARAMS ((const char *, struct fileloc *)); +static type_p find_param_structure + PARAMS ((type_p t, type_p param[NUM_PARAM])); +static type_p adjust_field_tree_exp PARAMS ((type_p t, options_p opt)); +static type_p adjust_field_rtx_def PARAMS ((type_p t, options_p opt)); + /* Define S as a typedef to T at POS. */ void @@ -118,6 +125,16 @@ do_typedef (s, t, pos) typedefs = p; } +/* Define S as a typename of a scalar. */ + +static void +do_scalar_typedef (s, pos) + const char *s; + struct fileloc *pos; +{ + do_typedef (s, create_scalar_type (s, strlen (s)), pos); +} + /* Return the type previously defined for S. Use POS to report errors. */ type_p @@ -235,6 +252,34 @@ find_structure (name, isunion) return s; } +/* Return the previously-defined parameterised structure for structure + T and parameters PARAM, or a new parameterised empty structure or + union if none was defined previously. */ + +static type_p +find_param_structure (t, param) + type_p t; + type_p param[NUM_PARAM]; +{ + type_p res; + + for (res = param_structs; res; res = res->next) + if (res->u.param_struct.stru == t + && memcmp (res->u.param_struct.param, param, + sizeof (type_p) * NUM_PARAM) == 0) + break; + if (res == NULL) + { + res = xcalloc (1, sizeof (*res)); + res->kind = TYPE_PARAM_STRUCT; + res->next = param_structs; + param_structs = res; + res->u.param_struct.stru = t; + memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM); + } + return res; +} + /* Return a scalar type with name NAME. */ type_p @@ -280,13 +325,420 @@ create_array (t, len) return v; } +/* Add a variable named S of type T with options O defined at POS, + to `variables'. */ + +void +note_variable (s, t, o, pos) + const char *s; + type_p t; + options_p o; + struct fileloc *pos; +{ + pair_p n; + n = xmalloc (sizeof (*n)); + n->name = s; + n->type = t; + n->line = *pos; + n->opt = o; + n->next = variables; + variables = n; +} + +enum rtx_code { +#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM , +#include "rtl.def" +#undef DEF_RTL_EXPR + NUM_RTX_CODE +}; + +/* We really don't care how long a CONST_DOUBLE is. */ +#define CONST_DOUBLE_FORMAT "ww" +static const char * const rtx_format[NUM_RTX_CODE] = { +#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT , +#include "rtl.def" +#undef DEF_RTL_EXPR +}; + +static char rtx_next[NUM_RTX_CODE]; + +/* Generate the contents of the rtx_next array. This really doesn't belong + in gengtype at all, but it's needed for adjust_field_rtx_def. */ + +static void +gen_rtx_next () +{ + int i; + for (i = 0; i < NUM_RTX_CODE; i++) + { + int k; + + rtx_next[i] = -1; + if (strncmp (rtx_format[i], "iuu", 3) == 0) + rtx_next[i] = 2; + else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST) + rtx_next[i] = 1; + else + for (k = strlen (rtx_format[i]) - 1; k >= 0; k--) + if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u') + rtx_next[i] = k; + } +} + +/* Write out the contents of the rtx_next array. */ +static void +write_rtx_next () +{ + outf_p f = get_output_file_with_visibility (NULL); + int i; + + oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n"); + oprintf (f, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n"); + for (i = 0; i < NUM_RTX_CODE; i++) + if (rtx_next[i] == -1) + oprintf (f, " 0,\n"); + else + oprintf (f, + " offsetof (struct rtx_def, fld) + %d * sizeof (rtunion),\n", + rtx_next[i]); + oprintf (f, "};\n"); +} + +/* Handle `special("rtx_def")'. This is a special case for field + `fld' of struct rtx_def, which is an array of unions whose values + are based in a complex way on the type of RTL. */ + +static type_p +adjust_field_rtx_def (t, opt) + type_p t; + options_p opt ATTRIBUTE_UNUSED; +{ + pair_p flds = NULL; + options_p nodot; + int i; + type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp; + type_p bitmap_tp, basic_block_tp; + + static const char * const rtx_name[NUM_RTX_CODE] = { +#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME , +#include "rtl.def" +#undef DEF_RTL_EXPR + }; + + if (t->kind != TYPE_ARRAY) + { + error_at_line (&lexer_line, + "special `rtx_def' must be applied to an array"); + return &string_type; + } + + nodot = xmalloc (sizeof (*nodot)); + nodot->next = NULL; + nodot->name = "dot"; + nodot->info = ""; + + rtx_tp = create_pointer (find_structure ("rtx_def", 0)); + rtvec_tp = create_pointer (find_structure ("rtvec_def", 0)); + tree_tp = create_pointer (find_structure ("tree_node", 1)); + mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0)); + bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0)); + basic_block_tp = create_pointer (find_structure ("basic_block_def", 0)); + scalar_tp = create_scalar_type ("rtunion scalar", 14); + + { + pair_p note_flds = NULL; + int c; + + for (c = 0; c < 3; c++) + { + pair_p old_note_flds = note_flds; + + note_flds = xmalloc (sizeof (*note_flds)); + note_flds->line.file = __FILE__; + note_flds->line.line = __LINE__; + note_flds->name = "rttree"; + note_flds->type = tree_tp; + note_flds->opt = xmalloc (sizeof (*note_flds->opt)); + note_flds->opt->next = nodot; + note_flds->opt->name = "tag"; + note_flds->next = old_note_flds; + } + + note_flds->type = rtx_tp; + note_flds->name = "rtx"; + note_flds->opt->info = "NOTE_INSN_EXPECTED_VALUE"; + note_flds->next->opt->info = "NOTE_INSN_BLOCK_BEG"; + note_flds->next->next->opt->info = "NOTE_INSN_BLOCK_END"; + + new_structure ("rtx_def_note_subunion", 1, &lexer_line, note_flds, NULL); + } + + note_union_tp = find_structure ("rtx_def_note_subunion", 1); + + for (i = 0; i < NUM_RTX_CODE; i++) + { + pair_p old_flds = flds; + pair_p subfields = NULL; + size_t aindex, nmindex; + const char *sname; + char *ftag; + + for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++) + { + pair_p old_subf = subfields; + type_p t; + const char *subname; + + switch (rtx_format[i][aindex]) + { + case '*': + case 'i': + case 'n': + case 'w': + t = scalar_tp; + subname = "rtint"; + break; + + case '0': + if (i == MEM && aindex == 1) + t = mem_attrs_tp, subname = "rtmem"; + else if (i == JUMP_INSN && aindex == 9) + t = rtx_tp, subname = "rtx"; + else if (i == CODE_LABEL && aindex == 4) + t = scalar_tp, subname = "rtint"; + else if (i == CODE_LABEL && aindex == 5) + t = rtx_tp, subname = "rtx"; + else if (i == LABEL_REF + && (aindex == 1 || aindex == 2)) + t = rtx_tp, subname = "rtx"; + else if (i == NOTE && aindex == 4) + t = note_union_tp, subname = ""; + else if (i == NOTE && aindex >= 7) + t = scalar_tp, subname = "rtint"; + else if (i == ADDR_DIFF_VEC && aindex == 4) + t = scalar_tp, subname = "rtint"; + else if (i == VALUE && aindex == 0) + t = scalar_tp, subname = "rtint"; + else if (i == REG && aindex == 1) + t = scalar_tp, subname = "rtint"; + else if (i == SCRATCH && aindex == 0) + t = scalar_tp, subname = "rtint"; + else if (i == BARRIER && aindex >= 3) + t = scalar_tp, subname = "rtint"; + else + { + error_at_line (&lexer_line, + "rtx type `%s' has `0' in position %d, can't handle", + rtx_name[i], aindex); + t = &string_type; + subname = "rtint"; + } + break; + + case 's': + case 'S': + case 'T': + t = &string_type; + subname = "rtstr"; + break; + + case 'e': + case 'u': + t = rtx_tp; + subname = "rtx"; + break; + + case 'E': + case 'V': + t = rtvec_tp; + subname = "rtvec"; + break; + + case 't': + t = tree_tp; + subname = "rttree"; + break; + + case 'b': + t = bitmap_tp; + subname = "rtbit"; + break; + + case 'B': + t = basic_block_tp; + subname = "bb"; + break; + + default: + error_at_line (&lexer_line, + "rtx type `%s' has `%c' in position %d, can't handle", + rtx_name[i], rtx_format[i][aindex], + aindex); + t = &string_type; + subname = "rtint"; + break; + } + + subfields = xmalloc (sizeof (*subfields)); + subfields->next = old_subf; + subfields->type = t; + subfields->name = xasprintf ("[%d].%s", aindex, subname); + subfields->line.file = __FILE__; + subfields->line.line = __LINE__; + if (t == note_union_tp) + { + subfields->opt = xmalloc (sizeof (*subfields->opt)); + subfields->opt->next = nodot; + subfields->opt->name = "desc"; + subfields->opt->info = "NOTE_LINE_NUMBER (&%0)"; + } + else if (t == basic_block_tp) + { + /* We don't presently GC basic block structures... */ + subfields->opt = xmalloc (sizeof (*subfields->opt)); + subfields->opt->next = nodot; + subfields->opt->name = "skip"; + subfields->opt->info = NULL; + } + else if ((size_t) rtx_next[i] == aindex) + { + /* The 'next' field will be marked by the chain_next option. */ + subfields->opt = xmalloc (sizeof (*subfields->opt)); + subfields->opt->next = nodot; + subfields->opt->name = "skip"; + subfields->opt->info = NULL; + } + else + subfields->opt = nodot; + } + + flds = xmalloc (sizeof (*flds)); + flds->next = old_flds; + flds->name = ""; + sname = xasprintf ("rtx_def_%s", rtx_name[i]); + new_structure (sname, 0, &lexer_line, subfields, NULL); + flds->type = find_structure (sname, 0); + flds->line.file = __FILE__; + flds->line.line = __LINE__; + flds->opt = xmalloc (sizeof (*flds->opt)); + flds->opt->next = nodot; + flds->opt->name = "tag"; + ftag = xstrdup (rtx_name[i]); + for (nmindex = 0; nmindex < strlen (ftag); nmindex++) + ftag[nmindex] = TOUPPER (ftag[nmindex]); + flds->opt->info = ftag; + } + + new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot); + return find_structure ("rtx_def_subunion", 1); +} + +/* Handle `special("tree_exp")'. This is a special case for + field `operands' of struct tree_exp, which although it claims to contain + pointers to trees, actually sometimes contains pointers to RTL too. + Passed T, the old type of the field, and OPT its options. Returns + a new type for the field. */ + +static type_p +adjust_field_tree_exp (t, opt) + type_p t; + options_p opt ATTRIBUTE_UNUSED; +{ + pair_p flds; + options_p nodot; + size_t i; + static const struct { + const char *name; + int first_rtl; + int num_rtl; + } data[] = { + { "SAVE_EXPR", 2, 1 }, + { "GOTO_SUBROUTINE_EXPR", 0, 2 }, + { "RTL_EXPR", 0, 2 }, + { "WITH_CLEANUP_EXPR", 2, 1 }, + { "METHOD_CALL_EXPR", 3, 1 } + }; + + if (t->kind != TYPE_ARRAY) + { + error_at_line (&lexer_line, + "special `tree_exp' must be applied to an array"); + return &string_type; + } + + nodot = xmalloc (sizeof (*nodot)); + nodot->next = NULL; + nodot->name = "dot"; + nodot->info = ""; + + flds = xmalloc (sizeof (*flds)); + flds->next = NULL; + flds->name = ""; + flds->type = t; + flds->line.file = __FILE__; + flds->line.line = __LINE__; + flds->opt = xmalloc (sizeof (*flds->opt)); + flds->opt->next = nodot; + flds->opt->name = "length"; + flds->opt->info = "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))"; + { + options_p oldopt = flds->opt; + flds->opt = xmalloc (sizeof (*flds->opt)); + flds->opt->next = oldopt; + flds->opt->name = "default"; + flds->opt->info = ""; + } + + for (i = 0; i < ARRAY_SIZE (data); i++) + { + pair_p old_flds = flds; + pair_p subfields = NULL; + int r_index; + const char *sname; + + for (r_index = 0; + r_index < data[i].first_rtl + data[i].num_rtl; + r_index++) + { + pair_p old_subf = subfields; + subfields = xmalloc (sizeof (*subfields)); + subfields->next = old_subf; + subfields->name = xasprintf ("[%d]", r_index); + if (r_index < data[i].first_rtl) + subfields->type = t->u.a.p; + else + subfields->type = create_pointer (find_structure ("rtx_def", 0)); + subfields->line.file = __FILE__; + subfields->line.line = __LINE__; + subfields->opt = nodot; + } + + flds = xmalloc (sizeof (*flds)); + flds->next = old_flds; + flds->name = ""; + sname = xasprintf ("tree_exp_%s", data[i].name); + new_structure (sname, 0, &lexer_line, subfields, NULL); + flds->type = find_structure (sname, 0); + flds->line.file = __FILE__; + flds->line.line = __LINE__; + flds->opt = xmalloc (sizeof (*flds->opt)); + flds->opt->next = nodot; + flds->opt->name = "tag"; + flds->opt->info = data[i].name; + } + + new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot); + return find_structure ("tree_exp_subunion", 1); +} + /* Perform any special processing on a type T, about to become the type of a field. Return the appropriate type for the field. At present: - Converts pointer-to-char, with no length parameter, to TYPE_STRING; - Similarly for arrays of pointer-to-char; - Converts structures for which a parameter is provided to - TYPE_PARAM_STRUCT. + TYPE_PARAM_STRUCT; + - Handles "special" options. */ type_p @@ -296,30 +748,61 @@ adjust_field_type (t, opt) { int length_p = 0; const int pointer_p = t->kind == TYPE_POINTER; + type_p params[NUM_PARAM]; + int params_p = 0; + int i; + + for (i = 0; i < NUM_PARAM; i++) + params[i] = NULL; for (; opt; opt = opt->next) if (strcmp (opt->name, "length") == 0) length_p = 1; - else if (strcmp (opt->name, "param_is") == 0) + else if (strcmp (opt->name, "param_is") == 0 + || (strncmp (opt->name, "param", 5) == 0 + && ISDIGIT (opt->name[5]) + && strcmp (opt->name + 6, "_is") == 0)) { - type_p realt; + int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0; - if (pointer_p) - t = t->u.p; - - for (realt = param_structs; realt; realt = realt->next) - if (realt->u.param_struct.stru == t - && realt->u.param_struct.param == (type_p) opt->info) - return pointer_p ? create_pointer (realt) : realt; - realt = xcalloc (1, sizeof (*realt)); - realt->kind = TYPE_PARAM_STRUCT; - realt->next = param_structs; - param_structs = realt; - realt->u.param_struct.stru = t; - realt->u.param_struct.param = (type_p) opt->info; - return pointer_p ? create_pointer (realt) : realt; + if (! UNION_OR_STRUCT_P (t) + && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p))) + { + error_at_line (&lexer_line, + "option `%s' may only be applied to structures or structure pointers", + opt->name); + return t; + } + + params_p = 1; + if (params[num] != NULL) + error_at_line (&lexer_line, "duplicate `%s' option", opt->name); + if (! ISDIGIT (opt->name[5])) + params[num] = create_pointer ((type_p) opt->info); + else + params[num] = (type_p) opt->info; } - + else if (strcmp (opt->name, "special") == 0) + { + const char *special_name = (const char *)opt->info; + if (strcmp (special_name, "tree_exp") == 0) + t = adjust_field_tree_exp (t, opt); + else if (strcmp (special_name, "rtx_def") == 0) + t = adjust_field_rtx_def (t, opt); + else + error_at_line (&lexer_line, "unknown special `%s'", special_name); + } + + if (params_p) + { + type_p realt; + + if (pointer_p) + t = t->u.p; + realt = find_param_structure (t, params); + t = pointer_p ? create_pointer (realt) : realt; + } + if (! length_p && pointer_p && t->u.p->kind == TYPE_SCALAR @@ -335,26 +818,6 @@ adjust_field_type (t, opt) return t; } -/* Add a variable named S of type T with options O defined at POS, - to `variables'. */ - -void -note_variable (s, t, o, pos) - const char *s; - type_p t; - options_p o; - struct fileloc *pos; -{ - pair_p n; - n = xmalloc (sizeof (*n)); - n->name = s; - n->type = t; - n->line = *pos; - n->opt = o; - n->next = variables; - variables = n; -} - /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS and information about the correspondance between token types and fields in TYPEINFO. POS is used for error messages. */ @@ -419,36 +882,44 @@ note_yacc_type (o, fields, typeinfo, pos) do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos); } -static void process_gc_options PARAMS ((options_p, enum gc_used_enum, int *)); -static void set_gc_used_type PARAMS ((type_p, enum gc_used_enum)); +static void process_gc_options PARAMS ((options_p, enum gc_used_enum, + int *, int *, int *)); +static void set_gc_used_type PARAMS ((type_p, enum gc_used_enum, type_p *)); static void set_gc_used PARAMS ((pair_p)); /* Handle OPT for set_gc_used_type. */ static void -process_gc_options (opt, level, maybe_undef) +process_gc_options (opt, level, maybe_undef, pass_param, length) options_p opt; enum gc_used_enum level; int *maybe_undef; + int *pass_param; + int *length; { options_p o; for (o = opt; o; o = o->next) if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO) - set_gc_used_type ((type_p) o->info, GC_POINTED_TO); + set_gc_used_type ((type_p) o->info, GC_POINTED_TO, NULL); else if (strcmp (o->name, "maybe_undef") == 0) *maybe_undef = 1; + else if (strcmp (o->name, "use_params") == 0) + *pass_param = 1; + else if (strcmp (o->name, "length") == 0) + *length = 1; } /* Set the gc_used field of T to LEVEL, and handle the types it references. */ static void -set_gc_used_type (t, level) +set_gc_used_type (t, level, param) type_p t; enum gc_used_enum level; + type_p param[NUM_PARAM]; { if (t->gc_used >= level) return; - + t->gc_used = level; switch (t->kind) @@ -459,37 +930,56 @@ set_gc_used_type (t, level) pair_p f; int dummy; - process_gc_options (t->u.s.opt, level, &dummy); + process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy); for (f = t->u.s.fields; f; f = f->next) { int maybe_undef = 0; - process_gc_options (t->u.s.opt, level, &maybe_undef); + int pass_param = 0; + int length = 0; + process_gc_options (f->opt, level, &maybe_undef, &pass_param, + &length); - if (maybe_undef && f->type->kind == TYPE_POINTER) - set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO); + if (length && f->type->kind == TYPE_POINTER) + set_gc_used_type (f->type->u.p, GC_USED, NULL); + else if (maybe_undef && f->type->kind == TYPE_POINTER) + set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL); + else if (pass_param && f->type->kind == TYPE_POINTER && param) + set_gc_used_type (find_param_structure (f->type->u.p, param), + GC_POINTED_TO, NULL); else - set_gc_used_type (f->type, GC_USED); + set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL); } break; } case TYPE_POINTER: - set_gc_used_type (t->u.p, GC_POINTED_TO); + set_gc_used_type (t->u.p, GC_POINTED_TO, NULL); break; case TYPE_ARRAY: - set_gc_used_type (t->u.a.p, GC_USED); + set_gc_used_type (t->u.a.p, GC_USED, param); break; case TYPE_LANG_STRUCT: for (t = t->u.s.lang_struct; t; t = t->next) - set_gc_used_type (t, level); + set_gc_used_type (t, level, param); break; case TYPE_PARAM_STRUCT: - set_gc_used_type (t->u.param_struct.param, GC_POINTED_TO); - set_gc_used_type (t->u.param_struct.stru, GC_USED); + { + int i; + for (i = 0; i < NUM_PARAM; i++) + if (t->u.param_struct.param[i] != 0) + set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL); + } + if (t->u.param_struct.stru->gc_used == GC_POINTED_TO) + level = GC_POINTED_TO; + else + level = GC_USED; + t->u.param_struct.stru->gc_used = GC_UNUSED; + set_gc_used_type (t->u.param_struct.stru, level, + t->u.param_struct.param); break; default: @@ -497,7 +987,7 @@ set_gc_used_type (t, level) } } -/* Set the gc_used fileds of all the types pointed to by VARIABLES. */ +/* Set the gc_used fields of all the types pointed to by VARIABLES. */ static void set_gc_used (variables) @@ -505,7 +995,7 @@ set_gc_used (variables) { pair_p p; for (p = variables; p; p = p->next) - set_gc_used_type (p->type, GC_USED); + set_gc_used_type (p->type, GC_USED, NULL); } /* File mapping routines. For each input file, there is one output .c file @@ -609,8 +1099,6 @@ oprintf VPARAMS ((outf_p o, const char *format, ...)) /* Open the global header file and the language-specific header files. */ -static void open_base_files PARAMS((void)); - static void open_base_files () { @@ -626,7 +1114,7 @@ open_base_files () { /* The order of files here matters very much. */ static const char *const ifiles [] = { - "config.h", "system.h", "varray.h", "hashtab.h", + "config.h", "system.h", "varray.h", "hashtab.h", "splay-tree.h", "bitmap.h", "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h", "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h", "ssa.h", "optabs.h", "libfuncs.h", @@ -878,11 +1366,14 @@ struct flist { static void output_escaped_param PARAMS ((outf_p , const char *, const char *, const char *, const char *, struct fileloc *)); +static void output_mangled_typename PARAMS ((outf_p, type_p)); static void write_gc_structure_fields PARAMS ((outf_p , type_p, const char *, const char *, options_p, - int, struct fileloc *, lang_bitmap, type_p)); -static void write_gc_marker_routine_for_structure PARAMS ((type_p, type_p)); + int, struct fileloc *, lang_bitmap, type_p *)); +static void write_gc_marker_routine_for_structure PARAMS ((type_p, type_p, + type_p *)); static void write_gc_types PARAMS ((type_p structures, type_p param_structs)); +static void write_enum_defn PARAMS ((type_p structures, type_p param_structs)); static void put_mangled_filename PARAMS ((outf_p , const char *)); static void finish_root_table PARAMS ((struct flist *flp, const char *pfx, const char *tname, const char *lastname, @@ -911,15 +1402,70 @@ output_escaped_param (of, param, val, prev_val, oname, line) for (p = param; *p; p++) if (*p != '%') oprintf (of, "%c", *p); - else if (*++p == 'h') - oprintf (of, "(%s)", val); - else if (*p == '0') - oprintf (of, "(*x)"); - else if (*p == '1') - oprintf (of, "(%s)", prev_val); - else - error_at_line (line, "`%s' option contains bad escape %c%c", - oname, '%', *p); + else switch (*++p) + { + case 'h': + oprintf (of, "(%s)", val); + break; + case '0': + oprintf (of, "(*x)"); + break; + case '1': + oprintf (of, "(%s)", prev_val); + break; + case 'a': + { + const char *pp = val + strlen (val); + while (pp[-1] == ']') + while (*pp != '[') + pp--; + oprintf (of, "%s", pp); + } + break; + default: + error_at_line (line, "`%s' option contains bad escape %c%c", + oname, '%', *p); + } +} + +/* Print a mangled name representing T to OF. */ + +static void +output_mangled_typename (of, t) + outf_p of; + type_p t; +{ + if (t == NULL) + oprintf (of, "Z"); + else switch (t->kind) + { + case TYPE_POINTER: + oprintf (of, "P"); + output_mangled_typename (of, t->u.p); + break; + case TYPE_SCALAR: + oprintf (of, "I"); + break; + case TYPE_STRING: + oprintf (of, "S"); + break; + case TYPE_STRUCT: + case TYPE_UNION: + case TYPE_LANG_STRUCT: + oprintf (of, "%d%s", strlen (t->u.s.tag), t->u.s.tag); + break; + case TYPE_PARAM_STRUCT: + { + int i; + for (i = 0; i < NUM_PARAM; i++) + if (t->u.param_struct.param[i] != NULL) + output_mangled_typename (of, t->u.param_struct.param[i]); + output_mangled_typename (of, t->u.param_struct.stru); + } + break; + case TYPE_ARRAY: + abort (); + } } /* Write out code to OF which marks the fields of S. VAL references @@ -940,10 +1486,10 @@ write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap, int indent; struct fileloc *line; lang_bitmap bitmap; - type_p param; + type_p * param; { pair_p f; - int tagcounter = -1; + int seen_default = 0; if (! s->u.s.line.file) error_at_line (line, "incomplete structure `%s'", s->u.s.tag); @@ -958,7 +1504,6 @@ write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap, const char *tagexpr = NULL; options_p oo; - tagcounter = ++gc_counter; for (oo = opts; oo; oo = oo->next) if (strcmp (oo->name, "desc") == 0) tagexpr = (const char *)oo->info; @@ -968,29 +1513,26 @@ write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap, error_at_line (line, "missing `desc' option"); } - oprintf (of, "%*s{\n", indent, ""); - indent += 2; - oprintf (of, "%*sunsigned int tag%d = (", indent, "", tagcounter); + oprintf (of, "%*sswitch (", indent, ""); output_escaped_param (of, tagexpr, val, prev_val, "desc", line); - oprintf (of, ");\n"); + oprintf (of, ")\n"); + indent += 2; + oprintf (of, "%*s{\n", indent, ""); } for (f = s->u.s.fields; f; f = f->next) { const char *tagid = NULL; const char *length = NULL; - const char *special = NULL; int skip_p = 0; - int always_p = 0; + int default_p = 0; int maybe_undef_p = 0; - int use_param_p = 0; + int use_param_num = -1; + int use_params_p = 0; + int needs_cast_p = 0; options_p oo; type_p t = f->type; - - if (t->kind == TYPE_SCALAR - || (t->kind == TYPE_ARRAY - && t->u.a.p->kind == TYPE_SCALAR)) - continue; + const char *dot = "."; for (oo = f->opt; oo; oo = oo->next) if (strcmp (oo->name, "length") == 0) @@ -1000,62 +1542,88 @@ write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap, else if (strcmp (oo->name, "tag") == 0) tagid = (const char *)oo->info; else if (strcmp (oo->name, "special") == 0) - special = (const char *)oo->info; + ; else if (strcmp (oo->name, "skip") == 0) skip_p = 1; - else if (strcmp (oo->name, "always") == 0) - always_p = 1; - else if (strcmp (oo->name, "desc") == 0 && UNION_P (t)) + else if (strcmp (oo->name, "default") == 0) + default_p = 1; + else if (strcmp (oo->name, "desc") == 0) ; - else if (strcmp (oo->name, "descbits") == 0 && UNION_P (t)) + else if (strcmp (oo->name, "descbits") == 0) ; else if (strcmp (oo->name, "param_is") == 0) ; - else if (strcmp (oo->name, "use_param") == 0) - use_param_p = 1; + else if (strncmp (oo->name, "use_param", 9) == 0 + && (oo->name[9] == '\0' || ISDIGIT (oo->name[9]))) + use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0'; + else if (strcmp (oo->name, "use_params") == 0) + use_params_p = 1; + else if (strcmp (oo->name, "dot") == 0) + dot = (const char *)oo->info; else error_at_line (&f->line, "unknown field option `%s'\n", oo->name); if (skip_p) continue; + + if (use_params_p) + { + int pointer_p = t->kind == TYPE_POINTER; + + if (pointer_p) + t = t->u.p; + t = find_param_structure (t, param); + if (pointer_p) + t = create_pointer (t); + } - if (use_param_p) + if (use_param_num != -1) { - if (param != NULL) + if (param != NULL && param[use_param_num] != NULL) { - type_p t1; - type_p nt = param; - int arraycount = 0; + type_p nt = param[use_param_num]; - for (t1 = t; t->kind == TYPE_ARRAY; t = t->u.a.p) - arraycount++; - for (; t->kind == TYPE_POINTER; t = t->u.p) - nt = create_pointer (nt); - while (arraycount-- > 0) + if (t->kind == TYPE_ARRAY) nt = create_array (nt, t->u.a.len); + else if (length != NULL && t->kind == TYPE_POINTER) + nt = create_pointer (nt); + needs_cast_p = (t->kind != TYPE_POINTER + && nt->kind == TYPE_POINTER); t = nt; } - else if (s->kind == TYPE_UNION && ! always_p && tagid) - ; - else + else if (s->kind != TYPE_UNION) error_at_line (&f->line, "no parameter defined"); } + if (t->kind == TYPE_SCALAR + || (t->kind == TYPE_ARRAY + && t->u.a.p->kind == TYPE_SCALAR)) + continue; + + seen_default |= default_p; + if (maybe_undef_p && (t->kind != TYPE_POINTER || t->u.p->kind != TYPE_STRUCT)) error_at_line (&f->line, "field `%s' has invalid option `maybe_undef_p'\n", f->name); - if (s->kind == TYPE_UNION && ! always_p ) + if (s->kind == TYPE_UNION) { - if (! tagid) + if (tagid) + { + oprintf (of, "%*scase %s:\n", indent, "", tagid); + + } + else if (default_p) + { + oprintf (of, "%*sdefault:\n", indent, ""); + } + else { error_at_line (&f->line, "field `%s' has no tag", f->name); continue; } - oprintf (of, "%*sif (tag%d == (%s)) {\n", indent, "", - tagcounter, tagid); indent += 2; } @@ -1087,7 +1655,7 @@ write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap, { char *newval; - newval = xasprintf ("%s.%s", val, f->name); + newval = xasprintf ("%s%s%s", val, dot, f->name); write_gc_structure_fields (of, t, newval, val, f->opt, indent, &f->line, bitmap, param); free (newval); @@ -1099,17 +1667,20 @@ write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap, { if (maybe_undef_p && t->u.p->u.s.line.file == NULL) - oprintf (of, "%*sif (%s.%s) abort();\n", indent, "", - val, f->name); - else if (UNION_OR_STRUCT_P (t->u.p)) - oprintf (of, "%*sgt_ggc_m_%s (%s.%s);\n", indent, "", - t->u.p->u.s.tag, val, f->name); - else if (t->u.p->kind == TYPE_PARAM_STRUCT) - oprintf (of, "%*sgt_ggc_mm_%d%s_%s (%s.%s);\n", indent, "", - (int) strlen (t->u.p->u.param_struct.param->u.s.tag), - t->u.p->u.param_struct.param->u.s.tag, - t->u.p->u.param_struct.stru->u.s.tag, - val, f->name); + oprintf (of, "%*sif (%s%s%s) abort();\n", indent, "", + val, dot, f->name); + else if (UNION_OR_STRUCT_P (t->u.p) + || t->u.p->kind == TYPE_PARAM_STRUCT) + { + oprintf (of, "%*sgt_ggc_m_", indent, ""); + output_mangled_typename (of, t->u.p); + oprintf (of, " ("); + if (needs_cast_p) + oprintf (of, "(%s %s *)", + UNION_P (t->u.p) ? "union" : "struct", + t->u.p->u.s.tag); + oprintf (of, "%s%s%s);\n", val, dot, f->name); + } else error_at_line (&f->line, "field `%s' is pointer to scalar", f->name); @@ -1117,18 +1688,18 @@ write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap, } else if (t->u.p->kind == TYPE_SCALAR || t->u.p->kind == TYPE_STRING) - oprintf (of, "%*sggc_mark (%s.%s);\n", indent, "", - val, f->name); + oprintf (of, "%*sggc_mark (%s%s%s);\n", indent, "", + val, dot, f->name); else { int loopcounter = ++gc_counter; - oprintf (of, "%*sif (%s.%s != NULL) {\n", indent, "", - val, f->name); + oprintf (of, "%*sif (%s%s%s != NULL) {\n", indent, "", + val, dot, f->name); indent += 2; oprintf (of, "%*ssize_t i%d;\n", indent, "", loopcounter); - oprintf (of, "%*sggc_set_mark (%s.%s);\n", indent, "", - val, f->name); + oprintf (of, "%*sggc_set_mark (%s%s%s);\n", indent, "", + val, dot, f->name); oprintf (of, "%*sfor (i%d = 0; i%d < (size_t)(", indent, "", loopcounter, loopcounter); output_escaped_param (of, length, val, prev_val, "length", line); @@ -1141,7 +1712,7 @@ write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap, { char *newval; - newval = xasprintf ("%s.%s[i%d]", val, f->name, + newval = xasprintf ("%s%s%s[i%d]", val, dot, f->name, loopcounter); write_gc_structure_fields (of, t->u.p, newval, val, f->opt, indent, &f->line, @@ -1150,10 +1721,14 @@ write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap, break; } case TYPE_POINTER: - if (UNION_OR_STRUCT_P (t->u.p->u.p)) - oprintf (of, "%*sgt_ggc_m_%s (%s.%s[i%d]);\n", indent, "", - t->u.p->u.p->u.s.tag, val, f->name, - loopcounter); + if (UNION_OR_STRUCT_P (t->u.p->u.p) + || t->u.p->u.p->kind == TYPE_PARAM_STRUCT) + { + oprintf (of, "%*sgt_ggc_m_", indent, ""); + output_mangled_typename (of, t->u.p->u.p); + oprintf (of, " (%s%s%s[i%d]);\n", val, dot, f->name, + loopcounter); + } else error_at_line (&f->line, "field `%s' is array of pointer to scalar", @@ -1195,17 +1770,6 @@ write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap, oprintf (of, "%*s{\n", indent, ""); indent += 2; - if (special != NULL && strcmp (special, "tree_exp") == 0) - { - oprintf (of, "%*sconst size_t tree_exp_size = (", - indent, ""); - output_escaped_param (of, length, val, prev_val, - "length", line); - oprintf (of, ");\n"); - - length = "first_rtl_op (TREE_CODE ((tree)&%h))"; - } - for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++) { oprintf (of, "%*ssize_t i%d_%d;\n", @@ -1230,11 +1794,12 @@ write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap, } if (ta->kind == TYPE_POINTER - && (ta->u.p->kind == TYPE_STRUCT - || ta->u.p->kind == TYPE_UNION)) + && (UNION_OR_STRUCT_P (ta->u.p) + || ta->u.p->kind == TYPE_PARAM_STRUCT)) { - oprintf (of, "%*sgt_ggc_m_%s (%s.%s", - indent, "", ta->u.p->u.s.tag, val, f->name); + oprintf (of, "%*sgt_ggc_m_", indent, ""); + output_mangled_typename (of, ta->u.p); + oprintf (of, " (%s%s%s", val, dot, f->name); for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++) @@ -1251,7 +1816,7 @@ write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap, len += sizeof ("[i_]") + 2*6; newval = xmalloc (len); - sprintf (newval, "%s.%s", val, f->name); + sprintf (newval, "%s%s%s", val, dot, f->name); for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++) @@ -1263,7 +1828,7 @@ write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap, free (newval); } else if (ta->kind == TYPE_POINTER && ta->u.p->kind == TYPE_SCALAR - && use_param_p && param == NULL) + && use_param_num != -1 && param == NULL) oprintf (of, "%*sabort();\n", indent, ""); else error_at_line (&f->line, @@ -1275,16 +1840,6 @@ write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap, oprintf (of, "%*s}\n", indent, ""); } - if (special != NULL && strcmp (special, "tree_exp") == 0) - { - oprintf (of, - "%*sfor (; i%d_0 < tree_exp_size; i%d_0++)\n", - indent, "", loopcounter, loopcounter); - oprintf (of, "%*s gt_ggc_m_rtx_def (%s.%s[i%d_0]);\n", - indent, "", val, f->name, loopcounter); - special = NULL; - } - indent -= 2; oprintf (of, "%*s}\n", indent, ""); break; @@ -1297,18 +1852,21 @@ write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap, break; } - if (s->kind == TYPE_UNION && ! always_p ) + if (s->kind == TYPE_UNION) { + oprintf (of, "%*sbreak;\n", indent, ""); indent -= 2; - oprintf (of, "%*s}\n", indent, ""); } - if (special) - error_at_line (&f->line, "unhandled special `%s'", special); } if (s->kind == TYPE_UNION) { - indent -= 2; + if (! seen_default) + { + oprintf (of, "%*sdefault:\n", indent, ""); + oprintf (of, "%*s break;\n", indent, ""); + } oprintf (of, "%*s}\n", indent, ""); + indent -= 2; } } @@ -1316,36 +1874,96 @@ write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap, enclosing PARAM_IS option. */ static void -write_gc_marker_routine_for_structure (s, param) +write_gc_marker_routine_for_structure (orig_s, s, param) + type_p orig_s; type_p s; - type_p param; + type_p * param; { outf_p f; - if (param == NULL) - f = get_output_file_with_visibility (s->u.s.line.file); - else - f = get_output_file_with_visibility (param->u.s.line.file); + const char *fn = s->u.s.line.file; + int i; + const char *chain_next = NULL; + const char *chain_prev = NULL; + options_p opt; + + /* This is a hack, and not the good kind either. */ + for (i = NUM_PARAM - 1; i >= 0; i--) + if (param && param[i] && param[i]->kind == TYPE_POINTER + && UNION_OR_STRUCT_P (param[i]->u.p)) + fn = param[i]->u.p->u.s.line.file; + + f = get_output_file_with_visibility (fn); - oprintf (f, "%c", '\n'); + for (opt = s->u.s.opt; opt; opt = opt->next) + if (strcmp (opt->name, "chain_next") == 0) + chain_next = (const char *) opt->info; + else if (strcmp (opt->name, "chain_prev") == 0) + chain_prev = (const char *) opt->info; + + if (chain_prev != NULL && chain_next == NULL) + error_at_line (&s->u.s.line, "chain_prev without chain_next"); + + oprintf (f, "\n"); oprintf (f, "void\n"); if (param == NULL) - oprintf (f, "gt_ggc_mx_%s (x_p)\n", s->u.s.tag); + oprintf (f, "gt_ggc_mx_%s", s->u.s.tag); else - oprintf (f, "gt_ggc_mm_%d%s_%s (x_p)\n", (int) strlen (param->u.s.tag), - param->u.s.tag, s->u.s.tag); + { + oprintf (f, "gt_ggc_m_"); + output_mangled_typename (f, orig_s); + } + oprintf (f, " (x_p)\n"); oprintf (f, " void *x_p;\n"); oprintf (f, "{\n"); - oprintf (f, " %s %s * const x = (%s %s *)x_p;\n", + oprintf (f, " %s %s * %sx = (%s %s *)x_p;\n", s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag, + chain_next == NULL ? "const " : "", s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag); - oprintf (f, " if (! ggc_test_and_set_mark (x))\n"); - oprintf (f, " return;\n"); + if (chain_next != NULL) + oprintf (f, " %s %s * xlimit = x;\n", + s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag); + if (chain_next == NULL) + oprintf (f, " if (ggc_test_and_set_mark (x))\n"); + else + { + oprintf (f, " while (ggc_test_and_set_mark (xlimit))\n"); + oprintf (f, " xlimit = ("); + output_escaped_param (f, chain_next, "*xlimit", "*xlimit", + "chain_next", &s->u.s.line); + oprintf (f, ");\n"); + if (chain_prev != NULL) + { + oprintf (f, " if (x != xlimit)\n"); + oprintf (f, " for (;;)\n"); + oprintf (f, " {\n"); + oprintf (f, " %s %s * const xprev = (", + s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag); + output_escaped_param (f, chain_prev, "*x", "*x", + "chain_prev", &s->u.s.line); + oprintf (f, ");\n"); + oprintf (f, " if (xprev == NULL) break;\n"); + oprintf (f, " x = xprev;\n"); + oprintf (f, " ggc_set_mark (xprev);\n"); + oprintf (f, " }\n"); + } + oprintf (f, " while (x != xlimit)\n"); + } + oprintf (f, " {\n"); gc_counter = 0; write_gc_structure_fields (f, s, "(*x)", "not valid postage", - s->u.s.opt, 2, &s->u.s.line, s->u.s.bitmap, + s->u.s.opt, 6, &s->u.s.line, s->u.s.bitmap, param); + if (chain_next != NULL) + { + oprintf (f, " x = ("); + output_escaped_param (f, chain_next, "*x", "*x", + "chain_next", &s->u.s.line); + oprintf (f, ");\n"); + } + + oprintf (f, " }\n"); oprintf (f, "}\n"); } @@ -1369,8 +1987,9 @@ write_gc_types (structures, param_structs) && s->u.s.line.file == NULL) continue; - oprintf (header_file, - "#define gt_ggc_m_%s(X) do { \\\n", s->u.s.tag); + oprintf (header_file, "#define gt_ggc_m_"); + output_mangled_typename (header_file, s); + oprintf (header_file, "(X) do { \\\n"); oprintf (header_file, " if (X != NULL) gt_ggc_mx_%s (X);\\\n", s->u.s.tag); oprintf (header_file, @@ -1410,31 +2029,22 @@ write_gc_types (structures, param_structs) { type_p ss; for (ss = s->u.s.lang_struct; ss; ss = ss->next) - write_gc_marker_routine_for_structure (ss, NULL); + write_gc_marker_routine_for_structure (s, ss, NULL); } else - write_gc_marker_routine_for_structure (s, NULL); + write_gc_marker_routine_for_structure (s, s, NULL); } for (s = param_structs; s; s = s->next) if (s->gc_used == GC_POINTED_TO) { - type_p param = s->u.param_struct.param; + type_p * param = s->u.param_struct.param; type_p stru = s->u.param_struct.stru; - if (param->kind != TYPE_STRUCT && param->kind != TYPE_UNION - && param->kind != TYPE_LANG_STRUCT) - { - error_at_line (&s->u.param_struct.line, - "unsupported parameter type"); - continue; - } - /* Declare the marker procedure. */ - oprintf (header_file, - "extern void gt_ggc_mm_%d%s_%s PARAMS ((void *));\n", - (int) strlen (param->u.s.tag), param->u.s.tag, - stru->u.s.tag); + oprintf (header_file, "extern void gt_ggc_m_"); + output_mangled_typename (header_file, s); + oprintf (header_file, " PARAMS ((void *));\n"); if (stru->u.s.line.file == NULL) { @@ -1447,13 +2057,48 @@ write_gc_types (structures, param_structs) { type_p ss; for (ss = stru->u.s.lang_struct; ss; ss = ss->next) - write_gc_marker_routine_for_structure (ss, param); + write_gc_marker_routine_for_structure (s, ss, param); } else - write_gc_marker_routine_for_structure (stru, param); + write_gc_marker_routine_for_structure (s, stru, param); + } +} + +/* Write out the 'enum' definition for gt_types_enum. */ + +static void +write_enum_defn (structures, param_structs) + type_p structures; + type_p param_structs; +{ + type_p s; + + oprintf (header_file, "\n/* Enumeration of types known. */\n"); + oprintf (header_file, "enum gt_types_enum {\n"); + for (s = structures; s; s = s->next) + if (s->gc_used == GC_POINTED_TO + || s->gc_used == GC_MAYBE_POINTED_TO) + { + if (s->gc_used == GC_MAYBE_POINTED_TO + && s->u.s.line.file == NULL) + continue; + + oprintf (header_file, " gt_ggc_e_"); + output_mangled_typename (header_file, s); + oprintf (header_file, ", \n"); } + for (s = param_structs; s; s = s->next) + if (s->gc_used == GC_POINTED_TO) + { + oprintf (header_file, " gt_e_"); + output_mangled_typename (header_file, s); + oprintf (header_file, ", \n"); + } + oprintf (header_file, " gt_types_enum_last\n"); + oprintf (header_file, "};\n"); } + /* Mangle FN and print it to F. */ static void @@ -1540,7 +2185,7 @@ finish_root_table (flp, pfx, lastname, tname, name) if (bitmap & 1) { oprintf (base_files[fnum], " NULL\n"); - oprintf (base_files[fnum], "};\n\n"); + oprintf (base_files[fnum], "};\n"); } } } @@ -1667,10 +2312,8 @@ write_gc_root (f, v, type, name, has_length, line, if_marked) } else if (! has_length && tp->kind == TYPE_PARAM_STRUCT) { - oprintf (f, " >_ggc_mm_%d%s_%s", - (int) strlen (tp->u.param_struct.param->u.s.tag), - tp->u.param_struct.param->u.s.tag, - tp->u.param_struct.stru->u.s.tag); + oprintf (f, " >_ggc_m_"); + output_mangled_typename (f, tp); } else if (has_length && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp))) @@ -1724,6 +2367,10 @@ write_gc_roots (variables) deletable_p = 1; else if (strcmp (o->name, "param_is") == 0) ; + else if (strncmp (o->name, "param", 5) == 0 + && ISDIGIT (o->name[5]) + && strcmp (o->name + 6, "_is") == 0) + ; else if (strcmp (o->name, "if_marked") == 0) ; else @@ -1768,7 +2415,8 @@ write_gc_roots (variables) s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag); oprintf (f, " if (ggc_test_and_set_mark (x))\n"); oprintf (f, " for (i = 0; i < (%s); i++)\n", length); - if (s->kind != TYPE_STRUCT && s->kind != TYPE_UNION) + if (! UNION_OR_STRUCT_P (s) + && ! s->kind == TYPE_PARAM_STRUCT) { error_at_line (&v->line, "global `%s' has unsupported ** type", @@ -1776,7 +2424,9 @@ write_gc_roots (variables) continue; } - oprintf (f, " gt_ggc_m_%s (x[i]);\n", s->u.s.tag); + oprintf (f, " gt_ggc_m_"); + output_mangled_typename (f, s); + oprintf (f, " (x[i]);\n"); } else { @@ -1906,7 +2556,7 @@ write_gc_roots (variables) oprintf (f, "[] = {\n"); } - write_gc_root (f, v, create_pointer (v->type->u.p->u.param_struct.param), + write_gc_root (f, v, v->type->u.p->u.param_struct.param[0], v->name, length_p, &v->line, if_marked); } @@ -1925,20 +2575,19 @@ main(argc, argv) static struct fileloc pos = { __FILE__, __LINE__ }; unsigned j; + gen_rtx_next (); + srcdir_len = strlen (srcdir); - do_typedef ("CUMULATIVE_ARGS", - create_scalar_type ("CUMULATIVE_ARGS", - strlen ("CUMULATIVE_ARGS")), - &pos); - do_typedef ("REAL_VALUE_TYPE", - create_scalar_type ("REAL_VALUE_TYPE", - strlen ("REAL_VALUE_TYPE")), - &pos); + do_scalar_typedef ("CUMULATIVE_ARGS", &pos); + do_scalar_typedef ("REAL_VALUE_TYPE", &pos); + do_scalar_typedef ("uint8", &pos); + do_scalar_typedef ("jword", &pos); + do_scalar_typedef ("JCF_u2", &pos); + do_typedef ("PTR", create_pointer (create_scalar_type ("void", strlen ("void"))), &pos); - do_typedef ("HARD_REG_SET", create_array ( create_scalar_type ("unsigned long", strlen ("unsigned long")), "2"), &pos); @@ -1965,8 +2614,10 @@ main(argc, argv) set_gc_used (variables); open_base_files (); + write_enum_defn (structures, param_structs); write_gc_types (structures, param_structs); write_gc_roots (variables); + write_rtx_next (); close_output_files (); return (hit_error != 0); diff --git a/gcc/gengtype.h b/gcc/gengtype.h index 20e496da05c..0c23d95f44a 100644 --- a/gcc/gengtype.h +++ b/gcc/gengtype.h @@ -41,7 +41,7 @@ enum typekind { typedef struct options { struct options *next; const char *name; - void *info; + const void *info; } *options_p; typedef struct pair *pair_p; @@ -57,6 +57,8 @@ struct pair { options_p opt; }; +#define NUM_PARAM 10 + /* A description of a type. */ struct type { enum typekind kind; @@ -85,7 +87,7 @@ struct type { } a; struct { type_p stru; - type_p param; + type_p param[NUM_PARAM]; struct fileloc line; } param_struct; } u; diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c index dcff4614001..2674cec52a1 100644 --- a/gcc/ggc-common.c +++ b/gcc/ggc-common.c @@ -34,7 +34,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA /* Statistics about the allocation. */ static ggc_statistics *ggc_stats; -static void ggc_mark_rtx_children_1 PARAMS ((rtx)); static int ggc_htab_delete PARAMS ((void **, void *)); /* Maintain global roots that are preserved during GC. */ @@ -132,140 +131,6 @@ ggc_mark_roots () htab_traverse (*cti->base, ggc_htab_delete, (PTR) cti); } -/* R had not been previously marked, but has now been marked via - ggc_set_mark. Now recurse and process the children. */ - -void -ggc_mark_rtx_children (r) - rtx r; -{ - rtx i, last; - - /* Special case the instruction chain. This is a data structure whose - chain length is potentially unbounded, and which contain references - within the chain (e.g. label_ref and insn_list). If do nothing here, - we risk blowing the stack recursing through a long chain of insns. - - Combat this by marking all of the instructions in the chain before - marking the contents of those instructions. */ - - switch (GET_CODE (r)) - { - case INSN: - case JUMP_INSN: - case CALL_INSN: - case NOTE: - case CODE_LABEL: - case BARRIER: - for (i = NEXT_INSN (r); ; i = NEXT_INSN (i)) - if (! ggc_test_and_set_mark (i)) - break; - last = i; - - for (i = NEXT_INSN (r); i != last; i = NEXT_INSN (i)) - ggc_mark_rtx_children_1 (i); - - default: - break; - } - - ggc_mark_rtx_children_1 (r); -} - -static void -ggc_mark_rtx_children_1 (r) - rtx r; -{ - const char *fmt; - int i; - rtx next_rtx; - - do - { - enum rtx_code code = GET_CODE (r); - /* This gets set to a child rtx to eliminate tail recursion. */ - next_rtx = NULL; - - /* Collect statistics, if appropriate. */ - if (ggc_stats) - { - ++ggc_stats->num_rtxs[(int) code]; - ggc_stats->size_rtxs[(int) code] += ggc_get_size (r); - } - - /* ??? If (some of) these are really pass-dependent info, do we - have any right poking our noses in? */ - switch (code) - { - case MEM: - gt_ggc_m_mem_attrs (MEM_ATTRS (r)); - break; - case JUMP_INSN: - ggc_mark_rtx (JUMP_LABEL (r)); - break; - case CODE_LABEL: - ggc_mark_rtx (LABEL_REFS (r)); - break; - case LABEL_REF: - ggc_mark_rtx (LABEL_NEXTREF (r)); - ggc_mark_rtx (CONTAINING_INSN (r)); - break; - case ADDRESSOF: - ggc_mark_tree (ADDRESSOF_DECL (r)); - break; - case NOTE: - switch (NOTE_LINE_NUMBER (r)) - { - case NOTE_INSN_EXPECTED_VALUE: - ggc_mark_rtx (NOTE_EXPECTED_VALUE (r)); - break; - - case NOTE_INSN_BLOCK_BEG: - case NOTE_INSN_BLOCK_END: - ggc_mark_tree (NOTE_BLOCK (r)); - break; - - default: - break; - } - break; - - default: - break; - } - - for (fmt = GET_RTX_FORMAT (GET_CODE (r)), i = 0; *fmt ; ++fmt, ++i) - { - rtx exp; - switch (*fmt) - { - case 'e': case 'u': - exp = XEXP (r, i); - if (ggc_test_and_set_mark (exp)) - { - if (next_rtx == NULL) - next_rtx = exp; - else - ggc_mark_rtx_children (exp); - } - break; - case 'V': case 'E': - gt_ggc_m_rtvec_def (XVEC (r, i)); - break; - } - } - } - while ((r = next_rtx) != NULL); -} - -/* Various adaptor functions. */ -void -gt_ggc_mx_rtx_def (x) - void *x; -{ - ggc_mark_rtx((rtx)x); -} - /* Allocate a block of memory, then clear it. */ void * ggc_alloc_cleared (size) diff --git a/gcc/ggc.h b/gcc/ggc.h index 0cd87f4dad9..b672cbecfaf 100644 --- a/gcc/ggc.h +++ b/gcc/ggc.h @@ -1,5 +1,5 @@ /* Garbage collection for the GNU compiler. - Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GCC. @@ -62,21 +62,13 @@ extern const struct ggc_cache_tab * const gt_ggc_cache_rtab[]; extern void ggc_mark_roots PARAMS ((void)); -extern void ggc_mark_rtx_children PARAMS ((struct rtx_def *)); - /* If EXPR is not NULL and previously unmarked, mark it and evaluate to true. Otherwise evaluate to false. */ #define ggc_test_and_set_mark(EXPR) \ ((EXPR) != NULL && ((void *) (EXPR)) != (void *) 1 && ! ggc_set_mark (EXPR)) -#define ggc_mark_rtx(EXPR) \ - do { \ - rtx const r__ = (EXPR); \ - if (ggc_test_and_set_mark (r__)) \ - ggc_mark_rtx_children (r__); \ - } while (0) - -#define ggc_mark_tree gt_ggc_m_tree_node +#define ggc_mark_rtx gt_ggc_m_7rtx_def +#define ggc_mark_tree gt_ggc_m_9tree_node #define ggc_mark(EXPR) \ do { \ diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index ac1b565950f..e1eb6f14558 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,7 @@ +2002-09-16 Geoffrey Keating <geoffk@apple.com> + + * java-tree.h (union lang_tree_node): Add chain_next option. + 2002-09-16 Richard Henderson <rth@redhat.com> * jcf-parse.c (get_constant): Runtime check for IEEE format; diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index a08ec5830fc..324156d2336 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -693,7 +693,8 @@ struct lang_identifier GTY(()) /* The resulting tree type. */ union lang_tree_node - GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"))) + GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"), + chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)"))) { union tree_node GTY ((tag ("0"), desc ("tree_node_structure (&%h)"))) diff --git a/gcc/rtl.c b/gcc/rtl.c index 7b6c0a1f9bd..292dcc35184 100644 --- a/gcc/rtl.c +++ b/gcc/rtl.c @@ -186,6 +186,7 @@ const char * const rtx_format[NUM_RTX_CODE] = { "u" a pointer to another insn prints the uid of the insn. "b" is a pointer to a bitmap header. + "B" is a basic block pointer. "t" is a tree pointer. */ #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT , diff --git a/gcc/rtl.h b/gcc/rtl.h index d27b9a2d41c..0fd7e6775b9 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -62,6 +62,8 @@ extern const char * const rtx_format[NUM_RTX_CODE]; extern const char rtx_class[NUM_RTX_CODE]; #define GET_RTX_CLASS(CODE) (rtx_class[(int) (CODE)]) + +extern const unsigned char rtx_next[NUM_RTX_CODE]; /* The flags and bitfields of an ADDR_DIFF_VEC. BASE is the base label relative to which the offsets are calculated, as explained in rtl.def. */ @@ -103,7 +105,7 @@ typedef struct mem_attrs GTY(()) /* Common union for an element of an rtx. */ -typedef union rtunion_def +union rtunion_def { HOST_WIDE_INT rtwint; int rtint; @@ -118,11 +120,13 @@ typedef union rtunion_def tree rttree; struct basic_block_def *bb; mem_attrs *rtmem; -} rtunion; +}; +typedef union rtunion_def rtunion; /* RTL expression ("rtx"). */ -struct rtx_def +struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"), + chain_prev ("RTX_PREV (&%h)"))) { /* The kind of expression this is. */ ENUM_BITFIELD(rtx_code) code: 16; @@ -198,11 +202,29 @@ struct rtx_def /* The first element of the operands of this rtx. The number of operands and their types are controlled by the `code' field, according to rtl.def. */ - rtunion fld[1]; + rtunion GTY ((special ("rtx_def"), + desc ("GET_CODE (&%0)"))) fld[1]; }; #define NULL_RTX (rtx) 0 +/* The "next" and "previous" RTX, relative to this one. */ + +#define RTX_NEXT(X) (rtx_next[GET_CODE (X)] == 0 ? NULL \ + : *(rtx *)(((char *)X) + rtx_next[GET_CODE (X)])) + +/* FIXME: the "NEXT_INSN (PREV_INSN (X)) == X" condition shouldn't be needed. + */ +#define RTX_PREV(X) ((GET_CODE (X) == INSN \ + || GET_CODE (X) == CALL_INSN \ + || GET_CODE (X) == JUMP_INSN \ + || GET_CODE (X) == NOTE \ + || GET_CODE (X) == BARRIER \ + || GET_CODE (X) == CODE_LABEL) \ + && PREV_INSN (X) != NULL \ + && NEXT_INSN (PREV_INSN (X)) == X \ + ? PREV_INSN (X) : NULL) + /* Define macros to access the `code' field of the rtx. */ #define GET_CODE(RTX) ((enum rtx_code) (RTX)->code) diff --git a/gcc/tree.h b/gcc/tree.h index 856a18d517e..6eab3307c8c 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -889,7 +889,7 @@ struct tree_exp GTY(()) struct tree_common common; int complexity; tree GTY ((special ("tree_exp"), - length ("TREE_CODE_LENGTH (TREE_CODE ((tree) &%h))"))) + desc ("TREE_CODE ((tree) &%0)"))) operands[1]; }; |