*** empty log message ***

From-SVN: r579
This commit is contained in:
Richard Stallman 1992-03-23 19:42:32 +00:00
parent e932039036
commit 5089e22e27
2 changed files with 121 additions and 36 deletions

View File

@ -114,7 +114,7 @@ static int combine_successes;
static int total_attempts, total_merges, total_extras, total_successes;
/* Vector mapping INSN_UIDs to cuids.
The cuids are like uids but increase monononically always.
The cuids are like uids but increase monotonically always.
Combine always uses cuids so that it can compare them.
But actually renumbering the uids, which we used to do,
proves to be a bad idea because it makes it hard to compare
@ -174,7 +174,7 @@ static int previous_num_undos;
/* The next group of arrays allows the recording of the last value assigned
to (hard or pseudo) register n. We use this information to see if a
operation being processed is redundant given the a prior operation peformed
operation being processed is redundant given a prior operation performed
on the register. For example, an `and' with a constant is redundant if
all the zero bits are already known to be turned off.
@ -517,7 +517,7 @@ combine_instructions (f, nregs)
/* Finally, see if any of the insns that this insn links to
explicitly references CC0. If so, try this insn, that insn,
and its prececessor if it sets CC0. */
and its predecessor if it sets CC0. */
for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
if (GET_CODE (XEXP (links, 0)) == INSN
&& GET_CODE (PATTERN (XEXP (links, 0))) == SET
@ -576,7 +576,7 @@ set_significant (x, set)
return;
/* If this is a complex assignment, see if we can convert it into a
simple assignent. */
simple assignment. */
set = expand_field_assignment (set);
if (SET_DEST (set) == x)
reg_significant[REGNO (x)]
@ -682,9 +682,16 @@ can_combine_p (insn, i3, pred, succ, pdest, psrc)
It can worsen register allocation, and can even make invalid reload
insns, since the reg inside may need to be copied from in the
outside mode, and that may be invalid if it is an fp reg copied in
integer mode. */
integer mode. As a special exception, we can allow this if
I3 is simply copying DEST, a REG, to CC0. */
|| (GET_CODE (src) == SUBREG
&& ! MODES_TIEABLE_P (GET_MODE (src), GET_MODE (SUBREG_REG (src))))
&& ! MODES_TIEABLE_P (GET_MODE (src), GET_MODE (SUBREG_REG (src)))
#ifdef HAVE_cc0
&& ! (GET_CODE (i3) == INSN && GET_CODE (PATTERN (i3)) == SET
&& SET_DEST (PATTERN (i3)) == cc0_rtx
&& GET_CODE (dest) == REG && dest == SET_SRC (PATTERN (i3)))
#endif
)
/* If we couldn't eliminate a field assignment, we can't combine. */
|| GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == STRICT_LOW_PART
/* Don't combine with an insn that sets a register to itself if it has
@ -1031,29 +1038,56 @@ try_combine (i3, i2, i1)
&& find_reg_note (i3, REG_DEAD, SET_SRC (PATTERN (i3)))
&& GET_CODE (PATTERN (i2)) == PARALLEL
&& ! side_effects_p (SET_DEST (PATTERN (i3)))
/* If the dest of I3 is a ZERO_EXTRACT or STRICT_LOW_PART, the code
below would need to check what is inside (and reg_overlap_mentioned_p
doesn't support those codes anyway). Don't allow those destinations;
the resulting insn isn't likely to be recognized anyway. */
&& GET_CODE (SET_DEST (PATTERN (i3))) != ZERO_EXTRACT
&& GET_CODE (SET_DEST (PATTERN (i3))) != STRICT_LOW_PART
&& ! reg_overlap_mentioned_p (SET_SRC (PATTERN (i3)),
SET_DEST (PATTERN (i3)))
&& next_real_insn (i2) == i3)
for (i = 0; i < XVECLEN (PATTERN (i2), 0); i++)
if (SET_DEST (XVECEXP (PATTERN (i2), 0, i)) == SET_SRC (PATTERN (i3)))
{
combine_merges++;
{
rtx p2 = PATTERN (i2);
subst_insn = i3;
subst_low_cuid = INSN_CUID (i2);
/* Make sure that the destination of I3,
which we are going to substitute into one output of I2,
is not used within another output of I2. We must avoid making this:
(parallel [(set (mem (reg 69)) ...)
(set (reg 69) ...)])
which is not well-defined as to order of actions.
(Besides, reload can't handle output reloads for this.)
added_sets_2 = 0;
i2dest = SET_SRC (PATTERN (i3));
The problem can also happen if the dest of I3 is a memory ref,
if another dest in I2 is an indirect memory ref. */
for (i = 0; i < XVECLEN (p2, 0); i++)
if (GET_CODE (XVECEXP (p2, 0, i)) == SET
&& reg_overlap_mentioned_p (SET_DEST (PATTERN (i3)),
SET_DEST (XVECEXP (p2, 0, i))))
break;
/* Replace the dest in I2 with our dest and make the resulting
insn the new pattern for I3. Then skip to where we
validate the pattern. Everything was set up above. */
SUBST (SET_DEST (XVECEXP (PATTERN (i2), 0, i)),
SET_DEST (PATTERN (i3)));
if (i == XVECLEN (p2, 0))
for (i = 0; i < XVECLEN (p2, 0); i++)
if (SET_DEST (XVECEXP (p2, 0, i)) == SET_SRC (PATTERN (i3)))
{
combine_merges++;
newpat = PATTERN (i2);
goto validate_replacement;
}
subst_insn = i3;
subst_low_cuid = INSN_CUID (i2);
added_sets_2 = 0;
i2dest = SET_SRC (PATTERN (i3));
/* Replace the dest in I2 with our dest and make the resulting
insn the new pattern for I3. Then skip to where we
validate the pattern. Everything was set up above. */
SUBST (SET_DEST (XVECEXP (p2, 0, i)),
SET_DEST (PATTERN (i3)));
newpat = p2;
goto validate_replacement;
}
}
#ifndef HAVE_cc0
/* If we have no I1 and I2 looks like:
@ -1134,7 +1168,7 @@ try_combine (i3, i2, i1)
output operand. However, that exception can give rise to insns like
mov r3,(r3)+
which is a famous insn on the PDP-11 where the value of r3 used as the
source was model-dependant. Avoid this sort of thing. */
source was model-dependent. Avoid this sort of thing. */
#if 0
if (!(GET_CODE (PATTERN (i3)) == SET
@ -1175,7 +1209,7 @@ try_combine (i3, i2, i1)
/* If the set in I2 needs to be kept around, we must make a copy of
PATTERN (I2), so that when we substitute I1SRC for I1DEST in
PATTERN (I2), we are only substituing for the original I1DEST, not into
PATTERN (I2), we are only substituting for the original I1DEST, not into
an already-substituted copy. This also prevents making self-referential
rtx. If I2 is a PARALLEL, we just need the piece that assigns I2SRC to
I2DEST. */
@ -1517,6 +1551,50 @@ try_combine (i3, i2, i1)
i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
if (i2_code_number >= 0)
insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
if (insn_code_number >= 0)
{
rtx insn;
rtx link;
/* If we will be able to accept this, we have made a change to the
destination of I3. This can invalidate a LOG_LINKS pointing
to I3. No other part of combine.c makes such a transformation.
The new I3 will have a destination that was previously the
destination of I1 or I2 and which was used in i2 or I3. Call
distribute_links to make a LOG_LINK from the next use of
that destination. */
PATTERN (i3) = newpat;
distribute_links (gen_rtx (INSN_LIST, VOIDmode, i3, 0));
/* I3 now uses what used to be its destination and which is
now I2's destination. That means we need a LOG_LINK from
I3 to I2. But we used to have one, so we still will.
However, some later insn might be using I2's dest and have
a LOG_LINK pointing at I3. We must remove this link.
The simplest way to remove the link is to point it at I1,
which we know will be a NOTE. */
for (insn = NEXT_INSN (i3);
insn && GET_CODE (insn) != CODE_LABEL
&& GET_CODE (PREV_INSN (insn)) != JUMP_INSN;
insn = NEXT_INSN (insn))
{
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
&& reg_referenced_p (SET_DEST (newi2pat), PATTERN (insn)))
{
for (link = LOG_LINKS (insn); link;
link = XEXP (link, 1))
if (XEXP (link, 0) == i3)
XEXP (link, 0) = i1;
break;
}
}
}
}
/* Similarly, check for a case where we have a PARALLEL of two independent
@ -1620,7 +1698,7 @@ try_combine (i3, i2, i1)
/* Ensure that we do not have something that should not be shared but
occurs multiple times in the new insns. Check this by first
restting all the `used' flags and then copying anything is shared. */
resetting all the `used' flags and then copying anything is shared. */
reset_used_flags (i3notes);
reset_used_flags (i2notes);
@ -2082,7 +2160,7 @@ find_split_point (loc)
IN_DEST is non-zero if we are processing the SET_DEST of a SET.
UNIQUE_COPY is non-zero if each substition must be unique. We do this
UNIQUE_COPY is non-zero if each substitution must be unique. We do this
by copying if `n_occurrences' is non-zero. */
static rtx
@ -4435,7 +4513,8 @@ make_field_assignment (x)
/* Shift OTHER right POS places and make it the source, restricting it
to the proper length and mode. */
src = force_to_mode (simplify_shift_const (0, LSHIFTRT, mode, other, pos),
src = force_to_mode (simplify_shift_const (0, LSHIFTRT, GET_MODE (src),
other, pos),
mode, len, dest);
return gen_rtx_combine (SET, VOIDmode, assign, src);
@ -6253,7 +6332,7 @@ gen_unary (code, mode, op0)
It is possible that we might detect that a comparison is either always
true or always false. However, we do not perform general constant
folding in combine, so this knowlege isn't useful. Such tautologies
folding in combine, so this knowledge isn't useful. Such tautologies
should have been detected earlier. Hence we ignore all such cases. */
static enum rtx_code
@ -6685,7 +6764,7 @@ simplify_comparison (code, pop0, pop1)
case PLUS:
/* (eq (plus X C1) C2) -> (eq X (minus C2 C1)). We can only do
this for equality comparisons due to pathalogical cases involving
this for equality comparisons due to pathological cases involving
overflows. */
if (equality_comparison_p && GET_CODE (XEXP (op0, 1)) == CONST_INT
&& (tem = simplify_binary_operation (MINUS, mode, op1,
@ -7576,9 +7655,9 @@ reg_bitfield_target_p (reg, body)
if (GET_CODE (body) == SET)
return ((GET_CODE (SET_DEST (body)) == ZERO_EXTRACT
&& reg == XEXP (SET_DEST (body), 0))
&& rtx_equal_p (reg, XEXP (SET_DEST (body), 0)))
|| (GET_CODE (SET_DEST (body)) == STRICT_LOW_PART
&& reg == SUBREG_REG (XEXP (SET_DEST (body), 0))));
&& rtx_equal_p (reg, SUBREG_REG (XEXP (SET_DEST (body), 0)))));
else if (GET_CODE (body) == PARALLEL)
for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
@ -7742,7 +7821,11 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
{
rtx set = single_set (tem);
if (set != 0 && ! side_effects_p (SET_SRC (set)))
/* Verify that it was the set, and not a clobber that
modified the register. */
if (set != 0 && ! side_effects_p (SET_SRC (set))
&& rtx_equal_p (XEXP (note, 0), SET_DEST (set)))
{
/* Move the notes and links of TEM elsewhere.
This might delete other dead insns recursively.
@ -7830,6 +7913,7 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
= emit_insn_before (gen_rtx (USE, VOIDmode, piece),
place);
all_used = 0;
REG_NOTES (use_insn)
= gen_rtx (EXPR_LIST, REG_DEAD, piece,
REG_NOTES (use_insn));
@ -7878,7 +7962,8 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
}
/* Similarly to above, distribute the LOG_LINKS that used to be present on
I3, I2, and I1 to new locations. */
I3, I2, and I1 to new locations. This is also called in one case to
add a link pointing at I3 when I3's destination is changed. */
static void
distribute_links (links)
@ -7921,7 +8006,7 @@ distribute_links (links)
when we reach a set of the register or the end of the basic block.
Note that this correctly handles the link that used to point from
I3 to I2. Also note that not much seaching is typically done here
I3 to I2. Also note that not much searching is typically done here
since most links don't point very far away. */
for (insn = NEXT_INSN (XEXP (link, 0));

View File

@ -43,7 +43,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* -m68881 is the default */
#define CPP_SPEC \
"%{!msoft-float:%{mfpa:-D__HAVE_FPA__ }%{!mfpa:-D__HAVE_68881__ }}\
%{m68000:-D__mc68010__}%{mc68000:-D__mc68010__}%{!mc68000:%{!m68000:-D__mc68020__}}} \
%{m68000:-D__mc68010__}%{mc68000:-D__mc68010__}%{!mc68000:%{!m68000:-D__mc68020__}} \
%{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}}"
#else
@ -51,7 +51,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* -msoft-float is the default */
#define CPP_SPEC \
"%{m68881:-D__HAVE_68881__ }%{mfpa:-D__HAVE_FPA__ }\
%{m68000:-D__mc68010__}%{mc68000:-D__mc68010__}%{!mc68000:%{!m68000:-D__mc68020__}}} \
%{m68000:-D__mc68010__}%{mc68000:-D__mc68010__}%{!mc68000:%{!m68000:-D__mc68020__}} \
%{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}}"
#endif