Use varrays for constant-equivalence data:
* varray.h (struct const_equiv_data): New type. (union varray_data_tag): New element const_equiv. (VARRAY_CONST_EQUIV_INIT, VARRAY_CONST_EQUIV): New macros. (VARRAY_SIZE): New macro, returns number of elements. * integrate.h: Include varray.h. (struct inline_remap): Replace const_equiv_map, const_age_map and const_equiv_map_size with a const_equiv_varray element. (MAYBE_EXTEND_CONST_EQUIV_VARRAY): New macro; grows varray if needed. (SET_CONST_EQUIV_DATA): New macro; sets rtx and age fields simultaneously, growing the varray if needed. * integrate.c (global_const_equiv_map, global_const_equiv_map_size): Deleted, replaced by.... (global_const_equiv_varray): New variable. (expand_inline_function): References changed. * integrate.h: Update declarations. * integrate.c (process_reg_parm, expand_inline_function, copy_rtx_and_substitute, try_constants, subst_constants, mark_stores): Use varray allocation and accessor macros, new integrate.h macros, and global_const_equiv_varray. Don't conditionalize non-NULL stores on array size; instead, expand the array as needed. * unroll.c (unroll_loop): Likewise. * unroll.c (unroll_loop): Initialize const_equiv_varray element to zero. After allocating varray, always exit through bottom of function, where it can be deallocated if needed. Don't explicitly reallocate const_equiv_map storage; instead, just ensure the varray has been initialized, and update the global reference. From-SVN: r24956
This commit is contained in:
parent
9594b1b2a1
commit
c68da89c45
@ -1,3 +1,39 @@
|
||||
Mon Feb 1 15:00:02 1999 Ken Raeburn <raeburn@cygnus.com>
|
||||
|
||||
Use varrays for constant-equivalence data:
|
||||
|
||||
* varray.h (struct const_equiv_data): New type.
|
||||
(union varray_data_tag): New element const_equiv.
|
||||
(VARRAY_CONST_EQUIV_INIT, VARRAY_CONST_EQUIV): New macros.
|
||||
(VARRAY_SIZE): New macro, returns number of elements.
|
||||
* integrate.h: Include varray.h.
|
||||
(struct inline_remap): Replace const_equiv_map, const_age_map and
|
||||
const_equiv_map_size with a const_equiv_varray element.
|
||||
(MAYBE_EXTEND_CONST_EQUIV_VARRAY): New macro; grows varray if
|
||||
needed.
|
||||
(SET_CONST_EQUIV_DATA): New macro; sets rtx and age fields
|
||||
simultaneously, growing the varray if needed.
|
||||
|
||||
* integrate.c (global_const_equiv_map,
|
||||
global_const_equiv_map_size): Deleted, replaced by....
|
||||
(global_const_equiv_varray): New variable.
|
||||
(expand_inline_function): References changed.
|
||||
* integrate.h: Update declarations.
|
||||
|
||||
* integrate.c (process_reg_parm, expand_inline_function,
|
||||
copy_rtx_and_substitute, try_constants, subst_constants,
|
||||
mark_stores): Use varray allocation and accessor macros, new
|
||||
integrate.h macros, and global_const_equiv_varray. Don't
|
||||
conditionalize non-NULL stores on array size; instead, expand the
|
||||
array as needed.
|
||||
* unroll.c (unroll_loop): Likewise.
|
||||
|
||||
* unroll.c (unroll_loop): Initialize const_equiv_varray element to
|
||||
zero. After allocating varray, always exit through bottom of
|
||||
function, where it can be deallocated if needed. Don't explicitly
|
||||
reallocate const_equiv_map storage; instead, just ensure the
|
||||
varray has been initialized, and update the global reference.
|
||||
|
||||
Mon Feb 1 09:40:25 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* system.h (inline, const): Handle these for stage2 (and later) gcc.
|
||||
|
129
gcc/integrate.c
129
gcc/integrate.c
@ -1301,8 +1301,7 @@ copy_for_inline (orig)
|
||||
with a function called from note_stores. Be *very* careful that this
|
||||
is used properly in the presence of recursion. */
|
||||
|
||||
rtx *global_const_equiv_map;
|
||||
int global_const_equiv_map_size;
|
||||
varray_type global_const_equiv_varray;
|
||||
|
||||
#define FIXED_BASE_PLUS_P(X) \
|
||||
(GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
|
||||
@ -1332,12 +1331,8 @@ process_reg_param (map, loc, copy)
|
||||
{
|
||||
rtx temp = copy_to_mode_reg (GET_MODE (loc), copy);
|
||||
REG_USERVAR_P (temp) = REG_USERVAR_P (loc);
|
||||
if ((CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
|
||||
&& REGNO (temp) < map->const_equiv_map_size)
|
||||
{
|
||||
map->const_equiv_map[REGNO (temp)] = copy;
|
||||
map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
|
||||
}
|
||||
if (CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
|
||||
SET_CONST_EQUIV_DATA (map, temp, copy, CONST_AGE_PARM);
|
||||
copy = temp;
|
||||
}
|
||||
map->reg_map[REGNO (loc)] = copy;
|
||||
@ -1392,7 +1387,7 @@ expand_inline_function (fndecl, parms, target, ignore, type,
|
||||
rtx loc;
|
||||
rtx stack_save = 0;
|
||||
rtx temp;
|
||||
struct inline_remap *map;
|
||||
struct inline_remap *map = 0;
|
||||
#ifdef HAVE_cc0
|
||||
rtx cc0_insn = 0;
|
||||
#endif
|
||||
@ -1554,30 +1549,25 @@ expand_inline_function (fndecl, parms, target, ignore, type,
|
||||
|
||||
map->integrating = 1;
|
||||
|
||||
/* const_equiv_map maps pseudos in our routine to constants, so it needs to
|
||||
be large enough for all our pseudos. This is the number we are currently
|
||||
using plus the number in the called routine, plus 15 for each arg,
|
||||
five to compute the virtual frame pointer, and five for the return value.
|
||||
This should be enough for most cases. We do not reference entries
|
||||
outside the range of the map.
|
||||
/* const_equiv_varray maps pseudos in our routine to constants, so
|
||||
it needs to be large enough for all our pseudos. This is the
|
||||
number we are currently using plus the number in the called
|
||||
routine, plus 15 for each arg, five to compute the virtual frame
|
||||
pointer, and five for the return value. This should be enough
|
||||
for most cases. We do not reference entries outside the range of
|
||||
the map.
|
||||
|
||||
??? These numbers are quite arbitrary and were obtained by
|
||||
experimentation. At some point, we should try to allocate the
|
||||
table after all the parameters are set up so we an more accurately
|
||||
estimate the number of pseudos we will need. */
|
||||
|
||||
map->const_equiv_map_size
|
||||
= max_reg_num () + (max_regno - FIRST_PSEUDO_REGISTER) + 15 * nargs + 10;
|
||||
|
||||
map->const_equiv_map
|
||||
= (rtx *)alloca (map->const_equiv_map_size * sizeof (rtx));
|
||||
bzero ((char *) map->const_equiv_map,
|
||||
map->const_equiv_map_size * sizeof (rtx));
|
||||
|
||||
map->const_age_map
|
||||
= (unsigned *)alloca (map->const_equiv_map_size * sizeof (unsigned));
|
||||
bzero ((char *) map->const_age_map,
|
||||
map->const_equiv_map_size * sizeof (unsigned));
|
||||
VARRAY_CONST_EQUIV_INIT (map->const_equiv_varray,
|
||||
(max_reg_num ()
|
||||
+ (max_regno - FIRST_PSEUDO_REGISTER)
|
||||
+ 15 * nargs
|
||||
+ 10),
|
||||
"expand_inline_function");
|
||||
map->const_age = 0;
|
||||
|
||||
/* Record the current insn in case we have to set up pointers to frame
|
||||
@ -1646,12 +1636,8 @@ expand_inline_function (fndecl, parms, target, ignore, type,
|
||||
if (GET_CODE (copy) != REG)
|
||||
{
|
||||
temp = copy_addr_to_reg (copy);
|
||||
if ((CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
|
||||
&& REGNO (temp) < map->const_equiv_map_size)
|
||||
{
|
||||
map->const_equiv_map[REGNO (temp)] = copy;
|
||||
map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
|
||||
}
|
||||
if (CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
|
||||
SET_CONST_EQUIV_DATA (map, temp, copy, CONST_AGE_PARM);
|
||||
copy = temp;
|
||||
}
|
||||
map->reg_map[REGNO (XEXP (loc, 0))] = copy;
|
||||
@ -1751,17 +1737,16 @@ expand_inline_function (fndecl, parms, target, ignore, type,
|
||||
temp = force_reg (Pmode, temp);
|
||||
map->reg_map[REGNO (XEXP (loc, 0))] = temp;
|
||||
|
||||
if ((CONSTANT_P (structure_value_addr)
|
||||
|| GET_CODE (structure_value_addr) == ADDRESSOF
|
||||
|| (GET_CODE (structure_value_addr) == PLUS
|
||||
&& (XEXP (structure_value_addr, 0)
|
||||
== virtual_stack_vars_rtx)
|
||||
&& (GET_CODE (XEXP (structure_value_addr, 1))
|
||||
== CONST_INT)))
|
||||
&& REGNO (temp) < map->const_equiv_map_size)
|
||||
if (CONSTANT_P (structure_value_addr)
|
||||
|| GET_CODE (structure_value_addr) == ADDRESSOF
|
||||
|| (GET_CODE (structure_value_addr) == PLUS
|
||||
&& (XEXP (structure_value_addr, 0)
|
||||
== virtual_stack_vars_rtx)
|
||||
&& (GET_CODE (XEXP (structure_value_addr, 1))
|
||||
== CONST_INT)))
|
||||
{
|
||||
map->const_equiv_map[REGNO (temp)] = structure_value_addr;
|
||||
map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
|
||||
SET_CONST_EQUIV_DATA (map, temp, structure_value_addr,
|
||||
CONST_AGE_PARM);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1864,10 +1849,9 @@ expand_inline_function (fndecl, parms, target, ignore, type,
|
||||
/* Clean up stack so that variables might have smaller offsets. */
|
||||
do_pending_stack_adjust ();
|
||||
|
||||
/* Save a copy of the location of const_equiv_map for mark_stores, called
|
||||
via note_stores. */
|
||||
global_const_equiv_map = map->const_equiv_map;
|
||||
global_const_equiv_map_size = map->const_equiv_map_size;
|
||||
/* Save a copy of the location of const_equiv_varray for
|
||||
mark_stores, called via note_stores. */
|
||||
global_const_equiv_varray = map->const_equiv_varray;
|
||||
|
||||
/* If the called function does an alloca, save and restore the
|
||||
stack pointer around the call. This saves stack space, but
|
||||
@ -2051,7 +2035,7 @@ expand_inline_function (fndecl, parms, target, ignore, type,
|
||||
|
||||
/* Be lazy and assume CALL_INSNs clobber all hard registers. */
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
map->const_equiv_map[i] = 0;
|
||||
VARRAY_CONST_EQUIV (map->const_equiv_varray, i).rtx = 0;
|
||||
break;
|
||||
|
||||
case CODE_LABEL:
|
||||
@ -2186,6 +2170,8 @@ expand_inline_function (fndecl, parms, target, ignore, type,
|
||||
/* Make sure we free the things we explicitly allocated with xmalloc. */
|
||||
if (real_label_map)
|
||||
free (real_label_map);
|
||||
if (map)
|
||||
VARRAY_FREE (map->const_equiv_varray);
|
||||
|
||||
return target;
|
||||
}
|
||||
@ -2389,11 +2375,7 @@ copy_rtx_and_substitute (orig, map)
|
||||
STACK_BOUNDARY / BITS_PER_UNIT);
|
||||
#endif
|
||||
|
||||
if (REGNO (temp) < map->const_equiv_map_size)
|
||||
{
|
||||
map->const_equiv_map[REGNO (temp)] = loc;
|
||||
map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
|
||||
}
|
||||
SET_CONST_EQUIV_DATA (map, temp, loc, CONST_AGE_PARM);
|
||||
|
||||
seq = gen_sequence ();
|
||||
end_sequence ();
|
||||
@ -2424,11 +2406,7 @@ copy_rtx_and_substitute (orig, map)
|
||||
STACK_BOUNDARY / BITS_PER_UNIT);
|
||||
#endif
|
||||
|
||||
if (REGNO (temp) < map->const_equiv_map_size)
|
||||
{
|
||||
map->const_equiv_map[REGNO (temp)] = loc;
|
||||
map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
|
||||
}
|
||||
SET_CONST_EQUIV_DATA (map, temp, loc, CONST_AGE_PARM);
|
||||
|
||||
seq = gen_sequence ();
|
||||
end_sequence ();
|
||||
@ -2710,7 +2688,7 @@ copy_rtx_and_substitute (orig, map)
|
||||
|
||||
copy_rtx_and_substitute (SET_DEST (orig), map);
|
||||
equiv_reg = map->reg_map[REGNO (SET_DEST (orig))];
|
||||
equiv_loc = map->const_equiv_map[REGNO (equiv_reg)];
|
||||
equiv_loc = VARRAY_CONST_EQUIV (map->const_equiv_varray, REGNO (equiv_reg)).rtx;
|
||||
loc_offset
|
||||
= GET_CODE (equiv_loc) == REG ? 0 : INTVAL (XEXP (equiv_loc, 1));
|
||||
return gen_rtx_SET (VOIDmode, SET_DEST (orig),
|
||||
@ -2836,16 +2814,15 @@ try_constants (insn, map)
|
||||
{
|
||||
int regno = REGNO (map->equiv_sets[i].dest);
|
||||
|
||||
if (regno < map->const_equiv_map_size
|
||||
&& (map->const_equiv_map[regno] == 0
|
||||
/* Following clause is a hack to make case work where GNU C++
|
||||
reassigns a variable to make cse work right. */
|
||||
|| ! rtx_equal_p (map->const_equiv_map[regno],
|
||||
map->equiv_sets[i].equiv)))
|
||||
{
|
||||
map->const_equiv_map[regno] = map->equiv_sets[i].equiv;
|
||||
map->const_age_map[regno] = map->const_age;
|
||||
}
|
||||
MAYBE_EXTEND_CONST_EQUIV_VARRAY (map, regno);
|
||||
if (VARRAY_CONST_EQUIV (map->const_equiv_varray, regno).rtx == 0
|
||||
/* Following clause is a hack to make case work where GNU C++
|
||||
reassigns a variable to make cse work right. */
|
||||
|| ! rtx_equal_p (VARRAY_CONST_EQUIV (map->const_equiv_varray,
|
||||
regno).rtx,
|
||||
map->equiv_sets[i].equiv))
|
||||
SET_CONST_EQUIV_DATA (map, map->equiv_sets[i].dest,
|
||||
map->equiv_sets[i].equiv, map->const_age);
|
||||
}
|
||||
else if (map->equiv_sets[i].dest == pc_rtx)
|
||||
map->last_pc_value = map->equiv_sets[i].equiv;
|
||||
@ -2915,12 +2892,14 @@ subst_constants (loc, insn, map)
|
||||
hard regs used as user variables with constants. */
|
||||
{
|
||||
int regno = REGNO (x);
|
||||
struct const_equiv_data *p;
|
||||
|
||||
if (! (regno < FIRST_PSEUDO_REGISTER && REG_USERVAR_P (x))
|
||||
&& regno < map->const_equiv_map_size
|
||||
&& map->const_equiv_map[regno] != 0
|
||||
&& map->const_age_map[regno] >= map->const_age)
|
||||
validate_change (insn, loc, map->const_equiv_map[regno], 1);
|
||||
&& regno < VARRAY_SIZE (map->const_equiv_varray)
|
||||
&& (p = &VARRAY_CONST_EQUIV (map->const_equiv_varray, regno),
|
||||
p->rtx != 0)
|
||||
&& p->age >= map->const_age)
|
||||
validate_change (insn, loc, p->rtx, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3163,8 +3142,8 @@ mark_stores (dest, x)
|
||||
if (regno != VIRTUAL_INCOMING_ARGS_REGNUM
|
||||
&& regno != VIRTUAL_STACK_VARS_REGNUM)
|
||||
for (i = regno; i <= last_reg; i++)
|
||||
if (i < global_const_equiv_map_size)
|
||||
global_const_equiv_map[i] = 0;
|
||||
if (i < VARRAY_SIZE (global_const_equiv_varray))
|
||||
VARRAY_CONST_EQUIV (global_const_equiv_varray, i).rtx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,8 @@ along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "varray.h"
|
||||
|
||||
/* This structure is used to remap objects in the function being inlined to
|
||||
those belonging to the calling function. It is passed by
|
||||
expand_inline_function to its children.
|
||||
@ -67,19 +69,15 @@ struct inline_remap
|
||||
pseudos that contain pointers into the replacement area allocated for
|
||||
this inline instance. These pseudos are then marked as being equivalent
|
||||
to the appropriate address and substituted if valid. */
|
||||
rtx *const_equiv_map;
|
||||
/* Number of entries in const_equiv_map and const_arg_map. */
|
||||
int const_equiv_map_size;
|
||||
varray_type const_equiv_varray;
|
||||
/* This is incremented for each new basic block.
|
||||
It is used to store in const_age_map to record the domain of validity
|
||||
of each entry in const_equiv_map.
|
||||
It is used to store in the age field to record the domain of validity
|
||||
of each entry in const_equiv_varray.
|
||||
A value of -1 indicates an entry for a reg which is a parm.
|
||||
All other values are "positive". */
|
||||
#define CONST_AGE_PARM (-1)
|
||||
unsigned int const_age;
|
||||
/* In parallel with const_equiv_map, record the valid age for each entry.
|
||||
The entry is invalid if its age is less than const_age. */
|
||||
unsigned int *const_age_map;
|
||||
|
||||
/* Target of the inline function being expanded, or NULL if none. */
|
||||
rtx inline_target;
|
||||
/* When an insn is being copied by copy_rtx_and_substitute,
|
||||
@ -128,9 +126,29 @@ extern rtx get_label_from_map PROTO((struct inline_remap *, int));
|
||||
/* Set the label indicated. */
|
||||
#define set_label_in_map(MAP, I, X) ((MAP)->label_map[I] = (X))
|
||||
|
||||
/* Unfortunately, we need a global copy of const_equiv map for communication
|
||||
with a function called from note_stores. Be *very* careful that this
|
||||
is used properly in the presence of recursion. */
|
||||
/* Unfortunately, we need a global copy of const_equiv varray for
|
||||
communication with a function called from note_stores. Be *very*
|
||||
careful that this is used properly in the presence of recursion. */
|
||||
|
||||
extern rtx *global_const_equiv_map;
|
||||
extern int global_const_equiv_map_size;
|
||||
extern varray_type global_const_equiv_varray;
|
||||
|
||||
#define MAYBE_EXTEND_CONST_EQUIV_VARRAY(MAP,MAX) \
|
||||
{ \
|
||||
if ((MAX) >= VARRAY_SIZE ((MAP)->const_equiv_varray)) \
|
||||
{ \
|
||||
int is_global = (global_const_equiv_varray \
|
||||
== (MAP)->const_equiv_varray); \
|
||||
VARRAY_GROW ((MAP)->const_equiv_varray, (MAX)+1); \
|
||||
if (is_global) \
|
||||
global_const_equiv_varray = (MAP)->const_equiv_varray; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SET_CONST_EQUIV_DATA(MAP,REG,RTX,AGE) \
|
||||
{ \
|
||||
struct const_equiv_data *p; \
|
||||
MAYBE_EXTEND_CONST_EQUIV_VARRAY ((MAP), REGNO (REG)); \
|
||||
p = &VARRAY_CONST_EQUIV ((MAP)->const_equiv_varray, REGNO (REG)); \
|
||||
p->rtx = (RTX); \
|
||||
p->age = (AGE); \
|
||||
}
|
||||
|
54
gcc/unroll.c
54
gcc/unroll.c
@ -239,7 +239,6 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
|
||||
char *local_label;
|
||||
char *local_regno;
|
||||
int maxregnum;
|
||||
int new_maxregnum;
|
||||
rtx exit_label = 0;
|
||||
rtx start_label;
|
||||
struct iv_class *bl;
|
||||
@ -684,6 +683,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
|
||||
map = (struct inline_remap *) alloca (sizeof (struct inline_remap));
|
||||
|
||||
map->integrating = 0;
|
||||
map->const_equiv_varray = 0;
|
||||
|
||||
/* Allocate the label map. */
|
||||
|
||||
@ -873,12 +873,9 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
|
||||
|
||||
map->reg_map = (rtx *) alloca (maxregnum * sizeof (rtx));
|
||||
|
||||
map->const_equiv_map = (rtx *) alloca (maxregnum * sizeof (rtx));
|
||||
map->const_age_map = (unsigned *) alloca (maxregnum
|
||||
* sizeof (unsigned));
|
||||
map->const_equiv_map_size = maxregnum;
|
||||
global_const_equiv_map = map->const_equiv_map;
|
||||
global_const_equiv_map_size = maxregnum;
|
||||
VARRAY_CONST_EQUIV_INIT (map->const_equiv_varray, maxregnum,
|
||||
"unroll_loop");
|
||||
global_const_equiv_varray = map->const_equiv_varray;
|
||||
|
||||
init_reg_map (map, maxregnum);
|
||||
|
||||
@ -1045,9 +1042,9 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
|
||||
PREV_INSN (loop_start));
|
||||
|
||||
bzero ((char *) map->insn_map, max_insnno * sizeof (rtx));
|
||||
bzero ((char *) map->const_equiv_map, maxregnum * sizeof (rtx));
|
||||
bzero ((char *) map->const_age_map,
|
||||
maxregnum * sizeof (unsigned));
|
||||
bzero ((char *) &VARRAY_CONST_EQUIV (map->const_equiv_varray, 0),
|
||||
(VARRAY_SIZE (map->const_equiv_varray)
|
||||
* sizeof (struct const_equiv_data)));
|
||||
map->const_age = 0;
|
||||
|
||||
for (j = 0; j < max_labelno; j++)
|
||||
@ -1113,7 +1110,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
|
||||
{
|
||||
if (loop_dump_stream)
|
||||
fprintf (loop_dump_stream, "Unrolling failure: Naive unrolling not being done.\n");
|
||||
return;
|
||||
goto egress;
|
||||
}
|
||||
|
||||
/* At this point, we are guaranteed to unroll the loop. */
|
||||
@ -1149,19 +1146,11 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
|
||||
|
||||
init_reg_map (map, maxregnum);
|
||||
|
||||
/* Space is needed in some of the map for new registers, so new_maxregnum
|
||||
is an (over)estimate of how many registers will exist at the end. */
|
||||
new_maxregnum = maxregnum + (temp * unroll_number * 2);
|
||||
|
||||
/* Must realloc space for the constant maps, because the number of registers
|
||||
may have changed. */
|
||||
|
||||
map->const_equiv_map = (rtx *) alloca (new_maxregnum * sizeof (rtx));
|
||||
map->const_age_map = (unsigned *) alloca (new_maxregnum * sizeof (unsigned));
|
||||
|
||||
map->const_equiv_map_size = new_maxregnum;
|
||||
global_const_equiv_map = map->const_equiv_map;
|
||||
global_const_equiv_map_size = new_maxregnum;
|
||||
if (map->const_equiv_varray == 0)
|
||||
VARRAY_CONST_EQUIV_INIT (map->const_equiv_varray,
|
||||
maxregnum + temp * unroll_number * 2,
|
||||
"unroll_loop");
|
||||
global_const_equiv_varray = map->const_equiv_varray;
|
||||
|
||||
/* Search the list of bivs and givs to find ones which need to be remapped
|
||||
when split, and set their reg_map entry appropriately. */
|
||||
@ -1202,8 +1191,8 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
|
||||
for (i = 0; i < unroll_number; i++)
|
||||
{
|
||||
bzero ((char *) map->insn_map, max_insnno * sizeof (rtx));
|
||||
bzero ((char *) map->const_equiv_map, new_maxregnum * sizeof (rtx));
|
||||
bzero ((char *) map->const_age_map, new_maxregnum * sizeof (unsigned));
|
||||
bzero ((char *) &VARRAY_CONST_EQUIV (map->const_equiv_varray, 0),
|
||||
VARRAY_SIZE (map->const_equiv_varray) * sizeof (struct const_equiv_data));
|
||||
map->const_age = 0;
|
||||
|
||||
for (j = 0; j < max_labelno; j++)
|
||||
@ -1280,6 +1269,10 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
|
||||
not taken. */
|
||||
if (exit_label)
|
||||
emit_label_after (exit_label, loop_end);
|
||||
|
||||
egress:
|
||||
if (map && map->const_equiv_varray)
|
||||
VARRAY_FREE (map->const_equiv_varray);
|
||||
}
|
||||
|
||||
/* Return true if the loop can be safely, and profitably, preconditioned
|
||||
@ -1949,9 +1942,10 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
|
||||
{
|
||||
int regno = REGNO (SET_DEST (pattern));
|
||||
|
||||
if (regno < map->const_equiv_map_size
|
||||
&& map->const_age_map[regno] == map->const_age)
|
||||
map->const_age_map[regno] = -1;
|
||||
if (regno < VARRAY_SIZE (map->const_equiv_varray)
|
||||
&& (VARRAY_CONST_EQUIV (map->const_equiv_varray, regno).age
|
||||
== map->const_age))
|
||||
VARRAY_CONST_EQUIV (map->const_equiv_varray, regno).age = -1;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2106,7 +2100,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
|
||||
|
||||
/* Be lazy and assume CALL_INSNs clobber all hard registers. */
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
map->const_equiv_map[i] = 0;
|
||||
VARRAY_CONST_EQUIV (map->const_equiv_varray, i).rtx = 0;
|
||||
break;
|
||||
|
||||
case CODE_LABEL:
|
||||
|
31
gcc/varray.h
31
gcc/varray.h
@ -30,6 +30,30 @@
|
||||
#include "system.h"
|
||||
#endif
|
||||
|
||||
/* Auxiliary structure used inside the varray structure, used for
|
||||
function integration data. */
|
||||
|
||||
struct const_equiv_data {
|
||||
/* Map pseudo reg number in calling function to equivalent constant. We
|
||||
cannot in general substitute constants into parameter pseudo registers,
|
||||
since some machine descriptions (many RISCs) won't always handle
|
||||
the resulting insns. So if an incoming parameter has a constant
|
||||
equivalent, we record it here, and if the resulting insn is
|
||||
recognizable, we go with it.
|
||||
|
||||
We also use this mechanism to convert references to incoming arguments
|
||||
and stacked variables. copy_rtx_and_substitute will replace the virtual
|
||||
incoming argument and virtual stacked variables registers with new
|
||||
pseudos that contain pointers into the replacement area allocated for
|
||||
this inline instance. These pseudos are then marked as being equivalent
|
||||
to the appropriate address and substituted if valid. */
|
||||
rtx rtx;
|
||||
|
||||
/* Record the valid age for each entry. The entry is invalid if its
|
||||
age is less than const_age. */
|
||||
unsigned age;
|
||||
};
|
||||
|
||||
/* Union of various array types that are used. */
|
||||
typedef union varray_data_tag {
|
||||
char c[1];
|
||||
@ -50,6 +74,7 @@ typedef union varray_data_tag {
|
||||
struct bitmap_head_def *bitmap[1];
|
||||
struct sched_info_tag *sched[1];
|
||||
struct reg_info_def *reg[1];
|
||||
struct const_equiv_data const_equiv[1];
|
||||
} varray_data;
|
||||
|
||||
/* Virtual array of pointers header. */
|
||||
@ -118,6 +143,9 @@ extern varray_type varray_init PROTO ((size_t, size_t, const char *));
|
||||
#define VARRAY_REG_INIT(va, num, name) \
|
||||
va = varray_init (num, sizeof (struct reg_info_def *), name)
|
||||
|
||||
#define VARRAY_CONST_EQUIV_INIT(va, num, name) \
|
||||
va = varray_init (num, sizeof (struct const_equiv_data), name)
|
||||
|
||||
/* Free up memory allocated by the virtual array, but do not free any of the
|
||||
elements involved. */
|
||||
#define VARRAY_FREE(vp) \
|
||||
@ -128,6 +156,8 @@ extern varray_type varray_grow PROTO((varray_type, size_t));
|
||||
|
||||
#define VARRAY_GROW(VA, N) ((VA) = varray_grow (VA, N))
|
||||
|
||||
#define VARRAY_SIZE(VA) ((VA)->num_elements)
|
||||
|
||||
/* Check for VARRAY_xxx macros being in bound, return N for use as an
|
||||
index. */
|
||||
#ifdef ENABLE_CHECKING
|
||||
@ -159,5 +189,6 @@ extern varray_type varray_grow PROTO((varray_type, size_t));
|
||||
#define VARRAY_BITMAP(VA, N) ((VA)->data.bitmap[ VARRAY_CHECK (VA, N) ])
|
||||
#define VARRAY_SCHED(VA, N) ((VA)->data.sched[ VARRAY_CHECK (VA, N) ])
|
||||
#define VARRAY_REG(VA, N) ((VA)->data.reg[ VARRAY_CHECK (VA, N) ])
|
||||
#define VARRAY_CONST_EQUIV(VA, N) ((VA)->data.const_equiv[ VARRAY_CHECK (VA, N) ])
|
||||
|
||||
#endif /* _VARRAY_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user