/* A hash table storing CONST_INTs whose absolute value is greater
than MAX_SAVED_CONST_INT. */
-static htab_t const_int_htab;
+static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
+ htab_t const_int_htab;
/* A hash table storing memory attribute structures. */
-static htab_t mem_attrs_htab;
+static GTY ((if_marked ("ggc_marked_p"), param_is (struct mem_attrs)))
+ htab_t mem_attrs_htab;
/* A hash table storing all CONST_DOUBLEs. */
-static htab_t const_double_htab;
+static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
+ htab_t const_double_htab;
#define first_insn (cfun->emit->x_first_insn)
#define last_insn (cfun->emit->x_last_insn)
static rtx make_jump_insn_raw PARAMS ((rtx));
static rtx make_call_insn_raw PARAMS ((rtx));
static rtx find_line_note PARAMS ((rtx));
-static void mark_sequence_stack PARAMS ((struct sequence_stack *));
static rtx change_address_1 PARAMS ((rtx, enum machine_mode, rtx,
int));
static void unshare_all_rtl_1 PARAMS ((rtx));
static hashval_t mem_attrs_htab_hash PARAMS ((const void *));
static int mem_attrs_htab_eq PARAMS ((const void *,
const void *));
-static void mem_attrs_mark PARAMS ((const void *));
static mem_attrs *get_mem_attrs PARAMS ((HOST_WIDE_INT, tree, rtx,
rtx, unsigned int,
enum machine_mode));
&& p->size == q->size && p->align == q->align);
}
-/* This routine is called when we determine that we need a mem_attrs entry.
- It marks the associated decl and RTL as being used, if present. */
-
-static void
-mem_attrs_mark (x)
- const void *x;
-{
- mem_attrs *p = (mem_attrs *) x;
-
- if (p->expr)
- ggc_mark_tree (p->expr);
-
- if (p->offset)
- ggc_mark_rtx (p->offset);
-
- if (p->size)
- ggc_mark_rtx (p->size);
-}
-
/* Allocate a new mem_attrs structure and insert it into the hash table if
one identical to it is not already in the table. We are doing this for
MEM of mode MODE. */
rtx *new1;
tree *new2;
- new = xrealloc (f->emit->regno_pointer_align, old_size * 2);
+ new = ggc_realloc (f->emit->regno_pointer_align, old_size * 2);
memset (new + old_size, 0, old_size);
f->emit->regno_pointer_align = (unsigned char *) new;
- new1 = (rtx *) xrealloc (f->emit->x_regno_reg_rtx,
- old_size * 2 * sizeof (rtx));
+ new1 = (rtx *) ggc_realloc (f->emit->x_regno_reg_rtx,
+ old_size * 2 * sizeof (rtx));
memset (new1 + old_size, 0, old_size * sizeof (rtx));
regno_reg_rtx = new1;
- new2 = (tree *) xrealloc (f->emit->regno_decl,
- old_size * 2 * sizeof (tree));
+ new2 = (tree *) ggc_realloc (f->emit->regno_decl,
+ old_size * 2 * sizeof (tree));
memset (new2 + old_size, 0, old_size * sizeof (tree));
f->emit->regno_decl = new2;
{
last_label_num = 0;
}
-
-/* Clear out all parts of the state in F that can safely be discarded
- after the function has been compiled, to let garbage collection
- reclaim the memory. */
-
-void
-free_emit_status (f)
- struct function *f;
-{
- free (f->emit->x_regno_reg_rtx);
- free (f->emit->regno_pointer_align);
- free (f->emit->regno_decl);
- free (f->emit);
- f->emit = NULL;
-}
\f
/* Go through all the RTL insn bodies and copy any invalid shared
structure. This routine should only be called once. */
abort ();
}
\f
+/* Space for free sequence stack entries. */
+static GTY ((deletable (""))) struct sequence_stack *free_sequence_stack;
+
/* Begin emitting insns to a sequence which can be packaged in an
RTL_EXPR. If this sequence will contain something that might cause
the compiler to pop arguments to function calls (because those
{
struct sequence_stack *tem;
- tem = (struct sequence_stack *) xmalloc (sizeof (struct sequence_stack));
+ if (free_sequence_stack != NULL)
+ {
+ tem = free_sequence_stack;
+ free_sequence_stack = tem->next;
+ }
+ else
+ tem = (struct sequence_stack *) ggc_alloc (sizeof (struct sequence_stack));
tem->next = seq_stack;
tem->first = first_insn;
seq_rtl_expr = tem->sequence_rtl_expr;
seq_stack = tem->next;
- free (tem);
+ memset (tem, 0, sizeof (*tem));
+ tem->next = free_sequence_stack;
+ free_sequence_stack = tem;
}
/* This works like end_sequence, but records the old sequence in FIRST
{
struct function *f = cfun;
- f->emit = (struct emit_status *) xmalloc (sizeof (struct emit_status));
+ f->emit = (struct emit_status *) ggc_alloc (sizeof (struct emit_status));
first_insn = NULL;
last_insn = NULL;
seq_rtl_expr = NULL;
f->emit->regno_pointer_align_length = LAST_VIRTUAL_REGISTER + 101;
f->emit->regno_pointer_align
- = (unsigned char *) xcalloc (f->emit->regno_pointer_align_length,
- sizeof (unsigned char));
+ = (unsigned char *) ggc_alloc_cleared (f->emit->regno_pointer_align_length
+ * sizeof (unsigned char));
regno_reg_rtx
- = (rtx *) xcalloc (f->emit->regno_pointer_align_length, sizeof (rtx));
+ = (rtx *) ggc_alloc_cleared (f->emit->regno_pointer_align_length
+ * sizeof (rtx));
f->emit->regno_decl
- = (tree *) xcalloc (f->emit->regno_pointer_align_length, sizeof (tree));
+ = (tree *) ggc_alloc_cleared (f->emit->regno_pointer_align_length
+ * sizeof (tree));
/* Put copies of all the virtual register rtx into regno_reg_rtx. */
init_virtual_regs (f->emit);
#endif
}
-/* Mark SS for GC. */
-
-static void
-mark_sequence_stack (ss)
- struct sequence_stack *ss;
-{
- while (ss)
- {
- ggc_mark_rtx (ss->first);
- ggc_mark_tree (ss->sequence_rtl_expr);
- ss = ss->next;
- }
-}
-
-/* Mark ES for GC. */
-
-void
-mark_emit_status (es)
- struct emit_status *es;
-{
- rtx *r;
- tree *t;
- int i;
-
- if (es == 0)
- return;
-
- for (i = es->regno_pointer_align_length, r = es->x_regno_reg_rtx,
- t = es->regno_decl;
- i > 0; --i, ++r, ++t)
- {
- ggc_mark_rtx (*r);
- ggc_mark_tree (*t);
- }
-
- mark_sequence_stack (es->sequence_stack);
- ggc_mark_tree (es->sequence_rtl_expr);
- ggc_mark_rtx (es->x_first_insn);
-}
-
/* Generate the constant 0. */
static rtx
tables. */
const_int_htab = htab_create (37, const_int_htab_hash,
const_int_htab_eq, NULL);
- ggc_add_deletable_htab (const_int_htab, 0, 0);
const_double_htab = htab_create (37, const_double_htab_hash,
const_double_htab_eq, NULL);
- ggc_add_deletable_htab (const_double_htab, 0, 0);
mem_attrs_htab = htab_create (37, mem_attrs_htab_hash,
mem_attrs_htab_eq, NULL);
- ggc_add_deletable_htab (mem_attrs_htab, 0, mem_attrs_mark);
no_line_numbers = ! line_numbers;
gen_raw_REG (Pmode, VIRTUAL_OUTGOING_ARGS_REGNUM);
virtual_cfa_rtx = gen_raw_REG (Pmode, VIRTUAL_CFA_REGNUM);
- /* These rtx must be roots if GC is enabled. */
- ggc_add_rtx_root (global_rtl, GR_MAX);
-
#ifdef INIT_EXPANDERS
/* This is to initialize {init|mark|free}_machine_status before the first
call to push_function_context_to. This is needed by the Chill front
for (i = - MAX_SAVED_CONST_INT; i <= MAX_SAVED_CONST_INT; i++)
const_int_rtx[i + MAX_SAVED_CONST_INT] =
gen_rtx_raw_CONST_INT (VOIDmode, i);
- ggc_add_rtx_root (const_int_rtx, 2 * MAX_SAVED_CONST_INT + 1);
if (STORE_FLAG_VALUE >= - MAX_SAVED_CONST_INT
&& STORE_FLAG_VALUE <= MAX_SAVED_CONST_INT)
if (STORE_FLAG_VALUE == 1)
const_tiny_rtx[1][(int) BImode] = const1_rtx;
- /* For bounded pointers, `&const_tiny_rtx[0][0]' is not the same as
- `(rtx *) const_tiny_rtx'. The former has bounds that only cover
- `const_tiny_rtx[0]', whereas the latter has bounds that cover all. */
- ggc_add_rtx_root ((rtx *) const_tiny_rtx, sizeof const_tiny_rtx / sizeof (rtx));
- ggc_add_rtx_root (&const_true_rtx, 1);
-
#ifdef RETURN_ADDRESS_POINTER_REGNUM
return_address_pointer_rtx
= gen_raw_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM);
if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
pic_offset_table_rtx = gen_raw_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
-
- ggc_add_rtx_root (&pic_offset_table_rtx, 1);
- ggc_add_rtx_root (&struct_value_rtx, 1);
- ggc_add_rtx_root (&struct_value_incoming_rtx, 1);
- ggc_add_rtx_root (&static_chain_rtx, 1);
- ggc_add_rtx_root (&static_chain_incoming_rtx, 1);
- ggc_add_rtx_root (&return_address_pointer_rtx, 1);
}
\f
/* Query and clear/ restore no_line_numbers. This is used by the
}
return new;
}
+
+#include "gt-emit-rtl.h"