+2000-06-09 Zack Weinberg <zack@wolery.cumb.org>
+
+ * ggc-none.c, ggc-simple.c, ggc-page.c (ggc_alloc_obj): Rename
+ it ggc_alloc, drop second argument, never clear returned memory.
+ * ggc-common.c (ggc_alloc_string): Use ggc_alloc.
+ (ggc_alloc_cleared): New.
+ * ggc.h: Prototype ggc_alloc and ggc_alloc_cleared, not
+ ggc_alloc_obj. Remove ggc_alloc macro.
+ (ggc_alloc_rtx, ggc_alloc_rtvec, ggc_alloc_tree): Use ggc_alloc.
+
+ * rtl.c (rtvec_alloc): Clear the vector always.
+ (rtx_alloc): Clear the first word always. Remove dirty
+ obstack tricks (this routine is no longer a bottleneck).
+ * tree.c (make_node): Clear the new node always.
+ (make_tree_vec): Likewise.
+ (tree_cons): Clear the common structure always.
+ (build1): Likewise; also, clear TREE_COMPLEXITY.
+ * gengenrtl.c: Use puts wherever possible. Remove extra
+ newlines.
+ (gendef): Clear the first word of an RTX in the generator
+ function, irrespective of ggc_p. Initialize '0' slots to
+ NULL.
+ (genlegend): Don't generate obstack_alloc_rtx routine, just a
+ thin wrapper macro around obstack_alloc.
+
+ * stmt.c (expand_fixup): Use ggc_alloc.
+ * c-typeck.c (add_pending_init): Use ggc_alloc.
+ * emit-rtl.c (init_emit_once): Clear CONST_DOUBLE_CHAIN(tem).
+ * varasm.c (immed_double_const): Set CONST_DOUBLE_MEM(r) to
+ const0_rtx when it is created.
+ (immed_real_const_1): Set CONST_DOUBLE_CHAIN(r) to NULL_RTX if
+ we are not in a function.
+
+ * tree.c (tree_class_check_failed): Make second arg an int.
+ * tree.h: Update prototype.
+
2000-06-09 Geoff Keating <geoffk@cygnus.com>
* tree.h (VOID_TYPE_P): Don't look at the TYPE_MAIN_VARIANT
- of an error_type_node.
+ of an error_mark_node.
Fri Jun 9 20:35:13 2000 Denis Chertykov <denisc@overta.ru>
}
}
- r = (struct init_node *) ggc_alloc_obj (sizeof (struct init_node), 0);
+ r = (struct init_node *) ggc_alloc (sizeof (struct init_node));
r->purpose = purpose;
r->value = value;
+2000-06-09 Zack Weinberg <zack@wolery.cumb.org>
+
+ * call.c (add_candidate): Use ggc_alloc_cleared.
+ * decl.c (lookup_label): Likewise.
+ * lex.c (retrofit_lang_decl): Likewise.
+
2000-06-09 Jason Merrill <jason@casey.soma.redhat.com>
* semantics.c (expand_body): Push to TV_EXPAND.
int viable;
{
struct z_candidate *cand
- = (struct z_candidate *) ggc_alloc_obj (sizeof (struct z_candidate), 1);
+ = (struct z_candidate *) ggc_alloc_cleared (sizeof (struct z_candidate));
cand->fn = fn;
cand->convs = convs;
We do this before calling make_label_decl so that we get the
IDENTIFIER_LABEL_VALUE before the new label is declared. */
ent = ((struct named_label_list *)
- ggc_alloc_obj (sizeof (struct named_label_list), 1));
+ ggc_alloc_cleared (sizeof (struct named_label_list)));
ent->old_value = IDENTIFIER_LABEL_VALUE (id);
ent->next = named_labels;
named_labels = ent;
else
size = sizeof (struct lang_decl_flags);
- ld = (struct lang_decl *) ggc_alloc_obj (size, 1);
+ ld = (struct lang_decl *) ggc_alloc_cleared (size);
DECL_LANG_SPECIFIC (t) = ld;
if (current_lang_name == lang_name_cplusplus)
bcopy ((char *) &u, (char *) &CONST_DOUBLE_LOW (tem), sizeof u);
CONST_DOUBLE_MEM (tem) = cc0_rtx;
+ CONST_DOUBLE_CHAIN (tem) = NULL_RTX;
PUT_MODE (tem, mode);
const_tiny_rtx[i][(int) mode] = tem;
if (*p != '0')
printf (", (ARG%d)", i++);
- printf (")\n");
+ puts (")");
}
/* Generate the code for the function to generate RTL whose
if (*p != '0')
printf (", arg%d", i++);
- printf (")\n RTX_CODE code;\n enum machine_mode mode;\n");
+ puts (")\n RTX_CODE code;\n enum machine_mode mode;");
for (p = format, i = 0; *p != 0; p++)
if (*p != '0')
printf (" %sarg%d;\n", type_from_format (*p), i++);
/* Now write out the body of the function itself, which allocates
the memory and initializes it. */
- printf ("{\n");
- printf (" rtx rt;\n");
- printf (" if (ggc_p)\n");
- printf (" rt = ggc_alloc_rtx (%d);\n",
- (int) strlen (format));
- printf (" else\n");
- printf (" rt = obstack_alloc_rtx (sizeof (struct rtx_def) + %d * sizeof (rtunion));\n",
- (int) strlen (format) - 1);
-
- printf (" PUT_CODE (rt, code);\n");
- printf (" PUT_MODE (rt, mode);\n");
+ puts ("{");
+ puts (" rtx rt;");
+ puts (" if (ggc_p)");
+ printf (" rt = ggc_alloc_rtx (%d);\n", (int) strlen (format));
+ puts (" else");
+ printf (" rt = obstack_alloc_rtx (%d);\n", (int) strlen (format));
+
+ puts (" memset (rt, 0, sizeof (struct rtx_def) - sizeof (rtunion));\n");
+ puts (" PUT_CODE (rt, code);");
+ puts (" PUT_MODE (rt, mode);");
for (p = format, i = j = 0; *p ; ++p, ++i)
if (*p != '0')
printf (" %s (rt, %d) = arg%d;\n", accessor_from_format (*p), i, j++);
+ else
+ printf (" X0EXP (rt, %d) = NULL_RTX;\n", i);
- printf ("\n return rt;\n}\n\n");
+ puts ("\n return rt;\n}\n");
}
/* Generate the documentation header for files we write. */
static void
genlegend ()
{
- printf ("/* Generated automatically by the program `gengenrtl'\n");
- printf (" from the RTL description file `rtl.def' */\n\n");
+ puts ("/* Generated automatically by gengenrtl from rtl.def. */\n");
}
/* Generate the text of the header file we make, genrtl.h. */
for (fmt = formats; *fmt; ++fmt)
gendecl (*fmt);
- printf ("\n");
+ putchar ('\n');
for (i = 0; i < NUM_RTX_CODE; i++)
if (! special_format (defs[i].format))
{
const char **fmt;
- puts ("#include \"config.h\"\n");
- puts ("#include \"system.h\"\n");
- puts ("#include \"obstack.h\"\n");
- puts ("#include \"rtl.h\"\n");
- puts ("#include \"ggc.h\"\n\n");
- puts ("extern struct obstack *rtl_obstack;\n\n");
- puts ("static rtx obstack_alloc_rtx PARAMS ((int length));\n");
- puts ("static rtx\n");
- puts ("obstack_alloc_rtx (length)\n");
- puts (" register int length;\n{\n");
- puts (" rtx rt = (rtx) obstack_alloc (rtl_obstack, length);\n\n");
- puts (" memset(rt, 0, sizeof(struct rtx_def) - sizeof(rtunion));\n\n");
- puts (" return rt;\n}\n\n");
+ puts ("#include \"config.h\"");
+ puts ("#include \"system.h\"");
+ puts ("#include \"obstack.h\"");
+ puts ("#include \"rtl.h\"");
+ puts ("#include \"ggc.h\"\n");
+ puts ("extern struct obstack *rtl_obstack;\n");
+ puts ("#define obstack_alloc_rtx(n) \\");
+ puts (" ((rtx) obstack_alloc (rtl_obstack, \\");
+ puts (" sizeof (struct rtx_def) \\");
+ puts (" + ((n) - 2) * sizeof (rtunion)))\n");
for (fmt = formats; *fmt != 0; fmt++)
gendef (*fmt);
length = strlen (contents);
}
- string = (char *) ggc_alloc_obj (length + 1, 0);
+ string = (char *) ggc_alloc (length + 1);
if (contents != NULL)
memcpy (string, contents, length);
string[length] = 0;
return string;
}
+/* Allocate a block of memory, then clear it. */
+void *
+ggc_alloc_cleared (size)
+ size_t size;
+{
+ void *buf = ggc_alloc (size);
+ memset (buf, 0, size);
+ return buf;
+}
+
/* Print statistics that are independent of the collector in use. */
void
int ggc_p = 0;
void *
-ggc_alloc_obj (size, zero)
+ggc_alloc (size)
size_t size;
- int zero;
{
- void *p = xmalloc (size);
- if (zero)
- memset (p, 0, size);
- return p;
+ return xmalloc (size);
}
memory is zeroed; otherwise, its contents are undefined. */
void *
-ggc_alloc_obj (size, zero)
+ggc_alloc (size)
size_t size;
- int zero;
{
unsigned order, word, bit, object_offset;
struct page_entry *entry;
result = entry->page + object_offset;
#ifdef GGC_POISON
- /* `Poison' the entire allocated object before zeroing the requested area,
- so that bytes beyond the end, if any, will not necessarily be zero. */
+ /* `Poison' the entire allocated object, including any padding at
+ the end. */
memset (result, 0xaf, 1 << order);
#endif
- if (zero)
- memset (result, 0, size);
-
/* Keep track of how many bytes are being allocated. This
information is used in deciding when to collect. */
G.allocated += (size_t) 1 << order;
/* Alloc SIZE bytes of GC'able memory. If ZERO, clear the memory. */
void *
-ggc_alloc_obj (size, zero)
+ggc_alloc (size)
size_t size;
- int zero;
{
struct ggc_mem *x;
x->context = G.context;
x->size = size;
- if (zero)
- memset (&x->u, 0, size);
#ifdef GGC_POISON
- else
- memset (&x->u, 0xaf, size);
+ memset (&x->u, 0xaf, size);
#endif
tree_insert (x);
/* Allocation. */
/* The internal primitive. */
-void *ggc_alloc_obj PARAMS ((size_t, int));
+void *ggc_alloc PARAMS ((size_t));
+/* Like ggc_alloc, but allocates cleared memory. */
+void *ggc_alloc_cleared PARAMS ((size_t));
-#define ggc_alloc_rtx(NSLOTS) \
- ((struct rtx_def *) ggc_alloc_obj (sizeof (struct rtx_def) \
- + ((NSLOTS) - 1) * sizeof (rtunion), 1))
+#define ggc_alloc_rtx(NSLOTS) \
+ ((struct rtx_def *) ggc_alloc (sizeof (struct rtx_def) \
+ + ((NSLOTS) - 1) * sizeof (rtunion)))
#define ggc_alloc_rtvec(NELT) \
- ((struct rtvec_def *) ggc_alloc_obj (sizeof (struct rtvec_def) \
- + ((NELT) - 1) * sizeof (rtx), 1))
+ ((struct rtvec_def *) ggc_alloc (sizeof (struct rtvec_def) \
+ + ((NELT) - 1) * sizeof (rtx)))
-#define ggc_alloc_tree(LENGTH) \
- ((union tree_node *) ggc_alloc_obj ((LENGTH), 1))
-
-#define ggc_alloc(SIZE) ggc_alloc_obj((SIZE), 0)
+#define ggc_alloc_tree(LENGTH) ((union tree_node *) ggc_alloc (LENGTH))
char *ggc_alloc_string PARAMS ((const char *contents, int length));
if (ggc_p)
rt = ggc_alloc_rtvec (n);
else
- {
- int i;
-
- rt = (rtvec) obstack_alloc (rtl_obstack,
- sizeof (struct rtvec_def)
- + (( n - 1) * sizeof (rtx)));
-
- /* clear out the vector */
- for (i = 0; i < n; i++)
- rt->elem[i] = 0;
- }
+ rt = (rtvec) obstack_alloc (rtl_obstack,
+ sizeof (struct rtvec_def)
+ + ((n - 1) * sizeof (rtx)));
+ /* clear out the vector */
+ memset (&rt->elem[0], 0, n * sizeof (rtx));
PUT_NUM_ELEM (rt, n);
return rt;
RTX_CODE code;
{
rtx rt;
+ int n = GET_RTX_LENGTH (code);
if (ggc_p)
- rt = ggc_alloc_rtx (GET_RTX_LENGTH (code));
+ rt = ggc_alloc_rtx (n);
else
- {
- register struct obstack *ob = rtl_obstack;
- register int nelts = GET_RTX_LENGTH (code);
- register int length = sizeof (struct rtx_def)
- + (nelts - 1) * sizeof (rtunion);
-
- /* This function is called more than any other in GCC, so we
- manipulate the obstack directly.
+ rt = (rtx) obstack_alloc (rtl_obstack,
+ sizeof (struct rtx_def)
+ + ((n - 1) * sizeof (rtunion)));
- Even though rtx objects are word aligned, we may be sharing
- an obstack with tree nodes, which may have to be double-word
- aligned. So align our length to the alignment mask in the
- obstack. */
-
- length = (length + ob->alignment_mask) & ~ ob->alignment_mask;
-
- if (ob->chunk_limit - ob->next_free < length)
- _obstack_newchunk (ob, length);
- rt = (rtx)ob->object_base;
- ob->next_free += length;
- ob->object_base = ob->next_free;
-
- /* We want to clear everything up to the FLD array. Normally,
- this is one int, but we don't want to assume that and it
- isn't very portable anyway; this is. */
-
- memset (rt, 0, sizeof (struct rtx_def) - sizeof (rtunion));
- }
+ /* We want to clear everything up to the FLD array. Normally, this
+ is one int, but we don't want to assume that and it isn't very
+ portable anyway; this is. */
+ memset (rt, 0, sizeof (struct rtx_def) - sizeof (rtunion));
PUT_CODE (rt, code);
return rt;
}
{
/* Ok, a fixup is needed. Add a fixup to the list of such. */
struct goto_fixup *fixup
- = (struct goto_fixup *) ggc_alloc_obj (sizeof (struct goto_fixup), 0);
+ = (struct goto_fixup *) ggc_alloc (sizeof (struct goto_fixup));
/* In case an old stack level is restored, make sure that comes
after any pending stack adjust. */
/* ?? If the fixup isn't to come at the present position,
if (ggc_p)
t = ggc_alloc_tree (length);
else
- {
- t = (tree) obstack_alloc (obstack, length);
- memset ((PTR) t, 0, length);
- }
+ t = (tree) obstack_alloc (obstack, length);
+
+ memset ((PTR) t, 0, length);
#ifdef GATHER_STATISTICS
tree_node_counts[(int)kind]++;
if (ggc_p)
t = ggc_alloc_tree (length);
else
- {
- t = (tree) obstack_alloc (obstack, length);
- bzero ((PTR) t, length);
- }
+ t = (tree) obstack_alloc (obstack, length);
+ memset ((PTR) t, 0, length);
TREE_SET_CODE (t, TREE_VEC);
TREE_VEC_LENGTH (t) = len;
TREE_SET_PERMANENT (t);
if (ggc_p)
node = ggc_alloc_tree (sizeof (struct tree_list));
else
- {
- node = (tree) obstack_alloc (current_obstack, sizeof (struct tree_list));
- memset (node, 0, sizeof (struct tree_common));
- }
+ node = (tree) obstack_alloc (current_obstack, sizeof (struct tree_list));
+
+ memset (node, 0, sizeof (struct tree_common));
#ifdef GATHER_STATISTICS
tree_node_counts[(int) x_kind]++;
if (ggc_p)
t = ggc_alloc_tree (length);
else
- {
- t = (tree) obstack_alloc (obstack, length);
- memset ((PTR) t, 0, length);
- }
+ t = (tree) obstack_alloc (obstack, length);
+
+ memset ((PTR) t, 0, sizeof (struct tree_common));
#ifdef GATHER_STATISTICS
tree_node_counts[(int)kind]++;
tree_node_sizes[(int)kind] += length;
#endif
- TREE_TYPE (t) = type;
TREE_SET_CODE (t, code);
TREE_SET_PERMANENT (t);
+ TREE_TYPE (t) = type;
+ TREE_COMPLEXITY (t) = 0;
TREE_OPERAND (t, 0) = node;
if (node && first_rtl_op (code) != 0 && TREE_SIDE_EFFECTS (node))
TREE_SIDE_EFFECTS (t) = 1;
void
tree_class_check_failed (node, cl, file, line, function)
const tree node;
- char cl;
+ int cl;
const char *file;
int line;
const char *function;
__t; })
extern void tree_check_failed PARAMS ((const tree, enum tree_code,
- const char *, int, const char *))
+ const char *, int, const char *))
ATTRIBUTE_NORETURN;
-extern void tree_class_check_failed PARAMS ((const tree, char,
- const char *, int, const char *))
+extern void tree_class_check_failed PARAMS ((const tree, int,
+ const char *, int, const char *))
ATTRIBUTE_NORETURN;
#else /* not ENABLE_TREE_CHECKING, or not gcc */
push_obstacks_nochange ();
rtl_in_saveable_obstack ();
- r = gen_rtx_CONST_DOUBLE (mode, NULL_RTX, i0, i1);
+ r = gen_rtx_CONST_DOUBLE (mode, const0_rtx, i0, i1);
pop_obstacks ();
/* Don't touch const_double_chain if not inside any function. */
const_double_chain = r;
}
- /* Store const0_rtx in mem-slot since this CONST_DOUBLE is on the chain.
- Actual use of mem-slot is only through force_const_mem. */
-
- CONST_DOUBLE_MEM (r) = const0_rtx;
-
return r;
}
PUT_MODE (r, mode);
bcopy ((char *) &u, (char *) &CONST_DOUBLE_LOW (r), sizeof u);
- /* Don't touch const_double_chain if not inside any function. */
+ /* If we aren't inside a function, don't put r on the
+ const_double_chain. */
if (current_function_decl != 0)
{
CONST_DOUBLE_CHAIN (r) = const_double_chain;
const_double_chain = r;
}
+ else
+ CONST_DOUBLE_CHAIN (r) = NULL_RTX;
/* Store const0_rtx in CONST_DOUBLE_MEM since this CONST_DOUBLE is on the
chain, but has not been allocated memory. Actual use of CONST_DOUBLE_MEM