enum machine_mode));
static void merge_equiv_classes PROTO((struct table_elt *,
struct table_elt *));
-static void invalidate PROTO((rtx));
+static void invalidate PROTO((rtx, enum machine_mode));
static void remove_invalid_refs PROTO((int));
static void rehash_using_reg PROTO((rtx));
static void invalidate_memory PROTO((struct write_data *));
next_qty = max_reg;
- bzero (reg_tick, max_reg * sizeof (int));
+ bzero ((char *) reg_tick, max_reg * sizeof (int));
- bcopy (all_minus_one, reg_in_table, max_reg * sizeof (int));
- bcopy (consec_ints, reg_qty, max_reg * sizeof (int));
+ bcopy ((char *) all_minus_one, (char *) reg_in_table,
+ max_reg * sizeof (int));
+ bcopy ((char *) consec_ints, (char *) reg_qty, max_reg * sizeof (int));
CLEAR_HARD_REG_SET (hard_regs_in_table);
/* The per-quantity values used to be initialized here, but it is
}
}
- bzero (table, sizeof table);
+ bzero ((char *) table, sizeof table);
prev_insn = 0;
(because, when a memory reference with a varying address is stored in,
all memory references are removed by invalidate_memory
so specific invalidation is superfluous).
+ FULL_MODE, if not VOIDmode, indicates that this much should be invalidated
+ instead of just the amount indicated by the mode of X. This is only used
+ for bitfield stores into memory.
A nonvarying address may be just a register or just
a symbol reference, or it may be either of those plus
a numeric offset. */
static void
-invalidate (x)
+invalidate (x, full_mode)
rtx x;
+ enum machine_mode full_mode;
{
register int i;
register struct table_elt *p;
{
if (GET_CODE (SUBREG_REG (x)) != REG)
abort ();
- invalidate (SUBREG_REG (x));
+ invalidate (SUBREG_REG (x), VOIDmode);
return;
}
if (GET_CODE (x) != MEM)
abort ();
- set_nonvarying_address_components (XEXP (x, 0), GET_MODE_SIZE (GET_MODE (x)),
+ if (full_mode == VOIDmode)
+ full_mode = GET_MODE (x);
+
+ set_nonvarying_address_components (XEXP (x, 0), GET_MODE_SIZE (full_mode),
&base, &start, &end);
for (i = 0; i < NBUCKETS; i++)
if (reg_tick[regno] >= 0)
reg_tick[regno]++;
- in_table |= TEST_HARD_REG_BIT (hard_regs_in_table, regno);
+ in_table |= (TEST_HARD_REG_BIT (hard_regs_in_table, regno) != 0);
}
/* In the case where we have no call-clobbered hard registers in the
case SYMBOL_REF:
hash
- += ((unsigned) SYMBOL_REF << 7) + (unsigned HOST_WIDE_INT) XEXP (x, 0);
+ += ((unsigned) SYMBOL_REF << 7) + (unsigned HOST_WIDE_INT) XSTR (x, 0);
return hash;
case MEM:
return INTVAL (x) == INTVAL (y);
case LABEL_REF:
- case SYMBOL_REF:
return XEXP (x, 0) == XEXP (y, 0);
+ case SYMBOL_REF:
+ return XSTR (x, 0) == XSTR (y, 0);
+
case REG:
{
int regno = REGNO (y);
set PBASE, PSTART, and PEND which correspond to the base of the address,
the starting offset, and ending offset respectively.
- ADDR is known to be a nonvarying address.
+ ADDR is known to be a nonvarying address. */
- cse_address_varies_p returns zero for nonvarying addresses. */
+/* ??? Despite what the comments say, this function is in fact frequently
+ passed varying addresses. This does not appear to cause any problems. */
static void
set_nonvarying_address_components (addr, size, pbase, pstart, pend)
HOST_WIDE_INT *pstart, *pend;
{
rtx base;
- int start, end;
+ HOST_WIDE_INT start, end;
base = addr;
start = 0;
base = qty_const[reg_qty[REGNO (XEXP (base, 0))]];
}
- /* By definition, operand1 of a LO_SUM is the associated constant
- address. Use the associated constant address as the base instead. */
- if (GET_CODE (base) == LO_SUM)
- base = XEXP (base, 1);
+ /* Handle everything that we can find inside an address that has been
+ viewed as constant. */
+
+ while (1)
+ {
+ /* If no part of this switch does a "continue", the code outside
+ will exit this loop. */
+
+ switch (GET_CODE (base))
+ {
+ case LO_SUM:
+ /* By definition, operand1 of a LO_SUM is the associated constant
+ address. Use the associated constant address as the base
+ instead. */
+ base = XEXP (base, 1);
+ continue;
+
+ case CONST:
+ /* Strip off CONST. */
+ base = XEXP (base, 0);
+ continue;
+
+ case PLUS:
+ if (GET_CODE (XEXP (base, 1)) == CONST_INT)
+ {
+ start += INTVAL (XEXP (base, 1));
+ base = XEXP (base, 0);
+ continue;
+ }
+ break;
+
+ case AND:
+ /* Handle the case of an AND which is the negative of a power of
+ two. This is used to represent unaligned memory operations. */
+ if (GET_CODE (XEXP (base, 1)) == CONST_INT
+ && exact_log2 (- INTVAL (XEXP (base, 1))) > 0)
+ {
+ set_nonvarying_address_components (XEXP (base, 0), size,
+ pbase, pstart, pend);
- /* Strip off CONST. */
- if (GET_CODE (base) == CONST)
- base = XEXP (base, 0);
+ /* Assume the worst misalignment. START is affected, but not
+ END, so compensate but adjusting SIZE. Don't lose any
+ constant we already had. */
- if (GET_CODE (base) == PLUS
- && GET_CODE (XEXP (base, 1)) == CONST_INT)
+ size = *pend - *pstart - INTVAL (XEXP (base, 1)) - 1;
+ start += *pstart - INTVAL (XEXP (base, 1)) - 1;
+ base = *pbase;
+ }
+ break;
+ }
+
+ break;
+ }
+
+ if (GET_CODE (base) == CONST_INT)
{
- start += INTVAL (XEXP (base, 1));
- base = XEXP (base, 0);
+ start += INTVAL (base);
+ base = const0_rtx;
}
end = start + size;
register enum rtx_code code;
register char *fmt;
- if (GET_CODE (base) == CONST_INT)
- {
- start += INTVAL (base);
- end += INTVAL (base);
- base = const0_rtx;
- }
-
repeat:
if (x == 0)
return 0;
check the wrong mode (input vs. output) for a conversion operation,
such as FIX. At some point, this should be simplified. */
-#if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
- if (code == FLOAT && GET_CODE (op) == CONST_INT)
- {
- REAL_VALUE_TYPE d;
+#if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
-#ifdef REAL_ARITHMETIC
- REAL_VALUE_FROM_INT (d, INTVAL (op), INTVAL (op) < 0 ? ~0 : 0);
-#else
- d = (double) INTVAL (op);
-#endif
- return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
- }
- else if (code == UNSIGNED_FLOAT && GET_CODE (op) == CONST_INT)
+ if (code == FLOAT && GET_MODE (op) == VOIDmode
+ && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
{
+ HOST_WIDE_INT hv, lv;
REAL_VALUE_TYPE d;
-#ifdef REAL_ARITHMETIC
- REAL_VALUE_FROM_INT (d, INTVAL (op), 0);
-#else
- d = (double) (unsigned int) INTVAL (op);
-#endif
- return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
- }
-
- else if (code == FLOAT && GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode)
- {
- REAL_VALUE_TYPE d;
+ if (GET_CODE (op) == CONST_INT)
+ lv = INTVAL (op), hv = INTVAL (op) < 0 ? -1 : 0;
+ else
+ lv = CONST_DOUBLE_LOW (op), hv = CONST_DOUBLE_HIGH (op);
#ifdef REAL_ARITHMETIC
- REAL_VALUE_FROM_INT (d, CONST_DOUBLE_LOW (op), CONST_DOUBLE_HIGH (op));
+ REAL_VALUE_FROM_INT (d, lv, hv);
#else
- if (CONST_DOUBLE_HIGH (op) < 0)
+ if (hv < 0)
{
- d = (double) (~ CONST_DOUBLE_HIGH (op));
+ d = (double) (~ hv);
d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
* (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
- d += (double) (unsigned HOST_WIDE_INT) (~ CONST_DOUBLE_LOW (op));
+ d += (double) (unsigned HOST_WIDE_INT) (~ lv);
d = (- d - 1.0);
}
else
{
- d = (double) CONST_DOUBLE_HIGH (op);
+ d = (double) hv;
d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
* (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
- d += (double) (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
+ d += (double) (unsigned HOST_WIDE_INT) lv;
}
#endif /* REAL_ARITHMETIC */
+
return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
}
- else if (code == UNSIGNED_FLOAT && GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode)
+ else if (code == UNSIGNED_FLOAT && GET_MODE (op) == VOIDmode
+ && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
{
+ HOST_WIDE_INT hv, lv;
REAL_VALUE_TYPE d;
+ if (GET_CODE (op) == CONST_INT)
+ lv = INTVAL (op), hv = INTVAL (op) < 0 ? -1 : 0;
+ else
+ lv = CONST_DOUBLE_LOW (op), hv = CONST_DOUBLE_HIGH (op);
+
+ if (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT * 2)
+ ;
+ else
+ hv = 0, lv &= GET_MODE_MASK (op_mode);
+
#ifdef REAL_ARITHMETIC
- REAL_VALUE_FROM_UNSIGNED_INT (d, CONST_DOUBLE_LOW (op),
- CONST_DOUBLE_HIGH (op));
+ REAL_VALUE_FROM_UNSIGNED_INT (d, lv, hv);
#else
- d = (double) CONST_DOUBLE_HIGH (op);
+
+ d = (double) (unsigned HOST_WIDE_INT) hv;
d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
* (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
- d += (double) (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
+ d += (double) (unsigned HOST_WIDE_INT) lv;
#endif /* REAL_ARITHMETIC */
+
return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
}
#endif
/* We can do some operations on integer CONST_DOUBLEs. Also allow
for a DImode operation on a CONST_INT. */
- else if (GET_MODE (op) == VOIDmode && width == HOST_BITS_PER_INT * 2
+ else if (GET_MODE (op) == VOIDmode && width <= HOST_BITS_PER_INT * 2
&& (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
{
HOST_WIDE_INT l1, h1, lv, hv;
break;
case TRUNCATE:
- if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
- return GEN_INT (l1 & GET_MODE_MASK (mode));
- else
- return 0;
+ /* This is just a change-of-mode, so do nothing. */
break;
case ZERO_EXTEND:
set_float_handler (NULL_PTR);
return x;
}
- else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE_CLASS (mode) == MODE_INT
+
+ else if (GET_CODE (op) == CONST_DOUBLE
+ && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT
+ && GET_MODE_CLASS (mode) == MODE_INT
&& width <= HOST_BITS_PER_WIDE_INT && width > 0)
{
REAL_VALUE_TYPE d;
return tem;
/* Don't let a relocatable value get a negative coeff. */
- if (GET_CODE (op1) == CONST_INT && GET_MODE (op1) != VOIDmode)
+ if (GET_CODE (op1) == CONST_INT && GET_MODE (op0) != VOIDmode)
return plus_constant (op0, - INTVAL (op1));
break;
int first = 1, negate = 0, changed;
int i, j;
- bzero (ops, sizeof ops);
+ bzero ((char *) ops, sizeof ops);
/* Set up the two operands and then expand them until nothing has been
changed. If we run out of room in our array, give up; this should
if (GET_MODE (table) != Pmode)
new = gen_rtx (TRUNCATE, GET_MODE (table), new);
- return new;
+ /* Indicate this is a constant. This isn't a
+ valid form of CONST, but it will only be used
+ to fold the next insns and then discarded, so
+ it should be safe. */
+ return gen_rtx (CONST, GET_MODE (new), new);
}
}
}
switch (GET_RTX_CLASS (code))
{
case '1':
- /* We can't simplify extension ops unless we know the original mode. */
- if ((code == ZERO_EXTEND || code == SIGN_EXTEND)
- && mode_arg0 == VOIDmode)
- break;
- new = simplify_unary_operation (code, mode,
- const_arg0 ? const_arg0 : folded_arg0,
- mode_arg0);
+ {
+ int is_const = 0;
+
+ /* We can't simplify extension ops unless we know the
+ original mode. */
+ if ((code == ZERO_EXTEND || code == SIGN_EXTEND)
+ && mode_arg0 == VOIDmode)
+ break;
+
+ /* If we had a CONST, strip it off and put it back later if we
+ fold. */
+ if (const_arg0 != 0 && GET_CODE (const_arg0) == CONST)
+ is_const = 1, const_arg0 = XEXP (const_arg0, 0);
+
+ new = simplify_unary_operation (code, mode,
+ const_arg0 ? const_arg0 : folded_arg0,
+ mode_arg0);
+ if (new != 0 && is_const)
+ new = gen_rtx (CONST, mode, new);
+ }
break;
case '<':
ADDR_DIFF_VEC table. */
if (const_arg1 && GET_CODE (const_arg1) == LABEL_REF)
{
- rtx y = lookup_as_function (folded_arg0, MINUS);
+ rtx y
+ = GET_CODE (folded_arg0) == MINUS ? folded_arg0
+ : lookup_as_function (folded_arg0, MINUS);
if (y != 0 && GET_CODE (XEXP (y, 1)) == LABEL_REF
&& XEXP (XEXP (y, 1), 0) == XEXP (const_arg1, 0))
return XEXP (y, 0);
+
+ /* Now try for a CONST of a MINUS like the above. */
+ if ((y = (GET_CODE (folded_arg0) == CONST ? folded_arg0
+ : lookup_as_function (folded_arg0, CONST))) != 0
+ && GET_CODE (XEXP (y, 0)) == MINUS
+ && GET_CODE (XEXP (XEXP (y, 0), 1)) == LABEL_REF
+ && XEXP (XEXP (XEXP (y, 0),1), 0) == XEXP (const_arg1, 0))
+ return XEXP (XEXP (y, 0), 0);
+ }
+
+ /* Likewise if the operands are in the other order. */
+ if (const_arg0 && GET_CODE (const_arg0) == LABEL_REF)
+ {
+ rtx y
+ = GET_CODE (folded_arg1) == MINUS ? folded_arg1
+ : lookup_as_function (folded_arg1, MINUS);
+
+ if (y != 0 && GET_CODE (XEXP (y, 1)) == LABEL_REF
+ && XEXP (XEXP (y, 1), 0) == XEXP (const_arg0, 0))
+ return XEXP (y, 0);
+
+ /* Now try for a CONST of a MINUS like the above. */
+ if ((y = (GET_CODE (folded_arg1) == CONST ? folded_arg1
+ : lookup_as_function (folded_arg1, CONST))) != 0
+ && GET_CODE (XEXP (y, 0)) == MINUS
+ && GET_CODE (XEXP (XEXP (y, 0), 1)) == LABEL_REF
+ && XEXP (XEXP (XEXP (y, 0),1), 0) == XEXP (const_arg0, 0))
+ return XEXP (XEXP (y, 0), 0);
}
/* If second operand is a register equivalent to a negative
op0_elt = lookup (op0, op0_hash, mode);
op1_elt = lookup (op1, op1_hash, mode);
+ /* If both operands are already equivalent or if they are not in the
+ table but are identical, do nothing. */
+ if ((op0_elt != 0 && op1_elt != 0
+ && op0_elt->first_same_value == op1_elt->first_same_value)
+ || op0 == op1 || rtx_equal_p (op0, op1))
+ return;
+
/* If we aren't setting two things equal all we can do is save this
comparison. Similarly if this is floating-point. In the latter
case, OP1 might be zero and both -0.0 and 0.0 are equal to it.
{
for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
if (GET_CODE (XEXP (tem, 0)) == CLOBBER)
- invalidate (SET_DEST (XEXP (tem, 0)));
+ invalidate (SET_DEST (XEXP (tem, 0)), VOIDmode);
}
if (GET_CODE (x) == SET)
canon_reg (SET_SRC (x), insn);
apply_change_group ();
fold_rtx (SET_SRC (x), insn);
- invalidate (SET_DEST (x));
+ invalidate (SET_DEST (x), VOIDmode);
}
else
n_sets = 1;
if (GET_CODE (clobbered) == REG
|| GET_CODE (clobbered) == SUBREG)
- invalidate (clobbered);
+ invalidate (clobbered, VOIDmode);
else if (GET_CODE (clobbered) == STRICT_LOW_PART
|| GET_CODE (clobbered) == ZERO_EXTRACT)
- invalidate (XEXP (clobbered, 0));
+ invalidate (XEXP (clobbered, 0), GET_MODE (clobbered));
}
}
canon_reg (SET_SRC (y), insn);
apply_change_group ();
fold_rtx (SET_SRC (y), insn);
- invalidate (SET_DEST (y));
+ invalidate (SET_DEST (y), VOIDmode);
}
else if (SET_DEST (y) == pc_rtx
&& GET_CODE (SET_SRC (y)) == LABEL_REF)
fold_rtx (x, insn);
}
- /* Store the equivalent value in SRC_EQV, if different. */
+ /* Store the equivalent value in SRC_EQV, if different, or if the DEST
+ is a STRICT_LOW_PART. The latter condition is necessary because SRC_EQV
+ is handled specially for this case, and if it isn't set, then there will
+ be no equivalence for the destinatation. */
if (n_sets == 1 && REG_NOTES (insn) != 0
&& (tem = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0
- && ! rtx_equal_p (XEXP (tem, 0), SET_SRC (sets[0].rtl)))
+ && (! rtx_equal_p (XEXP (tem, 0), SET_SRC (sets[0].rtl))
+ || GET_CODE (SET_DEST (sets[0].rtl)) == STRICT_LOW_PART))
src_eqv = canon_reg (XEXP (tem, 0), NULL_RTX);
/* Canonicalize sources and addresses of destinations.
{
if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == MEM)
- invalidate (dest);
+ invalidate (dest, VOIDmode);
else if (GET_CODE (dest) == STRICT_LOW_PART
|| GET_CODE (dest) == ZERO_EXTRACT)
- invalidate (XEXP (dest, 0));
+ invalidate (XEXP (dest, 0), GET_MODE (dest));
sets[i].rtl = 0;
}
for (i = 0; i < n_sets; i++)
if (sets[i].rtl)
{
- register rtx dest = sets[i].inner_dest;
+ /* We can't use the inner dest, because the mode associated with
+ a ZERO_EXTRACT is significant. */
+ register rtx dest = SET_DEST (sets[i].rtl);
/* Needed for registers to remove the register from its
previous quantity's chain.
Needed for memory if this is a nonvarying address, unless
we have just done an invalidate_memory that covers even those. */
if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG
- || (! writes_memory.all && ! cse_rtx_addr_varies_p (dest)))
- invalidate (dest);
+ || (GET_CODE (dest) == MEM && ! writes_memory.all
+ && ! cse_rtx_addr_varies_p (dest)))
+ invalidate (dest, VOIDmode);
else if (GET_CODE (dest) == STRICT_LOW_PART
|| GET_CODE (dest) == ZERO_EXTRACT)
- invalidate (XEXP (dest, 0));
+ invalidate (XEXP (dest, 0), GET_MODE (dest));
}
/* Make sure registers mentioned in destinations
already entered SRC and DEST of the SET in the table. */
if (GET_CODE (dest) == SUBREG
- && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) / UNITS_PER_WORD
- == GET_MODE_SIZE (GET_MODE (dest)) / UNITS_PER_WORD)
+ && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) - 1)
+ / UNITS_PER_WORD)
+ == (GET_MODE_SIZE (GET_MODE (dest)) - 1)/ UNITS_PER_WORD)
&& (GET_MODE_SIZE (GET_MODE (dest))
>= GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))))
&& sets[i].src_elt != 0)
/* This should be *very* rare. */
if (TEST_HARD_REG_BIT (hard_regs_in_table, STACK_POINTER_REGNUM))
- invalidate (stack_pointer_rtx);
+ invalidate (stack_pointer_rtx, VOIDmode);
}
if (GET_CODE (x) == CLOBBER)
{
if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG
|| (GET_CODE (ref) == MEM && ! w->all))
- invalidate (ref);
+ invalidate (ref, VOIDmode);
else if (GET_CODE (ref) == STRICT_LOW_PART
|| GET_CODE (ref) == ZERO_EXTRACT)
- invalidate (XEXP (ref, 0));
+ invalidate (XEXP (ref, 0), GET_MODE (ref));
}
}
else if (GET_CODE (x) == PARALLEL)
{
if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG
|| (GET_CODE (ref) == MEM && !w->all))
- invalidate (ref);
+ invalidate (ref, VOIDmode);
else if (GET_CODE (ref) == STRICT_LOW_PART
|| GET_CODE (ref) == ZERO_EXTRACT)
- invalidate (XEXP (ref, 0));
+ invalidate (XEXP (ref, 0), GET_MODE (ref));
}
}
}
for (p = last_jump_equiv_class->first_same_value; p;
p = p->next_same_value)
if (GET_CODE (p->exp) == MEM || GET_CODE (p->exp) == REG
- || GET_CODE (p->exp) == SUBREG)
- invalidate (p->exp);
+ || (GET_CODE (p->exp) == SUBREG
+ && GET_CODE (SUBREG_REG (p->exp)) == REG))
+ invalidate (p->exp, VOIDmode);
else if (GET_CODE (p->exp) == STRICT_LOW_PART
|| GET_CODE (p->exp) == ZERO_EXTRACT)
- invalidate (XEXP (p->exp, 0));
+ invalidate (XEXP (p->exp, 0), GET_MODE (p->exp));
/* Process insns starting after LOOP_START until we hit a CALL_INSN or
a CODE_LABEL (we could handle a CALL_INSN, but it isn't worth it).
if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG
|| (! skipped_writes_memory.all && ! cse_rtx_addr_varies_p (dest)))
- invalidate (dest);
+ invalidate (dest, VOIDmode);
else if (GET_CODE (dest) == STRICT_LOW_PART
|| GET_CODE (dest) == ZERO_EXTRACT)
- invalidate (XEXP (dest, 0));
+ invalidate (XEXP (dest, 0), GET_MODE (dest));
}
/* Invalidate all insns from START up to the end of the function or the
if (GET_CODE (SET_DEST (x)) == REG || GET_CODE (SET_DEST (x)) == SUBREG
|| (GET_CODE (SET_DEST (x)) == MEM && ! writes_memory.all
&& ! cse_rtx_addr_varies_p (SET_DEST (x))))
- invalidate (SET_DEST (x));
+ invalidate (SET_DEST (x), VOIDmode);
else if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART
|| GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
- invalidate (XEXP (SET_DEST (x), 0));
+ invalidate (XEXP (SET_DEST (x), 0), GET_MODE (SET_DEST (x)));
}
\f
/* Find the end of INSN's basic block and return its range,
/* Discard all the free elements of the previous function
since they are allocated in the temporarily obstack. */
- bzero (table, sizeof table);
+ bzero ((char *) table, sizeof table);
free_element_chain = 0;
n_elements_made = 0;
max_uid = get_max_uid ();
uid_cuid = (int *) alloca ((max_uid + 1) * sizeof (int));
- bzero (uid_cuid, (max_uid + 1) * sizeof (int));
+ bzero ((char *) uid_cuid, (max_uid + 1) * sizeof (int));
/* Compute the mapping from uids to cuids.
CUIDs are numbers assigned to insns, like uids,
int in_libcall = 0;
/* First count the number of times each register is used. */
- bzero (counts, sizeof (int) * nreg);
+ bzero ((char *) counts, sizeof (int) * nreg);
for (insn = next_real_insn (insns); insn; insn = next_real_insn (insn))
count_reg_usage (insn, counts, NULL_RTX, 1);