Commit 2a9772e3 by Kazu Hirata Committed by Kazu Hirata

integrate.c (try_constants, [...]): Remove.

	* integrate.c (try_constants, subst_constants, mark_stores):
	Remove.
	* integrate.h: Remove the prototype for try_constants.

From-SVN: r88787
parent 6dcc04b0
2004-10-08 Kazu Hirata <kazu@cs.umass.edu>
* integrate.c (try_constants, subst_constants, mark_stores):
Remove.
* integrate.h: Remove the prototype for try_constants.
2004-10-08 Joseph S. Myers <jsm@polyomino.org.uk> 2004-10-08 Joseph S. Myers <jsm@polyomino.org.uk>
* c-typeck.c (enum impl_conv): Add ic_argpass_nonproto. * c-typeck.c (enum impl_conv): Add ic_argpass_nonproto.
......
...@@ -61,10 +61,8 @@ typedef struct initial_value_struct GTY(()) { ...@@ -61,10 +61,8 @@ typedef struct initial_value_struct GTY(()) {
initial_value_pair * GTY ((length ("%h.num_entries"))) entries; initial_value_pair * GTY ((length ("%h.num_entries"))) entries;
} initial_value_struct; } initial_value_struct;
static void subst_constants (rtx *, rtx, struct inline_remap *, int);
static void set_block_origin_self (tree); static void set_block_origin_self (tree);
static void set_block_abstract_flags (tree, int); static void set_block_abstract_flags (tree, int);
static void mark_stores (rtx, rtx, void *);
/* Returns the Ith entry in the label_map contained in MAP. If the /* 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 Ith entry has not yet been set, return a fresh label. This function
...@@ -583,443 +581,6 @@ copy_rtx_and_substitute (rtx orig, struct inline_remap *map, int for_lhs) ...@@ -583,443 +581,6 @@ copy_rtx_and_substitute (rtx orig, struct inline_remap *map, int for_lhs)
return copy; return copy;
} }
/* Substitute known constant values into INSN, if that is valid. */
void
try_constants (rtx insn, struct inline_remap *map)
{
int i;
map->num_sets = 0;
/* First try just updating addresses, then other things. This is
important when we have something like the store of a constant
into memory and we can update the memory address but the machine
does not support a constant source. */
subst_constants (&PATTERN (insn), insn, map, 1);
apply_change_group ();
subst_constants (&PATTERN (insn), insn, map, 0);
apply_change_group ();
/* Enforce consistency between the addresses in the regular insn flow
and the ones in CALL_INSN_FUNCTION_USAGE lists, if any. */
if (CALL_P (insn) && CALL_INSN_FUNCTION_USAGE (insn))
{
subst_constants (&CALL_INSN_FUNCTION_USAGE (insn), insn, map, 1);
apply_change_group ();
}
/* Show we don't know the value of anything stored or clobbered. */
note_stores (PATTERN (insn), mark_stores, NULL);
map->last_pc_value = 0;
#ifdef HAVE_cc0
map->last_cc0_value = 0;
#endif
/* Set up any constant equivalences made in this insn. */
for (i = 0; i < map->num_sets; i++)
{
if (REG_P (map->equiv_sets[i].dest))
{
int regno = REGNO (map->equiv_sets[i].dest);
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;
#ifdef HAVE_cc0
else if (map->equiv_sets[i].dest == cc0_rtx)
map->last_cc0_value = map->equiv_sets[i].equiv;
#endif
}
}
/* Substitute known constants for pseudo regs in the contents of LOC,
which are part of INSN.
If INSN is zero, the substitution should always be done (this is used to
update DECL_RTL).
These changes are taken out by try_constants if the result is not valid.
Note that we are more concerned with determining when the result of a SET
is a constant, for further propagation, than actually inserting constants
into insns; cse will do the latter task better.
This function is also used to adjust address of items previously addressed
via the virtual stack variable or virtual incoming arguments registers.
If MEMONLY is nonzero, only make changes inside a MEM. */
static void
subst_constants (rtx *loc, rtx insn, struct inline_remap *map, int memonly)
{
rtx x = *loc;
int i, j;
enum rtx_code code;
const char *format_ptr;
int num_changes = num_validated_changes ();
rtx new = 0;
enum machine_mode op0_mode = MAX_MACHINE_MODE;
code = GET_CODE (x);
switch (code)
{
case PC:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case CONST:
case LABEL_REF:
case ADDRESS:
return;
#ifdef HAVE_cc0
case CC0:
if (! memonly)
validate_change (insn, loc, map->last_cc0_value, 1);
return;
#endif
case USE:
case CLOBBER:
/* The only thing we can do with a USE or CLOBBER is possibly do
some substitutions in a MEM within it. */
if (MEM_P (XEXP (x, 0)))
subst_constants (&XEXP (XEXP (x, 0), 0), insn, map, 0);
return;
case REG:
/* Substitute for parms and known constants. Don't replace
hard regs used as user variables with constants. */
if (! memonly)
{
int regno = REGNO (x);
struct const_equiv_data *p;
if (! (regno < FIRST_PSEUDO_REGISTER && REG_USERVAR_P (x))
&& (size_t) 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;
case SUBREG:
/* SUBREG applied to something other than a reg
should be treated as ordinary, since that must
be a special hack and we don't know how to treat it specially.
Consider for example mulsidi3 in m68k.md.
Ordinary SUBREG of a REG needs this special treatment. */
if (! memonly && REG_P (SUBREG_REG (x)))
{
rtx inner = SUBREG_REG (x);
rtx new = 0;
/* We can't call subst_constants on &SUBREG_REG (x) because any
constant or SUBREG wouldn't be valid inside our SUBEG. Instead,
see what is inside, try to form the new SUBREG and see if that is
valid. We handle two cases: extracting a full word in an
integral mode and extracting the low part. */
subst_constants (&inner, NULL_RTX, map, 0);
new = simplify_gen_subreg (GET_MODE (x), inner,
GET_MODE (SUBREG_REG (x)),
SUBREG_BYTE (x));
if (new)
validate_change (insn, loc, new, 1);
else
cancel_changes (num_changes);
return;
}
break;
case MEM:
subst_constants (&XEXP (x, 0), insn, map, 0);
/* If a memory address got spoiled, change it back. */
if (! memonly && insn != 0 && num_validated_changes () != num_changes
&& ! memory_address_p (GET_MODE (x), XEXP (x, 0)))
cancel_changes (num_changes);
return;
case SET:
{
/* Substitute constants in our source, and in any arguments to a
complex (e..g, ZERO_EXTRACT) destination, but not in the destination
itself. */
rtx *dest_loc = &SET_DEST (x);
rtx dest = *dest_loc;
rtx src, tem;
enum machine_mode compare_mode = VOIDmode;
/* If SET_SRC is a COMPARE which subst_constants would turn into
COMPARE of 2 VOIDmode constants, note the mode in which comparison
is to be done. */
if (GET_CODE (SET_SRC (x)) == COMPARE)
{
src = SET_SRC (x);
if (GET_MODE_CLASS (GET_MODE (src)) == MODE_CC
|| CC0_P (dest))
{
compare_mode = GET_MODE (XEXP (src, 0));
if (compare_mode == VOIDmode)
compare_mode = GET_MODE (XEXP (src, 1));
}
}
subst_constants (&SET_SRC (x), insn, map, memonly);
src = SET_SRC (x);
while (GET_CODE (*dest_loc) == ZERO_EXTRACT
|| GET_CODE (*dest_loc) == SUBREG
|| GET_CODE (*dest_loc) == STRICT_LOW_PART)
{
if (GET_CODE (*dest_loc) == ZERO_EXTRACT)
{
subst_constants (&XEXP (*dest_loc, 1), insn, map, memonly);
subst_constants (&XEXP (*dest_loc, 2), insn, map, memonly);
}
dest_loc = &XEXP (*dest_loc, 0);
}
/* Do substitute in the address of a destination in memory. */
if (MEM_P (*dest_loc))
subst_constants (&XEXP (*dest_loc, 0), insn, map, 0);
/* Check for the case of DEST a SUBREG, both it and the underlying
register are less than one word, and the SUBREG has the wider mode.
In the case, we are really setting the underlying register to the
source converted to the mode of DEST. So indicate that. */
if (GET_CODE (dest) == SUBREG
&& GET_MODE_SIZE (GET_MODE (dest)) <= UNITS_PER_WORD
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) <= UNITS_PER_WORD
&& (GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
<= GET_MODE_SIZE (GET_MODE (dest)))
&& (tem = gen_lowpart_if_possible (GET_MODE (SUBREG_REG (dest)),
src)))
src = tem, dest = SUBREG_REG (dest);
/* If storing a recognizable value save it for later recording. */
if ((map->num_sets < MAX_RECOG_OPERANDS)
&& (CONSTANT_P (src)
|| (REG_P (src)
&& (REGNO (src) == VIRTUAL_INCOMING_ARGS_REGNUM
|| REGNO (src) == VIRTUAL_STACK_VARS_REGNUM))
|| (GET_CODE (src) == PLUS
&& REG_P (XEXP (src, 0))
&& (REGNO (XEXP (src, 0)) == VIRTUAL_INCOMING_ARGS_REGNUM
|| REGNO (XEXP (src, 0)) == VIRTUAL_STACK_VARS_REGNUM)
&& CONSTANT_P (XEXP (src, 1)))
|| GET_CODE (src) == COMPARE
|| CC0_P (dest)
|| (dest == pc_rtx
&& (src == pc_rtx || GET_CODE (src) == RETURN
|| GET_CODE (src) == LABEL_REF))))
{
/* Normally, this copy won't do anything. But, if SRC is a COMPARE
it will cause us to save the COMPARE with any constants
substituted, which is what we want for later. */
rtx src_copy = copy_rtx (src);
map->equiv_sets[map->num_sets].equiv = src_copy;
map->equiv_sets[map->num_sets++].dest = dest;
if (compare_mode != VOIDmode
&& GET_CODE (src) == COMPARE
&& (GET_MODE_CLASS (GET_MODE (src)) == MODE_CC
|| CC0_P (dest))
&& GET_MODE (XEXP (src, 0)) == VOIDmode
&& GET_MODE (XEXP (src, 1)) == VOIDmode)
{
map->compare_src = src_copy;
map->compare_mode = compare_mode;
}
}
}
return;
default:
break;
}
format_ptr = GET_RTX_FORMAT (code);
/* If the first operand is an expression, save its mode for later. */
if (*format_ptr == 'e')
op0_mode = GET_MODE (XEXP (x, 0));
for (i = 0; i < GET_RTX_LENGTH (code); i++)
{
switch (*format_ptr++)
{
case '0':
break;
case 'e':
if (XEXP (x, i))
subst_constants (&XEXP (x, i), insn, map, memonly);
break;
case 'u':
case 'i':
case 's':
case 'w':
case 'n':
case 't':
case 'B':
break;
case 'E':
if (XVEC (x, i) != NULL && XVECLEN (x, i) != 0)
for (j = 0; j < XVECLEN (x, i); j++)
subst_constants (&XVECEXP (x, i, j), insn, map, memonly);
break;
default:
abort ();
}
}
/* If this is a commutative operation, move a constant to the second
operand unless the second operand is already a CONST_INT. */
if (! memonly
&& (GET_RTX_CLASS (code) == RTX_COMM_ARITH
|| GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
&& CONSTANT_P (XEXP (x, 0)) && GET_CODE (XEXP (x, 1)) != CONST_INT)
{
rtx tem = XEXP (x, 0);
validate_change (insn, &XEXP (x, 0), XEXP (x, 1), 1);
validate_change (insn, &XEXP (x, 1), tem, 1);
}
/* Simplify the expression in case we put in some constants. */
if (! memonly)
switch (GET_RTX_CLASS (code))
{
case RTX_UNARY:
if (op0_mode == MAX_MACHINE_MODE)
abort ();
new = simplify_unary_operation (code, GET_MODE (x),
XEXP (x, 0), op0_mode);
break;
case RTX_COMPARE:
case RTX_COMM_COMPARE:
{
enum machine_mode op_mode = GET_MODE (XEXP (x, 0));
if (op_mode == VOIDmode)
op_mode = GET_MODE (XEXP (x, 1));
new = simplify_relational_operation (code, GET_MODE (x), op_mode,
XEXP (x, 0), XEXP (x, 1));
break;
}
case RTX_BIN_ARITH:
case RTX_COMM_ARITH:
new = simplify_binary_operation (code, GET_MODE (x),
XEXP (x, 0), XEXP (x, 1));
break;
case RTX_BITFIELD_OPS:
case RTX_TERNARY:
if (op0_mode == MAX_MACHINE_MODE)
abort ();
if (code == IF_THEN_ELSE)
{
rtx op0 = XEXP (x, 0);
if (COMPARISON_P (op0)
&& GET_MODE (op0) == VOIDmode
&& ! side_effects_p (op0)
&& XEXP (op0, 0) == map->compare_src
&& GET_MODE (XEXP (op0, 1)) == VOIDmode)
{
/* We have compare of two VOIDmode constants for which
we recorded the comparison mode. */
rtx tem =
simplify_gen_relational (GET_CODE (op0), GET_MODE (op0),
map->compare_mode, XEXP (op0, 0),
XEXP (op0, 1));
if (GET_CODE (tem) != CONST_INT)
new = simplify_ternary_operation (code, GET_MODE (x),
op0_mode, tem, XEXP (x, 1),
XEXP (x, 2));
else if (tem == const0_rtx)
new = XEXP (x, 2);
else
new = XEXP (x, 1);
}
}
if (!new)
new = simplify_ternary_operation (code, GET_MODE (x), op0_mode,
XEXP (x, 0), XEXP (x, 1),
XEXP (x, 2));
break;
default:
break;
}
if (new)
validate_change (insn, loc, new, 1);
}
/* Show that register modified no longer contain known constants. We are
called from note_stores with parts of the new insn. */
static void
mark_stores (rtx dest, rtx x ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED)
{
int regno = -1;
enum machine_mode mode = VOIDmode;
/* DEST is always the innermost thing set, except in the case of
SUBREGs of hard registers. */
if (REG_P (dest))
regno = REGNO (dest), mode = GET_MODE (dest);
else if (GET_CODE (dest) == SUBREG && REG_P (SUBREG_REG (dest)))
{
regno = REGNO (SUBREG_REG (dest));
if (regno < FIRST_PSEUDO_REGISTER)
regno += subreg_regno_offset (REGNO (SUBREG_REG (dest)),
GET_MODE (SUBREG_REG (dest)),
SUBREG_BYTE (dest),
GET_MODE (dest));
mode = GET_MODE (SUBREG_REG (dest));
}
if (regno >= 0)
{
unsigned int uregno = regno;
unsigned int last_reg = (uregno >= FIRST_PSEUDO_REGISTER ? uregno
: uregno + hard_regno_nregs[uregno][mode] - 1);
unsigned int i;
/* Ignore virtual stack var or virtual arg register since those
are handled separately. */
if (uregno != VIRTUAL_INCOMING_ARGS_REGNUM
&& uregno != VIRTUAL_STACK_VARS_REGNUM)
for (i = uregno; i <= last_reg; i++)
if ((size_t) i < VARRAY_SIZE (global_const_equiv_varray))
VARRAY_CONST_EQUIV (global_const_equiv_varray, i).rtx = 0;
}
}
/* Given a pointer to some BLOCK node, if the BLOCK_ABSTRACT_ORIGIN for the /* 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 given BLOCK node is NULL, set the BLOCK_ABSTRACT_ORIGIN for the node so
that it points to the node itself, thus indicating that the node is its that it points to the node itself, thus indicating that the node is its
......
...@@ -142,8 +142,6 @@ extern tree copy_decl_for_inlining (tree, tree, tree); ...@@ -142,8 +142,6 @@ extern tree copy_decl_for_inlining (tree, tree, tree);
true otherwise. */ true otherwise. */
extern bool function_attribute_inlinable_p (tree); extern bool function_attribute_inlinable_p (tree);
extern void try_constants (rtx, struct inline_remap *);
/* Return the label indicated. */ /* Return the label indicated. */
extern rtx get_label_from_map (struct inline_remap *, int); extern rtx get_label_from_map (struct inline_remap *, int);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment