diff options
author | Michael Meissner <meissner@gcc.gnu.org> | 1998-07-02 13:49:34 +0000 |
---|---|---|
committer | Michael Meissner <meissner@gcc.gnu.org> | 1998-07-02 13:49:34 +0000 |
commit | 6feacd095463d1215e8797639cabad6058f49e5c (patch) | |
tree | 07fac8f9725ba2a3a78cb899e4367fe27d91d686 /gcc/regclass.c | |
parent | 39403d8233deb862fc951f95cd11280440c90880 (diff) | |
download | gcc-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.c | 140 |
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 *) ®_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 *) ®_data->data, + sizeof (reg_info) * (max - min_index + 1)); + + for (i = min_index; i <= max; i++) + { + VARRAY_REG (reg_n_info, i) = ®_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; } |