aboutsummaryrefslogtreecommitdiff
path: root/gcc/regclass.c
diff options
context:
space:
mode:
authorMichael Meissner <meissner@gcc.gnu.org>1998-07-02 13:49:34 +0000
committerMichael Meissner <meissner@gcc.gnu.org>1998-07-02 13:49:34 +0000
commit6feacd095463d1215e8797639cabad6058f49e5c (patch)
tree07fac8f9725ba2a3a78cb899e4367fe27d91d686 /gcc/regclass.c
parent39403d8233deb862fc951f95cd11280440c90880 (diff)
downloadgcc-6feacd095463d1215e8797639cabad6058f49e5c.zip
gcc-6feacd095463d1215e8797639cabad6058f49e5c.tar.gz
gcc-6feacd095463d1215e8797639cabad6058f49e5c.tar.bz2
Switch reg_n_info structure to use varrays
From-SVN: r20894
Diffstat (limited to 'gcc/regclass.c')
-rw-r--r--gcc/regclass.c140
1 files changed, 108 insertions, 32 deletions
diff --git a/gcc/regclass.c b/gcc/regclass.c
index b9238cd..d76ace3 100644
--- a/gcc/regclass.c
+++ b/gcc/regclass.c
@@ -193,6 +193,21 @@ static rtx top_of_stack[MAX_MACHINE_MODE];
#endif /* HAVE_SECONDARY_RELOADS */
+/* Linked list of reg_info structures allocated for reg_n_info array.
+ Grouping all of the allocated structures together in one lump
+ means only one call to bzero to clear them, rather than n smaller
+ calls. */
+struct reg_info_data {
+ struct reg_info_data *next; /* next set of reg_info structures */
+ size_t min_index; /* minimum index # */
+ size_t max_index; /* maximum index # */
+ char used_p; /* non-zero if this has been used previously */
+ reg_info data[1]; /* beginning of the reg_info data */
+};
+
+static struct reg_info_data *reg_info_head;
+
+
/* Function called only once to initialize the above data on reg usage.
Once this is done, various switches may override. */
@@ -637,6 +652,10 @@ static char *prefclass;
static char *altclass;
+/* Allocated buffers for prefclass and altclass. */
+static char *prefclass_buffer;
+static char *altclass_buffer;
+
/* Record the depth of loops that we are in. */
static int loop_depth;
@@ -987,8 +1006,8 @@ regclass (f, nregs)
if (pass == 0)
{
- prefclass = (char *) oballoc (nregs);
- altclass = (char *) oballoc (nregs);
+ prefclass = prefclass_buffer;
+ altclass = altclass_buffer;
}
for (i = FIRST_PSEUDO_REGISTER; i < nregs; i++)
@@ -1750,29 +1769,36 @@ auto_inc_dec_reg_p (reg, mode)
void
allocate_reg_info (num_regs, new_p, renumber_p)
- int num_regs;
+ size_t num_regs;
int new_p;
int renumber_p;
{
- static int regno_allocated = 0;
+ static size_t regno_allocated = 0;
static short *renumber = (short *)0;
int i;
- int size_info;
- int size_renumber;
- int min = (new_p) ? 0 : reg_n_max;
-
- /* If this message come up, and you want to fix it, then all of the tables
- like reg_renumber, etc. that use short will have to be found and lengthed
- to int or HOST_WIDE_INT. */
+ size_t size_info;
+ size_t size_renumber;
+ size_t min = (new_p) ? 0 : reg_n_max;
+ struct reg_info_data *reg_data;
+ struct reg_info_data *reg_next;
/* Free up all storage allocated */
if (num_regs < 0)
{
if (reg_n_info)
{
- free ((char *)reg_n_info);
- free ((char *)renumber);
- reg_n_info = (reg_info *)0;
+ VARRAY_FREE (reg_n_info);
+ for (reg_data = reg_info_head; reg_data; reg_data = reg_next)
+ {
+ reg_next = reg_data->next;
+ free ((char *)reg_data);
+ }
+
+ free (prefclass_buffer);
+ free (altclass_buffer);
+ prefclass_buffer = (char *)0;
+ altclass_buffer = (char *)0;
+ reg_info_head = (struct reg_info_data *)0;
renumber = (short *)0;
}
regno_allocated = 0;
@@ -1782,48 +1808,98 @@ allocate_reg_info (num_regs, new_p, renumber_p)
if (num_regs > regno_allocated)
{
+ size_t old_allocated = regno_allocated;
+
regno_allocated = num_regs + (num_regs / 20); /* add some slop space */
- size_info = regno_allocated * sizeof (reg_info);
size_renumber = regno_allocated * sizeof (short);
if (!reg_n_info)
{
- reg_n_info = (reg_info *) xmalloc (size_info);
- renumber = (short *) xmalloc (size_renumber);
- }
-
- else if (new_p) /* if we're zapping everything, no need to realloc */
- {
- free ((char *)reg_n_info);
- free ((char *)renumber);
- reg_n_info = (reg_info *) xmalloc (size_info);
+ VARRAY_REG_INIT (reg_n_info, regno_allocated, "reg_n_info");
renumber = (short *) xmalloc (size_renumber);
+ prefclass_buffer = (char *) xmalloc (regno_allocated);
+ altclass_buffer = (char *) xmalloc (regno_allocated);
}
else
{
- reg_n_info = (reg_info *) xrealloc ((char *)reg_n_info, size_info);
- renumber = (short *) xrealloc ((char *)renumber, size_renumber);
+ VARRAY_GROW (reg_n_info, regno_allocated);
+
+ if (new_p) /* if we're zapping everything, no need to realloc */
+ {
+ free ((char *)renumber);
+ free ((char *)prefclass_buffer);
+ free ((char *)altclass_buffer);
+ renumber = (short *) xmalloc (size_renumber);
+ prefclass_buffer = (char *) xmalloc (regno_allocated);
+ altclass_buffer = (char *) xmalloc (regno_allocated);
+ }
+
+ else
+ {
+ renumber = (short *) xrealloc ((char *)renumber, size_renumber);
+ prefclass_buffer = (char *) xrealloc ((char *)prefclass_buffer,
+ regno_allocated);
+
+ altclass_buffer = (char *) xrealloc ((char *)altclass_buffer,
+ regno_allocated);
+ }
}
+
+ size_info = (regno_allocated - old_allocated) * sizeof (reg_info)
+ + sizeof (struct reg_info_data) - sizeof (reg_info);
+ reg_data = (struct reg_info_data *) xcalloc (size_info, 1);
+ reg_data->min_index = old_allocated;
+ reg_data->max_index = regno_allocated - 1;
+ reg_data->next = reg_info_head;
+ reg_info_head = reg_data;
}
+ reg_n_max = num_regs;
if (min < num_regs)
{
- bzero ((char *) &reg_n_info[min], (num_regs - min) * sizeof (reg_info));
- for (i = min; i < num_regs; i++)
+ /* Loop through each of the segments allocated for the actual
+ reg_info pages, and set up the pointers, zero the pages, etc. */
+ for (reg_data = reg_info_head; reg_data; reg_data = reg_next)
{
- REG_BASIC_BLOCK (i) = REG_BLOCK_UNKNOWN;
- renumber[i] = -1;
+ size_t min_index = reg_data->min_index;
+ size_t max_index = reg_data->max_index;
+
+ reg_next = reg_data->next;
+ if (min_index <= num_regs)
+ {
+ size_t max = (max_index > num_regs) ? num_regs : max_index;
+ if (!reg_data->used_p) /* page just allocated with calloc */
+ reg_data->used_p = 1; /* no need to zero */
+ else
+ bzero ((char *) &reg_data->data,
+ sizeof (reg_info) * (max - min_index + 1));
+
+ for (i = min_index; i <= max; i++)
+ {
+ VARRAY_REG (reg_n_info, i) = &reg_data->data[i-min_index];
+ REG_BASIC_BLOCK (i) = REG_BLOCK_UNKNOWN;
+ renumber[i] = -1;
+ prefclass_buffer[i] = (char) NO_REGS;
+ altclass_buffer[i] = (char) NO_REGS;
+ }
+ }
}
}
+ /* If {pref,alt}class have already been allocated, update the pointers to
+ the newly realloced ones. */
+ if (prefclass)
+ {
+ prefclass = prefclass_buffer;
+ altclass = altclass_buffer;
+ }
+
if (renumber_p)
reg_renumber = renumber;
/* Tell the regset code about the new number of registers */
MAX_REGNO_REG_SET (num_regs, new_p, renumber_p);
-
- reg_n_max = num_regs;
}