mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-16 05:49:56 +08:00
rtlanal.c (single_set_1): Do not require USE and CLOBBERs to come last.
* rtlanal.c (single_set_1): Do not require USE and CLOBBERs to come last. From-SVN: r36699
This commit is contained in:
parent
81bce466fe
commit
c9b89a214a
@ -1,3 +1,8 @@
|
||||
Mon Oct 2 14:50:14 MET DST 2000 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* rtlanal.c (single_set_1): Do not require USE and CLOBBERs
|
||||
to come last.
|
||||
|
||||
2000-10-03 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
|
||||
|
||||
* config/float-c4x.h: New.
|
||||
|
122
gcc/rtlanal.c
122
gcc/rtlanal.c
@ -846,98 +846,52 @@ rtx
|
||||
single_set_1 (insn)
|
||||
rtx insn;
|
||||
{
|
||||
rtx set;
|
||||
rtx set = NULL;
|
||||
int set_verified = 1;
|
||||
rtx pat = PATTERN (insn);
|
||||
int i;
|
||||
|
||||
|
||||
if (GET_CODE (pat) == PARALLEL)
|
||||
{
|
||||
rtx x, sub;
|
||||
/* This part is is performance critical for targets that use a lot of
|
||||
parallels, such as i386. We want to accept as single set
|
||||
instructions even an instructions with multiple sets where only
|
||||
one has live result, but we attempt to delay this tests only for
|
||||
multiple set instructions to reduce amount of calls to
|
||||
find_reg_note and side_effects_p.
|
||||
|
||||
We expect the "common" instruction to be parallel with first SET
|
||||
followed by the clobbers. So first we get the set, then look
|
||||
if it is followed by USE or CLOBBER. If so, we just return expect
|
||||
no SETs after these. When SET is followed by another SET, we
|
||||
continue by the clomplex loop trought all members of PARALLEL.
|
||||
*/
|
||||
#ifdef ENABLE_CHECKING
|
||||
if (XVECLEN (pat, 0) < 2)
|
||||
abort ();
|
||||
#endif
|
||||
set = XVECEXP (pat, 0, 0);
|
||||
switch (GET_CODE (set))
|
||||
for (i = 0; i < XVECLEN (pat, 0); i++)
|
||||
{
|
||||
#ifdef ENABLE_CHECKING
|
||||
case USE:
|
||||
case CLOBBER:
|
||||
/* Instruction should not consist only from USEs and CLOBBERS,
|
||||
since then gcc is allowed to remove it entirely. In case
|
||||
something else is present, it should be first in the pattern. */
|
||||
fatal_insn ("USE or CLOBBER before SET:", insn);
|
||||
#endif
|
||||
case SET:
|
||||
break;
|
||||
default:
|
||||
return NULL_RTX;
|
||||
}
|
||||
x = XVECEXP (pat, 0, 1);
|
||||
switch (GET_CODE (x))
|
||||
{
|
||||
case USE:
|
||||
case CLOBBER:
|
||||
#ifdef ENABLE_CHECKING
|
||||
/* The USEs and CLOBBERs should always come last in the pattern. */
|
||||
for (i = XVECLEN (pat, 0) - 1; i > 1; i--)
|
||||
if (GET_CODE (XVECEXP (pat, 0, i)) != USE
|
||||
&& GET_CODE (XVECEXP (pat, 0, i)) != CLOBBER)
|
||||
fatal_insn ("USE or CLOBBER before SET:", insn);
|
||||
#endif
|
||||
return set;
|
||||
case SET:
|
||||
{
|
||||
int seen_clobber = 0;
|
||||
rtx sub = XVECEXP (pat, 0, i);
|
||||
switch (GET_CODE (sub))
|
||||
{
|
||||
case USE:
|
||||
case CLOBBER:
|
||||
break;
|
||||
|
||||
/* Multiple set insns - we are off the critical path now. */
|
||||
for (i = 1; i < XVECLEN (pat, 0); i++)
|
||||
{
|
||||
sub = XVECEXP (pat, 0, i);
|
||||
switch GET_CODE (sub)
|
||||
{
|
||||
case USE:
|
||||
case CLOBBER:
|
||||
seen_clobber = 1;
|
||||
break;
|
||||
|
||||
case SET:
|
||||
if (seen_clobber)
|
||||
fatal_insn ("USE or CLOBBER before SET:", insn);
|
||||
if (!set
|
||||
|| (find_reg_note (insn, REG_UNUSED, SET_DEST (set))
|
||||
&& side_effects_p (set)))
|
||||
set = sub;
|
||||
else if (! find_reg_note (insn, REG_UNUSED, SET_DEST (sub))
|
||||
|| side_effects_p (sub))
|
||||
return NULL_RTX;
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL_RTX;
|
||||
}
|
||||
}
|
||||
}
|
||||
return set;
|
||||
default:
|
||||
return NULL_RTX;
|
||||
case SET:
|
||||
/* We can consider insns having multiple sets, where all
|
||||
but one are dead as single set insns. In common case
|
||||
only single set is present in the pattern so we want
|
||||
to avoid checking for REG_UNUSED notes unless neccesary.
|
||||
|
||||
When we reach set first time, we just expect this is
|
||||
the single set we are looking for and only when more
|
||||
sets are found in the insn, we check them. */
|
||||
if (!set_verified)
|
||||
{
|
||||
if (find_reg_note (insn, REG_UNUSED, SET_DEST (set))
|
||||
&& !side_effects_p (set))
|
||||
set = NULL;
|
||||
else
|
||||
set_verified = 1;
|
||||
}
|
||||
if (!set)
|
||||
set = sub, set_verified = 0;
|
||||
else if (!find_reg_note (insn, REG_UNUSED, SET_DEST (sub))
|
||||
|| side_effects_p (sub))
|
||||
return NULL_RTX;
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL_RTX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return set;
|
||||
}
|
||||
|
||||
/* Given an INSN, return nonzero if it has more than one SET, else return
|
||||
|
Loading…
Reference in New Issue
Block a user