cse.c (CHEAP_REGNO): Redefine using REGNO_PTR_FRAME_P and HARD_REGISTER_NUM_P.

* cse.c (CHEAP_REGNO): Redefine using REGNO_PTR_FRAME_P and
	HARD_REGISTER_NUM_P.

	* cselib.c (new_cselib_val): Make comment correct and more detailed.
	* flow.c (mark_set_1): Likewise.

	* except.c (duplicate_eh_region_1, duplicate_eh_region_2,
	duplicate_eh_regions): Remove.
	* except.h (duplicate_eh_regions): Remove prototype.
	* integrate.c (get_label_from_map, copy_rtx_and_substitute,
	global_const_equiv_varray): Remove.
	* integrate.h (get_label_from_map, copy_rtx_and_substitute,
	global_const_equiv_varray, set_label_in_map): Remove prototypes,
	extern declaration, and #define.
	(MAYBE_EXTEND_CONST_EQUIV_VARRAY, SET_CONST_EQUIV_DATA): Remove.
	(struct inline_remap): Remove.
	* varray.c (struct element): Remove entry for const_equiv_data.
	* varray.h (struct const_equiv_data): Remove.
	(enum varray_data_enum) <VARRAY_DATA_CONST_EQUIV>: Remove.
	(union varray_data_tag) <const_equiv>: Remove.
	(VARRAY_CONST_EQUIV_INIT, VARRAY_CONST_EQUIV,
	VARRAY_PUSH_CONST_EQUIV, VARRAY_TOP_CONST_EQUIV): Remove.

	* regstack.c (record_label_references): Remove unused function.

	* rtl.def (VALUE): Update comment.
	(LABEL_REF): Remove unused operand 2.
	* rtl.h (struct rtx_def): Update for removed accessor macros.
	(XCADVFLAGS, INSN_DEAD_CODE_P, LINE_NUMBER, CONTAINING_INSN,
	REG_LOOP_TEST_P): Remove.
	(ADDR_DIFF_VEC_FLAGS, CSELIB_VAL_PTR, LABEL_NEXTREF): Add comments.
	* web.c (entry_register): Don't copy REG_LOOP_TEST_P.
	* doc/rtl.texi (INSN_DEAD_CODE_P, REG_LOOP_TEST_P): Remove.

From-SVN: r90580
This commit is contained in:
Steven Bosscher 2004-11-13 14:18:04 +00:00 committed by Steven Bosscher
parent 1136d30e65
commit d67fb775b3
15 changed files with 58 additions and 838 deletions

View File

@ -1,3 +1,39 @@
2004-11-13 Steven Bosscher <stevenb@suse.de>
* cse.c (CHEAP_REGNO): Redefine using REGNO_PTR_FRAME_P and
HARD_REGISTER_NUM_P.
* cselib.c (new_cselib_val): Make comment correct and more detailed.
* flow.c (mark_set_1): Likewise.
* except.c (duplicate_eh_region_1, duplicate_eh_region_2,
duplicate_eh_regions): Remove.
* except.h (duplicate_eh_regions): Remove prototype.
* integrate.c (get_label_from_map, copy_rtx_and_substitute,
global_const_equiv_varray): Remove.
* integrate.h (get_label_from_map, copy_rtx_and_substitute,
global_const_equiv_varray, set_label_in_map): Remove prototypes,
extern declaration, and #define.
(MAYBE_EXTEND_CONST_EQUIV_VARRAY, SET_CONST_EQUIV_DATA): Remove.
(struct inline_remap): Remove.
* varray.c (struct element): Remove entry for const_equiv_data.
* varray.h (struct const_equiv_data): Remove.
(enum varray_data_enum) <VARRAY_DATA_CONST_EQUIV>: Remove.
(union varray_data_tag) <const_equiv>: Remove.
(VARRAY_CONST_EQUIV_INIT, VARRAY_CONST_EQUIV,
VARRAY_PUSH_CONST_EQUIV, VARRAY_TOP_CONST_EQUIV): Remove.
* regstack.c (record_label_references): Remove unused function.
* rtl.def (VALUE): Update comment.
(LABEL_REF): Remove unused operand 2.
* rtl.h (struct rtx_def): Update for removed accessor macros.
(XCADVFLAGS, INSN_DEAD_CODE_P, LINE_NUMBER, CONTAINING_INSN,
REG_LOOP_TEST_P): Remove.
(ADDR_DIFF_VEC_FLAGS, CSELIB_VAL_PTR, LABEL_NEXTREF): Add comments.
* web.c (entry_register): Don't copy REG_LOOP_TEST_P.
* doc/rtl.texi (INSN_DEAD_CODE_P, REG_LOOP_TEST_P): Remove.
2004-11-13 James A. Morrison <phython@gcc.gnu.org>
Eric Botcazou <ebotcazou@libertysurf.fr>

View File

@ -504,11 +504,9 @@ struct table_elt
of 0. Next come pseudos with a cost of one and other hard registers with
a cost of 2. Aside from these special cases, call `rtx_cost'. */
#define CHEAP_REGNO(N) \
((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM \
|| (N) == STACK_POINTER_REGNUM || (N) == ARG_POINTER_REGNUM \
|| ((N) >= FIRST_VIRTUAL_REGISTER && (N) <= LAST_VIRTUAL_REGISTER) \
|| ((N) < FIRST_PSEUDO_REGISTER \
#define CHEAP_REGNO(N) \
(REGNO_PTR_FRAME_P(N) \
|| (HARD_REGISTER_NUM_P (N) \
&& FIXED_REGNO_P (N) && REGNO_REG_CLASS (N) != NO_REGS))
#define COST(X) (REG_P (X) ? 0 : notreg_cost (X, SET))

View File

@ -704,8 +704,11 @@ new_cselib_val (unsigned int value, enum machine_mode mode)
gcc_assert (value);
e->value = value;
/* We use custom method to allocate this RTL construct because it accounts
about 8% of overall memory usage. */
/* We use an alloc pool to allocate this RTL construct because it
accounts for about 8% of the overall memory usage. We know
precisely when we can have VALUE RTXen (when cselib is active)
so we don't need to put them in garbave collected memory.
??? Why should a VALUE be an RTX in the first place? */
e->u.val_rtx = pool_alloc (value_pool);
memset (e->u.val_rtx, 0, RTX_HDR_SIZE);
PUT_CODE (e->u.val_rtx, VALUE);

View File

@ -537,14 +537,6 @@ that the branch is an annulling one. See the discussion under
@code{sequence} below. Stored in the @code{unchanging} field and
printed as @samp{/u}.
@findex INSN_DEAD_CODE_P
@cindex @code{insn} and @samp{/s}
@cindex @code{in_struct}, in @code{insn}
@item INSN_DEAD_CODE_P (@var{x})
In an @code{insn} during the dead-code elimination pass, nonzero if the
insn is dead.
Stored in the @code{in_struct} field and printed as @samp{/s}.
@findex INSN_DELETED_P
@cindex @code{insn} and @samp{/v}
@cindex @code{call_insn} and @samp{/v}
@ -660,14 +652,6 @@ value is going to be returned. (This happens only in a hard
register.) Stored in the @code{integrated} field and printed as
@samp{/i}.
@findex REG_LOOP_TEST_P
@cindex @code{reg} and @samp{/s}
@cindex @code{in_struct}, in @code{reg}
@item REG_LOOP_TEST_P (@var{x})
In @code{reg} expressions, nonzero if this register's entire life is
contained in the exit test code for some loop. Stored in the
@code{in_struct} field and printed as @samp{/s}.
@findex REG_POINTER
@cindex @code{reg} and @samp{/f}
@cindex @code{frame_related}, in @code{reg}

View File

@ -265,9 +265,6 @@ static void remove_fixup_regions (void);
static void remove_unreachable_regions (rtx);
static void convert_from_eh_region_ranges_1 (rtx *, int *, int);
static struct eh_region *duplicate_eh_region_1 (struct eh_region *,
struct inline_remap *);
static void duplicate_eh_region_2 (struct eh_region *, struct eh_region **);
static int ttypes_filter_eq (const void *, const void *);
static hashval_t ttypes_filter_hash (const void *);
static int ehspec_filter_eq (const void *, const void *);
@ -1064,150 +1061,6 @@ current_function_has_exception_handlers (void)
return false;
}
static struct eh_region *
duplicate_eh_region_1 (struct eh_region *o, struct inline_remap *map)
{
struct eh_region *n = ggc_alloc_cleared (sizeof (struct eh_region));
n->region_number = o->region_number + cfun->eh->last_region_number;
n->type = o->type;
switch (n->type)
{
case ERT_CLEANUP:
case ERT_MUST_NOT_THROW:
break;
case ERT_TRY:
if (o->u.try.continue_label)
n->u.try.continue_label
= get_label_from_map (map,
CODE_LABEL_NUMBER (o->u.try.continue_label));
break;
case ERT_CATCH:
n->u.catch.type_list = o->u.catch.type_list;
break;
case ERT_ALLOWED_EXCEPTIONS:
n->u.allowed.type_list = o->u.allowed.type_list;
break;
case ERT_THROW:
n->u.throw.type = o->u.throw.type;
default:
gcc_unreachable ();
}
if (o->label)
n->label = get_label_from_map (map, CODE_LABEL_NUMBER (o->label));
if (o->resume)
{
n->resume = map->insn_map[INSN_UID (o->resume)];
gcc_assert (n->resume);
}
return n;
}
static void
duplicate_eh_region_2 (struct eh_region *o, struct eh_region **n_array)
{
struct eh_region *n = n_array[o->region_number];
switch (n->type)
{
case ERT_TRY:
n->u.try.catch = n_array[o->u.try.catch->region_number];
n->u.try.last_catch = n_array[o->u.try.last_catch->region_number];
break;
case ERT_CATCH:
if (o->u.catch.next_catch)
n->u.catch.next_catch = n_array[o->u.catch.next_catch->region_number];
if (o->u.catch.prev_catch)
n->u.catch.prev_catch = n_array[o->u.catch.prev_catch->region_number];
break;
default:
break;
}
if (o->outer)
n->outer = n_array[o->outer->region_number];
if (o->inner)
n->inner = n_array[o->inner->region_number];
if (o->next_peer)
n->next_peer = n_array[o->next_peer->region_number];
}
int
duplicate_eh_regions (struct function *ifun, struct inline_remap *map)
{
int ifun_last_region_number = ifun->eh->last_region_number;
struct eh_region **n_array, *root, *cur;
int i;
if (ifun_last_region_number == 0)
return 0;
n_array = xcalloc (ifun_last_region_number + 1, sizeof (*n_array));
for (i = 1; i <= ifun_last_region_number; ++i)
{
cur = ifun->eh->region_array[i];
if (!cur || cur->region_number != i)
continue;
n_array[i] = duplicate_eh_region_1 (cur, map);
}
for (i = 1; i <= ifun_last_region_number; ++i)
{
cur = ifun->eh->region_array[i];
if (!cur || cur->region_number != i)
continue;
duplicate_eh_region_2 (cur, n_array);
}
root = n_array[ifun->eh->region_tree->region_number];
cur = cfun->eh->cur_region;
if (cur)
{
struct eh_region *p = cur->inner;
if (p)
{
while (p->next_peer)
p = p->next_peer;
p->next_peer = root;
}
else
cur->inner = root;
for (i = 1; i <= ifun_last_region_number; ++i)
if (n_array[i] && n_array[i]->outer == NULL)
n_array[i]->outer = cur;
}
else
{
struct eh_region *p = cfun->eh->region_tree;
if (p)
{
while (p->next_peer)
p = p->next_peer;
p->next_peer = root;
}
else
cfun->eh->region_tree = root;
}
free (n_array);
i = cfun->eh->last_region_number;
cfun->eh->last_region_number = i + ifun_last_region_number;
return i;
}
static int
t2r_eq (const void *pentry, const void *pdata)

View File

@ -23,8 +23,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
struct function;
struct inline_remap;
/* Per-function EH data. Used only in except.c, but GC and others
manipulate pointers to the opaque type. */
struct eh_status;
@ -83,7 +81,6 @@ extern void expand_eh_return (void);
extern rtx expand_builtin_extend_pointer (tree);
extern rtx get_exception_pointer (struct function *);
extern rtx get_exception_filter (struct function *);
extern int duplicate_eh_regions (struct function *, struct inline_remap *);
extern int check_handled (tree, tree);
extern void sjlj_emit_function_exit_after (rtx);

View File

@ -2634,7 +2634,7 @@ mark_set_1 (struct propagate_block_info *pbi, enum rtx_code code, rtx reg, rtx c
invalidate_mems_from_set (pbi, reg);
/* If the memory reference had embedded side effects (autoincrement
address modes. Then we may need to kill some entries on the
address modes) then we may need to kill some entries on the
memory set list. */
if (insn && MEM_P (reg))
for_each_rtx (&PATTERN (insn), invalidate_mems_from_autoinc, pbi);

View File

@ -64,21 +64,6 @@ typedef struct initial_value_struct GTY(()) {
static void set_block_origin_self (tree);
static void set_block_abstract_flags (tree, int);
/* Returns the Ith entry in the label_map contained in MAP. If the
Ith entry has not yet been set, return a fresh label. This function
performs a lazy initialization of label_map, thereby avoiding huge memory
explosions when the label_map gets very large. */
rtx
get_label_from_map (struct inline_remap *map, int i)
{
rtx x = map->label_map[i];
if (x == NULL_RTX)
x = map->label_map[i] = gen_label_rtx ();
return x;
}
/* Return false if the function FNDECL cannot be inlined on account of its
attributes, true otherwise. */
@ -174,412 +159,7 @@ copy_decl_for_inlining (tree decl, tree from_fn, tree to_fn)
return copy;
}
/* 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. */
varray_type global_const_equiv_varray;
/* Create a new copy of an rtx. Recursively copies the operands of the rtx,
except for those few rtx codes that are sharable.
We always return an rtx that is similar to that incoming rtx, with the
exception of possibly changing a REG to a SUBREG or vice versa. No
rtl is ever emitted.
If FOR_LHS is nonzero, if means we are processing something that will
be the LHS of a SET.
Handle constants that need to be placed in the constant pool by
calling `force_const_mem'. */
rtx
copy_rtx_and_substitute (rtx orig, struct inline_remap *map, int for_lhs)
{
rtx copy, temp;
int i, j;
RTX_CODE code;
enum machine_mode mode;
const char *format_ptr;
int regno;
if (orig == 0)
return 0;
code = GET_CODE (orig);
mode = GET_MODE (orig);
switch (code)
{
case REG:
/* If the stack pointer register shows up, it must be part of
stack-adjustments (*not* because we eliminated the frame pointer!).
Small hard registers are returned as-is. Pseudo-registers
go through their `reg_map'. */
regno = REGNO (orig);
if (regno <= LAST_VIRTUAL_REGISTER)
{
/* Some hard registers are also mapped,
but others are not translated. */
if (map->reg_map[regno] != 0)
return map->reg_map[regno];
/* If this is the virtual frame pointer, make space in current
function's stack frame for the stack frame of the inline function.
Copy the address of this area into a pseudo. Map
virtual_stack_vars_rtx to this pseudo and set up a constant
equivalence for it to be the address. This will substitute the
address into insns where it can be substituted and use the new
pseudo where it can't. */
else if (regno == VIRTUAL_STACK_VARS_REGNUM)
{
rtx loc, seq;
int size
= get_func_frame_size (DECL_STRUCT_FUNCTION (map->fndecl));
#ifdef FRAME_GROWS_DOWNWARD
int alignment
= (DECL_STRUCT_FUNCTION (map->fndecl)->stack_alignment_needed
/ BITS_PER_UNIT);
/* In this case, virtual_stack_vars_rtx points to one byte
higher than the top of the frame area. So make sure we
allocate a big enough chunk to keep the frame pointer
aligned like a real one. */
if (alignment)
size = CEIL_ROUND (size, alignment);
#endif
start_sequence ();
loc = assign_stack_temp (BLKmode, size, 1);
loc = XEXP (loc, 0);
#ifdef FRAME_GROWS_DOWNWARD
/* In this case, virtual_stack_vars_rtx points to one byte
higher than the top of the frame area. So compute the offset
to one byte higher than our substitute frame. */
loc = plus_constant (loc, size);
#endif
map->reg_map[regno] = temp
= force_reg (Pmode, force_operand (loc, NULL_RTX));
#ifdef STACK_BOUNDARY
mark_reg_pointer (map->reg_map[regno], STACK_BOUNDARY);
#endif
SET_CONST_EQUIV_DATA (map, temp, loc, CONST_AGE_PARM);
seq = get_insns ();
end_sequence ();
emit_insn_after (seq, map->insns_at_start);
return temp;
}
else if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
{
/* Do the same for a block to contain any arguments referenced
in memory. */
rtx loc, seq;
int size = DECL_STRUCT_FUNCTION (map->fndecl)->args_size;
start_sequence ();
loc = assign_stack_temp (BLKmode, size, 1);
loc = XEXP (loc, 0);
/* When arguments grow downward, the virtual incoming
args pointer points to the top of the argument block,
so the remapped location better do the same. */
#ifdef ARGS_GROW_DOWNWARD
loc = plus_constant (loc, size);
#endif
map->reg_map[regno] = temp
= force_reg (Pmode, force_operand (loc, NULL_RTX));
#ifdef STACK_BOUNDARY
mark_reg_pointer (map->reg_map[regno], STACK_BOUNDARY);
#endif
SET_CONST_EQUIV_DATA (map, temp, loc, CONST_AGE_PARM);
seq = get_insns ();
end_sequence ();
emit_insn_after (seq, map->insns_at_start);
return temp;
}
else
return orig;
abort ();
}
if (map->reg_map[regno] == NULL)
{
map->reg_map[regno] = gen_reg_rtx (mode);
REG_USERVAR_P (map->reg_map[regno]) = REG_USERVAR_P (orig);
REG_LOOP_TEST_P (map->reg_map[regno]) = REG_LOOP_TEST_P (orig);
/* A reg with REG_FUNCTION_VALUE_P true will never reach here. */
if (REG_POINTER (map->x_regno_reg_rtx[regno]))
mark_reg_pointer (map->reg_map[regno],
map->regno_pointer_align[regno]);
}
return map->reg_map[regno];
case SUBREG:
copy = copy_rtx_and_substitute (SUBREG_REG (orig), map, for_lhs);
return simplify_gen_subreg (GET_MODE (orig), copy,
GET_MODE (SUBREG_REG (orig)),
SUBREG_BYTE (orig));
case USE:
case CLOBBER:
/* USE and CLOBBER are ordinary, but we convert (use (subreg foo))
to (use foo) if the original insn didn't have a subreg.
Removing the subreg distorts the VAX movmemhi pattern
by changing the mode of an operand. */
copy = copy_rtx_and_substitute (XEXP (orig, 0), map, code == CLOBBER);
if (GET_CODE (copy) == SUBREG && GET_CODE (XEXP (orig, 0)) != SUBREG)
copy = SUBREG_REG (copy);
return gen_rtx_fmt_e (code, VOIDmode, copy);
/* We need to handle "deleted" labels that appear in the DECL_RTL
of a LABEL_DECL. */
case NOTE:
if (NOTE_LINE_NUMBER (orig) != NOTE_INSN_DELETED_LABEL)
break;
/* Fall through. */
case CODE_LABEL:
LABEL_PRESERVE_P (get_label_from_map (map, CODE_LABEL_NUMBER (orig)))
= LABEL_PRESERVE_P (orig);
return get_label_from_map (map, CODE_LABEL_NUMBER (orig));
case LABEL_REF:
copy
= gen_rtx_LABEL_REF
(mode,
LABEL_REF_NONLOCAL_P (orig) ? XEXP (orig, 0)
: get_label_from_map (map, CODE_LABEL_NUMBER (XEXP (orig, 0))));
LABEL_OUTSIDE_LOOP_P (copy) = LABEL_OUTSIDE_LOOP_P (orig);
/* The fact that this label was previously nonlocal does not mean
it still is, so we must check if it is within the range of
this function's labels. */
LABEL_REF_NONLOCAL_P (copy)
= (LABEL_REF_NONLOCAL_P (orig)
&& ! (CODE_LABEL_NUMBER (XEXP (copy, 0)) >= get_first_label_num ()
&& CODE_LABEL_NUMBER (XEXP (copy, 0)) < max_label_num ()));
return copy;
case PC:
case CC0:
case CONST_INT:
case CONST_VECTOR:
return orig;
case SYMBOL_REF:
/* Symbols which represent the address of a label stored in the constant
pool must be modified to point to a constant pool entry for the
remapped label. Otherwise, symbols are returned unchanged. */
if (CONSTANT_POOL_ADDRESS_P (orig))
{
struct function *f = cfun;
rtx constant = get_pool_constant_for_function (f, orig);
if (GET_CODE (constant) == LABEL_REF)
return XEXP (force_const_mem
(GET_MODE (orig),
copy_rtx_and_substitute (constant, map, for_lhs)),
0);
}
return orig;
case CONST_DOUBLE:
/* We have to make a new copy of this CONST_DOUBLE because don't want
to use the old value of CONST_DOUBLE_MEM. Also, this may be a
duplicate of a CONST_DOUBLE we have already seen. */
if (GET_MODE_CLASS (GET_MODE (orig)) == MODE_FLOAT)
{
REAL_VALUE_TYPE d;
REAL_VALUE_FROM_CONST_DOUBLE (d, orig);
return CONST_DOUBLE_FROM_REAL_VALUE (d, GET_MODE (orig));
}
else
return immed_double_const (CONST_DOUBLE_LOW (orig),
CONST_DOUBLE_HIGH (orig), VOIDmode);
case CONST:
break;
case ASM_OPERANDS:
/* If a single asm insn contains multiple output operands then
it contains multiple ASM_OPERANDS rtx's that share the input
and constraint vecs. We must make sure that the copied insn
continues to share it. */
if (map->orig_asm_operands_vector == ASM_OPERANDS_INPUT_VEC (orig))
{
copy = rtx_alloc (ASM_OPERANDS);
RTX_FLAG (copy, volatil) = RTX_FLAG (orig, volatil);
PUT_MODE (copy, GET_MODE (orig));
ASM_OPERANDS_TEMPLATE (copy) = ASM_OPERANDS_TEMPLATE (orig);
ASM_OPERANDS_OUTPUT_CONSTRAINT (copy)
= ASM_OPERANDS_OUTPUT_CONSTRAINT (orig);
ASM_OPERANDS_OUTPUT_IDX (copy) = ASM_OPERANDS_OUTPUT_IDX (orig);
ASM_OPERANDS_INPUT_VEC (copy) = map->copy_asm_operands_vector;
ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy)
= map->copy_asm_constraints_vector;
#ifdef USE_MAPPED_LOCATION
ASM_OPERANDS_SOURCE_LOCATION (copy)
= ASM_OPERANDS_SOURCE_LOCATION (orig);
#else
ASM_OPERANDS_SOURCE_FILE (copy) = ASM_OPERANDS_SOURCE_FILE (orig);
ASM_OPERANDS_SOURCE_LINE (copy) = ASM_OPERANDS_SOURCE_LINE (orig);
#endif
return copy;
}
break;
case CALL:
/* This is given special treatment because the first
operand of a CALL is a (MEM ...) which may get
forced into a register for cse. This is undesirable
if function-address cse isn't wanted or if we won't do cse. */
#ifndef NO_FUNCTION_CSE
if (! (optimize && ! flag_no_function_cse))
#endif
{
rtx copy
= gen_rtx_MEM (GET_MODE (XEXP (orig, 0)),
copy_rtx_and_substitute (XEXP (XEXP (orig, 0), 0),
map, 0));
MEM_COPY_ATTRIBUTES (copy, XEXP (orig, 0));
return
gen_rtx_CALL (GET_MODE (orig), copy,
copy_rtx_and_substitute (XEXP (orig, 1), map, 0));
}
break;
#if 0
/* Must be ifdefed out for loop unrolling to work. */
/* ??? Is this for the old or the new unroller? */
case RETURN:
abort ();
#endif
case SET:
/* If this is setting fp or ap, it means that we have a nonlocal goto.
Adjust the setting by the offset of the area we made.
If the nonlocal goto is into the current function,
this will result in unnecessarily bad code, but should work. */
if (SET_DEST (orig) == virtual_stack_vars_rtx
|| SET_DEST (orig) == virtual_incoming_args_rtx)
{
/* In case a translation hasn't occurred already, make one now. */
rtx equiv_reg;
rtx equiv_loc;
HOST_WIDE_INT loc_offset;
copy_rtx_and_substitute (SET_DEST (orig), map, for_lhs);
equiv_reg = map->reg_map[REGNO (SET_DEST (orig))];
equiv_loc = VARRAY_CONST_EQUIV (map->const_equiv_varray,
REGNO (equiv_reg)).rtx;
loc_offset
= REG_P (equiv_loc) ? 0 : INTVAL (XEXP (equiv_loc, 1));
return gen_rtx_SET (VOIDmode, SET_DEST (orig),
force_operand
(plus_constant
(copy_rtx_and_substitute (SET_SRC (orig),
map, 0),
- loc_offset),
NULL_RTX));
}
else
return gen_rtx_SET (VOIDmode,
copy_rtx_and_substitute (SET_DEST (orig), map, 1),
copy_rtx_and_substitute (SET_SRC (orig), map, 0));
break;
case MEM:
copy = gen_rtx_MEM (mode, copy_rtx_and_substitute (XEXP (orig, 0),
map, 0));
MEM_COPY_ATTRIBUTES (copy, orig);
return copy;
default:
break;
}
copy = rtx_alloc (code);
PUT_MODE (copy, mode);
RTX_FLAG (copy, in_struct) = RTX_FLAG (orig, in_struct);
RTX_FLAG (copy, volatil) = RTX_FLAG (orig, volatil);
RTX_FLAG (copy, unchanging) = RTX_FLAG (orig, unchanging);
format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
{
switch (*format_ptr++)
{
case '0':
X0ANY (copy, i) = X0ANY (orig, i);
break;
case 'e':
XEXP (copy, i)
= copy_rtx_and_substitute (XEXP (orig, i), map, for_lhs);
break;
case 'u':
/* Change any references to old-insns to point to the
corresponding copied insns. */
XEXP (copy, i) = map->insn_map[INSN_UID (XEXP (orig, i))];
break;
case 'E':
XVEC (copy, i) = XVEC (orig, i);
if (XVEC (orig, i) != NULL && XVECLEN (orig, i) != 0)
{
XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
for (j = 0; j < XVECLEN (copy, i); j++)
XVECEXP (copy, i, j)
= copy_rtx_and_substitute (XVECEXP (orig, i, j),
map, for_lhs);
}
break;
case 'w':
XWINT (copy, i) = XWINT (orig, i);
break;
case 'i':
XINT (copy, i) = XINT (orig, i);
break;
case 's':
XSTR (copy, i) = XSTR (orig, i);
break;
case 't':
XTREE (copy, i) = XTREE (orig, i);
break;
default:
abort ();
}
}
if (code == ASM_OPERANDS && map->orig_asm_operands_vector == 0)
{
map->orig_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (orig);
map->copy_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (copy);
map->copy_asm_constraints_vector
= ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy);
}
return copy;
}
/* Given a pointer to some BLOCK node, if the BLOCK_ABSTRACT_ORIGIN for the
given BLOCK node is NULL, set the BLOCK_ABSTRACT_ORIGIN for the node so

View File

@ -21,100 +21,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#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.
This structure is also used when unrolling loops and otherwise
replicating code, although not all fields are needed in this case;
only those fields needed by copy_rtx_and_substitute() and its children
are used.
This structure is used instead of static variables because
expand_inline_function may be called recursively via expand_expr. */
struct inline_remap
{
/* Definition of function be inlined. */
tree fndecl;
/* Place to put insns needed at start of function. */
rtx insns_at_start;
/* Mapping from old registers to new registers.
It is allocated and deallocated in `expand_inline_function' */
rtx *reg_map;
/* Mapping from old code-labels to new code-labels.
The first element of this map is label_map[min_labelno]. */
rtx *label_map;
/* Mapping from old insn uid's to copied insns. The first element
of this map is insn_map[min_insnno]; the last element is
insn_map[max_insnno]. We keep the bounds here for when the map
only covers a partial range of insns (such as loop unrolling or
code replication). */
rtx *insn_map;
int min_insnno, max_insnno;
/* 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. */
varray_type const_equiv_varray;
/* This is incremented for each new basic block.
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;
/* When an insn is being copied by copy_rtx_and_substitute,
this is nonzero if we have copied an ASM_OPERANDS.
In that case, it is the original input-operand vector. */
rtvec orig_asm_operands_vector;
/* When an insn is being copied by copy_rtx_and_substitute,
this is nonzero if we have copied an ASM_OPERANDS.
In that case, it is the copied input-operand vector. */
rtvec copy_asm_operands_vector;
/* Likewise, this is the copied constraints vector. */
rtvec copy_asm_constraints_vector;
/* Indications for regs being pointers and their alignment. */
unsigned char *regno_pointer_align;
rtx *x_regno_reg_rtx;
/* The next few fields are used for subst_constants to record the SETs
that it saw. */
int num_sets;
struct equiv_table
{
rtx dest;
rtx equiv;
} equiv_sets[MAX_RECOG_OPERANDS];
/* Record the last thing assigned to pc. This is used for folded
conditional branch insns. */
rtx last_pc_value;
#ifdef HAVE_cc0
/* Record the last thing assigned to cc0. */
rtx last_cc0_value;
#endif
/* Note mode of COMPARE if the mode would be otherwise lost (comparing of
two VOIDmode constants. */
rtx compare_src;
enum machine_mode compare_mode;
};
/* Return a copy of an rtx (as needed), substituting pseudo-register,
labels, and frame-pointer offsets as necessary. */
extern rtx copy_rtx_and_substitute (rtx, struct inline_remap *, int);
/* Return a pseudo that corresponds to the value in the specified hard
reg as of the start of the function (for inlined functions, the
value at the start of the parent function). */
@ -142,35 +48,3 @@ extern tree copy_decl_for_inlining (tree, tree, tree);
true otherwise. */
extern bool function_attribute_inlinable_p (tree);
/* Return the label indicated. */
extern rtx get_label_from_map (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 varray for
communication with a function called from note_stores. Be *very*
careful that this is used properly in the presence of recursion. */
extern varray_type global_const_equiv_varray;
#define MAYBE_EXTEND_CONST_EQUIV_VARRAY(MAP,MAX) \
{ \
if ((size_t)(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); \
}

View File

@ -265,7 +265,6 @@ static int convert_regs_2 (FILE *, basic_block);
static int convert_regs (FILE *);
static void print_stack (FILE *, stack);
static rtx next_flags_user (rtx);
static void record_label_references (rtx, rtx);
static bool compensate_edge (edge, FILE *);
/* Return nonzero if any stack register is mentioned somewhere within PAT. */
@ -491,58 +490,7 @@ reg_to_stack (FILE *file)
free_aux_for_blocks ();
return true;
}
/* Check PAT, which is in INSN, for LABEL_REFs. Add INSN to the
label's chain of references, and note which insn contains each
reference. */
static void
record_label_references (rtx insn, rtx pat)
{
enum rtx_code code = GET_CODE (pat);
int i;
const char *fmt;
if (code == LABEL_REF)
{
rtx label = XEXP (pat, 0);
rtx ref;
gcc_assert (LABEL_P (label));
/* If this is an undefined label, LABEL_REFS (label) contains
garbage. */
if (INSN_UID (label) == 0)
return;
/* Don't make a duplicate in the code_label's chain. */
for (ref = LABEL_REFS (label);
ref && ref != label;
ref = LABEL_NEXTREF (ref))
if (CONTAINING_INSN (ref) == insn)
return;
CONTAINING_INSN (pat) = insn;
LABEL_NEXTREF (pat) = LABEL_REFS (label);
LABEL_REFS (label) = pat;
return;
}
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
record_label_references (insn, XEXP (pat, i));
if (fmt[i] == 'E')
{
int j;
for (j = 0; j < XVECLEN (pat, i); j++)
record_label_references (insn, XVECEXP (pat, i, j));
}
}
}
/* Return a pointer to the REG expression within PAT. If PAT is not a
REG, possible enclosed by a conversion rtx, return the inner part of

View File

@ -331,7 +331,9 @@ DEF_RTL_EXPR(CONST, "const", "e", RTX_CONST_OBJ)
by a SET whose first operand is (PC). */
DEF_RTL_EXPR(PC, "pc", "", RTX_OBJ)
/* Used in the cselib routines to describe a value. */
/* Used in the cselib routines to describe a value. Objects of this
kind are only allocated in cselib.c, in an alloc pool instead of
in GC memory. The only operand of a VALUE is a cselib_val_struct. */
DEF_RTL_EXPR(VALUE, "value", "0", RTX_OBJ)
/* A register. The "operand" is the register number, accessed with
@ -387,9 +389,8 @@ DEF_RTL_EXPR(MEM, "mem", "e0", RTX_OBJ)
/* Reference to an assembler label in the code for this function.
The operand is a CODE_LABEL found in the insn chain.
The unprinted fields 1 and 2 are used in flow.c for the
LABEL_NEXTREF and CONTAINING_INSN. */
DEF_RTL_EXPR(LABEL_REF, "label_ref", "u00", RTX_CONST_OBJ)
The unprinted field 1 is used in flow.c for the LABEL_NEXTREF. */
DEF_RTL_EXPR(LABEL_REF, "label_ref", "u0", RTX_CONST_OBJ)
/* Reference to a named label:
Operand 0: label name

View File

@ -220,16 +220,11 @@ struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"),
promoted mode.
1 in a CODE_LABEL if the label is used for nonlocal gotos
and must not be deleted even if its count is zero.
1 in a LABEL_REF if this is a reference to a label outside the
current loop.
1 in an INSN, JUMP_INSN or CALL_INSN if this insn must be scheduled
together with the preceding insn. Valid only within sched.
1 in an INSN, JUMP_INSN, or CALL_INSN if insn is in a delay slot and
from the target of a branch. Valid from reorg until end of compilation;
cleared before used.
1 in an INSN, JUMP_INSN or CALL_INSN or related rtx if this insn is
dead code. Valid only during dead-code elimination phase; cleared
before use. */
cleared before used. */
unsigned int in_struct : 1;
/* At the end of RTL generation, 1 if this rtx is used. This is used for
copying shared structure. See `unshare_all_rtl'.
@ -642,7 +637,6 @@ do { \
#define XCBITMAP(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_bit)
#define XCTREE(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_tree)
#define XCBBDEF(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_bb)
#define XCADVFLAGS(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_addr_diff_vec_flags)
#define XCCSELIB(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_cselib)
#define XCVECEXP(RTX, N, M, C) RTVEC_ELT (XCVEC (RTX, N, C), M)
@ -698,11 +692,6 @@ do { \
#define INSN_ANNULLED_BRANCH_P(RTX) \
(RTL_FLAG_CHECK3("INSN_ANNULLED_BRANCH_P", (RTX), JUMP_INSN, CALL_INSN, INSN)->unchanging)
/* 1 if RTX is an insn that is dead code. Valid only for dead-code
elimination phase. */
#define INSN_DEAD_CODE_P(RTX) \
(RTL_FLAG_CHECK3("INSN_DEAD_CODE_P", (RTX), INSN, CALL_INSN, JUMP_INSN)->in_struct)
/* 1 if RTX is an insn in a delay slot and is from the target of the branch.
If the branch insn has INSN_ANNULLED_BRANCH_P set, this insn should only be
executed if the branch is taken. For annulled branches with this bit
@ -710,8 +699,12 @@ do { \
#define INSN_FROM_TARGET_P(RTX) \
(RTL_FLAG_CHECK3("INSN_FROM_TARGET_P", (RTX), INSN, JUMP_INSN, CALL_INSN)->in_struct)
/* In an ADDR_DIFF_VEC, the flags for RTX for use by branch shortening.
See the comments for ADDR_DIFF_VEC in rtl.def. */
#define ADDR_DIFF_VEC_FLAGS(RTX) X0ADVFLAGS(RTX, 4)
/* In a VALUE, the value cselib has assigned to RTX.
This is a "struct cselib_val_struct", see cselib.h. */
#define CSELIB_VAL_PTR(RTX) X0CSELIB(RTX, 0)
/* Holds a list of notes on what this insn does to various REGs.
@ -719,7 +712,6 @@ do { \
chain pointer and the first operand is the REG being described.
The mode field of the EXPR_LIST contains not a real machine mode
but a value from enum reg_note. */
#define REG_NOTES(INSN) XEXP(INSN, 8)
enum reg_note
@ -757,8 +749,6 @@ extern const char * const reg_note_name[];
Label numbers are unique in a compilation. */
#define CODE_LABEL_NUMBER(INSN) XINT (INSN, 6)
#define LINE_NUMBER NOTE
/* In a NOTE that is a line number, this is a string for the file name that the
line is in. We use the same field to record block numbers temporarily in
NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes. (We avoid lots of casts
@ -908,15 +898,11 @@ enum label_kind
/* This is the field in the LABEL_REF through which the circular chain
of references to a particular label is linked.
This chain is set up in flow.c. */
FIXME: This chain is used in loop.c and in the SH backend.
Since loop.c is about to go away, it could be a win to replace
the uses of this in the SH backend with something else. */
#define LABEL_NEXTREF(REF) XCEXP (REF, 1, LABEL_REF)
/* Once basic blocks are found in flow.c,
Each LABEL_REF points to its containing instruction with this field. */
#define CONTAINING_INSN(RTX) XCEXP (RTX, 2, LABEL_REF)
/* For a REG rtx, REGNO extracts the register number. ORIGINAL_REGNO holds
the number the register originally had; for a pseudo register turned into
a hard reg this will hold the old pseudo register number. */
@ -948,7 +934,6 @@ enum label_kind
#define HARD_REGISTER_NUM_P(REG_NO) ((REG_NO) < FIRST_PSEUDO_REGISTER)
/* For a CONST_INT rtx, INTVAL extracts the integer. */
#define INTVAL(RTX) XCWINT(RTX, 0, CONST_INT)
/* For a CONST_DOUBLE:
@ -1162,10 +1147,6 @@ do { \
#define LABEL_PRESERVE_P(RTX) \
(RTL_FLAG_CHECK2("LABEL_PRESERVE_P", (RTX), CODE_LABEL, NOTE)->in_struct)
/* 1 if RTX is a reg that is used only in an exit test of a loop. */
#define REG_LOOP_TEST_P(RTX) \
(RTL_FLAG_CHECK1("REG_LOOP_TEST_P", (RTX), REG)->in_struct)
/* During sched, 1 if RTX is an insn that must be scheduled together
with the preceding insn. */
#define SCHED_GROUP_P(RTX) \

View File

@ -113,7 +113,6 @@ static const struct {
{ sizeof (union tree_node *), 1 },
{ sizeof (struct bitmap_head_def *), 1 },
{ sizeof (struct reg_info_def *), 0 },
{ sizeof (struct const_equiv_data), 0 },
{ sizeof (struct basic_block_def *), 1 },
{ sizeof (struct elt_list *), 1 },
{ sizeof (struct edge_def *), 1 },

View File

@ -33,30 +33,6 @@
#include "tm.h"
#endif
/* Auxiliary structure used inside the varray structure, used for
function integration data. */
struct const_equiv_data GTY(()) {
/* 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;
};
/* Enum indicating what the varray contains.
If this is changed, `element' in varray.c needs to be updated. */
@ -79,7 +55,6 @@ enum varray_data_enum {
VARRAY_DATA_TREE,
VARRAY_DATA_BITMAP,
VARRAY_DATA_REG,
VARRAY_DATA_CONST_EQUIV,
VARRAY_DATA_BB,
VARRAY_DATA_TE,
VARRAY_DATA_EDGE,
@ -125,8 +100,6 @@ typedef union varray_data_tag GTY (()) {
tag ("VARRAY_DATA_BITMAP"))) bitmap[1];
struct reg_info_def *GTY ((length ("%0.num_elements"), skip,
tag ("VARRAY_DATA_REG"))) reg[1];
struct const_equiv_data GTY ((length ("%0.num_elements"),
tag ("VARRAY_DATA_CONST_EQUIV"))) const_equiv[1];
struct basic_block_def *GTY ((length ("%0.num_elements"), skip,
tag ("VARRAY_DATA_BB"))) bb[1];
struct elt_list *GTY ((length ("%0.num_elements"),
@ -207,9 +180,6 @@ extern varray_type varray_init (size_t, enum varray_data_enum, const char *);
#define VARRAY_REG_INIT(va, num, name) \
va = varray_init (num, VARRAY_DATA_REG, name)
#define VARRAY_CONST_EQUIV_INIT(va, num, name) \
va = varray_init (num, VARRAY_DATA_CONST_EQUIV, name)
#define VARRAY_BB_INIT(va, num, name) \
va = varray_init (num, VARRAY_DATA_BB, name)
@ -298,7 +268,6 @@ extern void varray_underflow (varray_type, const char *, int, const char *)
#define VARRAY_TREE(VA, N) VARRAY_CHECK (VA, N, tree)
#define VARRAY_BITMAP(VA, N) VARRAY_CHECK (VA, N, bitmap)
#define VARRAY_REG(VA, N) VARRAY_CHECK (VA, N, reg)
#define VARRAY_CONST_EQUIV(VA, N) VARRAY_CHECK (VA, N, const_equiv)
#define VARRAY_BB(VA, N) VARRAY_CHECK (VA, N, bb)
#define VARRAY_ELT_LIST(VA, N) VARRAY_CHECK (VA, N, te)
#define VARRAY_EDGE(VA, N) VARRAY_CHECK (VA, N, e)
@ -323,7 +292,6 @@ extern void varray_underflow (varray_type, const char *, int, const char *)
#define VARRAY_PUSH_TREE(VA, X) VARRAY_PUSH (VA, tree, X)
#define VARRAY_PUSH_BITMAP(VA, X) VARRAY_PUSH (VA, bitmap, X)
#define VARRAY_PUSH_REG(VA, X) VARRAY_PUSH (VA, reg, X)
#define VARRAY_PUSH_CONST_EQUIV(VA, X) VARRAY_PUSH (VA, const_equiv, X)
#define VARRAY_PUSH_BB(VA, X) VARRAY_PUSH (VA, bb, X)
#define VARRAY_PUSH_EDGE(VA, X) VARRAY_PUSH (VA, e, X)
#define VARRAY_PUSH_TREE_PTR(VA, X) VARRAY_PUSH (VA, tp, X)
@ -349,7 +317,6 @@ extern void varray_underflow (varray_type, const char *, int, const char *)
#define VARRAY_TOP_TREE(VA) VARRAY_TOP (VA, tree)
#define VARRAY_TOP_BITMAP(VA) VARRAY_TOP (VA, bitmap)
#define VARRAY_TOP_REG(VA) VARRAY_TOP (VA, reg)
#define VARRAY_TOP_CONST_EQUIV(VA) VARRAY_TOP (VA, const_equiv)
#define VARRAY_TOP_BB(VA) VARRAY_TOP (VA, bb)
#define VARRAY_TOP_EDGE(VA) VARRAY_TOP (VA, e)
#define VARRAY_TOP_TREE_PTR(VA) VARRAY_TOP (VA, tp)

View File

@ -201,7 +201,6 @@ entry_register (struct web_entry *entry, struct ref *ref, char *used)
newreg = gen_reg_rtx (GET_MODE (reg));
REG_USERVAR_P (newreg) = REG_USERVAR_P (reg);
REG_POINTER (newreg) = REG_POINTER (reg);
REG_LOOP_TEST_P (newreg) = REG_LOOP_TEST_P (reg);
REG_ATTRS (newreg) = REG_ATTRS (reg);
if (dump_file)
fprintf (dump_file, "Web oldreg=%i newreg=%i\n", REGNO (reg),