flow.c (mark_set_1, [...]): Now case; rework to allow entry to be EXPR_LIST.
* flow.c (mark_set_1, case PARALLEL): Now case; rework to allow entry to be EXPR_LIST. * rtlanal.c (reg_overlap_mentioned_p): Allow PARALLEL in SET to be an EXPR_LIST (but not null, which other code doesn't allow). (note_stores): Properly handle PARALLEL in SET. Recursively call for top-level PARALLEL. * sched-deps.c (sched_analyze_1): Handle EXPR_LIST in PARALLEL in SET. * sched-rgn.c (check_live_1, update_live_1): Likewise. From-SVN: r39118
This commit is contained in:
parent
8eeb855e2b
commit
90d036a050
|
@ -1,5 +1,14 @@
|
||||||
Thu Jan 18 06:43:04 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
Thu Jan 18 06:43:04 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||||
|
|
||||||
|
* flow.c (mark_set_1, case PARALLEL): Now case; rework to allow
|
||||||
|
entry to be EXPR_LIST.
|
||||||
|
* rtlanal.c (reg_overlap_mentioned_p): Allow PARALLEL in SET to
|
||||||
|
be an EXPR_LIST (but not null, which other code doesn't allow).
|
||||||
|
(note_stores): Properly handle PARALLEL in SET.
|
||||||
|
Recursively call for top-level PARALLEL.
|
||||||
|
* sched-deps.c (sched_analyze_1): Handle EXPR_LIST in PARALLEL in SET.
|
||||||
|
* sched-rgn.c (check_live_1, update_live_1): Likewise.
|
||||||
|
|
||||||
* config.gcc (rs6000-ibm-aix*, rs6000-bull-bosx): Add rs6000/aix.h.
|
* config.gcc (rs6000-ibm-aix*, rs6000-bull-bosx): Add rs6000/aix.h.
|
||||||
|
|
||||||
2001-01-18 Neil Booth <neil@daikokuya.demon.co.uk>
|
2001-01-18 Neil Booth <neil@daikokuya.demon.co.uk>
|
||||||
|
|
33
gcc/flow.c
33
gcc/flow.c
|
@ -4651,23 +4651,30 @@ mark_set_1 (pbi, code, reg, cond, insn, flags)
|
||||||
int not_dead = 0;
|
int not_dead = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Some targets place small structures in registers for
|
|
||||||
return values of functions. We have to detect this
|
|
||||||
case specially here to get correct flow information. */
|
|
||||||
if (GET_CODE (reg) == PARALLEL
|
|
||||||
&& GET_MODE (reg) == BLKmode)
|
|
||||||
{
|
|
||||||
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
|
|
||||||
mark_set_1 (pbi, code, XVECEXP (reg, 0, i), cond, insn, flags);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Modifying just one hardware register of a multi-reg value or just a
|
/* Modifying just one hardware register of a multi-reg value or just a
|
||||||
byte field of a register does not mean the value from before this insn
|
byte field of a register does not mean the value from before this insn
|
||||||
is now dead. Of course, if it was dead after it's unused now. */
|
is now dead. Of course, if it was dead after it's unused now. */
|
||||||
|
|
||||||
switch (GET_CODE (reg))
|
switch (GET_CODE (reg))
|
||||||
{
|
{
|
||||||
|
case PARALLEL:
|
||||||
|
/* Some targets place small structures in registers for return values of
|
||||||
|
functions. We have to detect this case specially here to get correct
|
||||||
|
flow information. Note that each element might be either a REG
|
||||||
|
or an EXPR_LIST whose first operand is a REG. */
|
||||||
|
if (GET_MODE (reg) != BLKmode)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
rtx elmt = XVECEXP (reg, 0, i);
|
||||||
|
|
||||||
|
mark_set_1 (pbi, code,
|
||||||
|
GET_CODE (elmt) == EXPR_LIST ? XEXP (elmt, 0) : elmt,
|
||||||
|
cond, insn, flags);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
case ZERO_EXTRACT:
|
case ZERO_EXTRACT:
|
||||||
case SIGN_EXTRACT:
|
case SIGN_EXTRACT:
|
||||||
case STRICT_LOW_PART:
|
case STRICT_LOW_PART:
|
||||||
|
@ -5964,8 +5971,8 @@ mark_used_regs (pbi, x, cond, insn)
|
||||||
testreg = XEXP (testreg, 0);
|
testreg = XEXP (testreg, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is a store into a register, recursively scan the
|
/* If this is a store into a register or group of registers,
|
||||||
value being stored. */
|
recursively scan the value being stored. */
|
||||||
|
|
||||||
if ((GET_CODE (testreg) == PARALLEL
|
if ((GET_CODE (testreg) == PARALLEL
|
||||||
&& GET_MODE (testreg) == BLKmode)
|
&& GET_MODE (testreg) == BLKmode)
|
||||||
|
|
|
@ -1182,20 +1182,21 @@ reg_overlap_mentioned_p (x, in)
|
||||||
|
|
||||||
case PARALLEL:
|
case PARALLEL:
|
||||||
{
|
{
|
||||||
int i, n;
|
int i;
|
||||||
|
|
||||||
/* Check for a NULL entry, used to indicate that the parameter goes
|
|
||||||
both on the stack and in registers. */
|
|
||||||
if (XEXP (XVECEXP (x, 0, 0), 0))
|
|
||||||
i = 0;
|
|
||||||
else
|
|
||||||
i = 1;
|
|
||||||
|
|
||||||
/* If any register in here refers to it we return true. */
|
/* If any register in here refers to it we return true. */
|
||||||
for (n = XVECLEN (x, 0); i < n; ++i)
|
for (i = XVECLEN (x, 0); i >= 0; i--)
|
||||||
if (reg_overlap_mentioned_p (XEXP (XVECEXP (x, 0, i), 0), in))
|
{
|
||||||
|
rtx reg = XVECEXP (x, 0, i);
|
||||||
|
|
||||||
|
if (GET_CODE (reg) == EXPR_LIST)
|
||||||
|
reg = XEXP (reg, 0);
|
||||||
|
|
||||||
|
if (reg_overlap_mentioned_p (reg, in))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1270,11 +1271,15 @@ note_stores (x, fun, data)
|
||||||
void (*fun) PARAMS ((rtx, rtx, void *));
|
void (*fun) PARAMS ((rtx, rtx, void *));
|
||||||
void *data;
|
void *data;
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if (GET_CODE (x) == COND_EXEC)
|
if (GET_CODE (x) == COND_EXEC)
|
||||||
x = COND_EXEC_CODE (x);
|
x = COND_EXEC_CODE (x);
|
||||||
|
|
||||||
if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
|
if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
|
||||||
{
|
{
|
||||||
register rtx dest = SET_DEST (x);
|
register rtx dest = SET_DEST (x);
|
||||||
|
|
||||||
while ((GET_CODE (dest) == SUBREG
|
while ((GET_CODE (dest) == SUBREG
|
||||||
&& (GET_CODE (SUBREG_REG (dest)) != REG
|
&& (GET_CODE (SUBREG_REG (dest)) != REG
|
||||||
|| REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER))
|
|| REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER))
|
||||||
|
@ -1283,48 +1288,27 @@ note_stores (x, fun, data)
|
||||||
|| GET_CODE (dest) == STRICT_LOW_PART)
|
|| GET_CODE (dest) == STRICT_LOW_PART)
|
||||||
dest = XEXP (dest, 0);
|
dest = XEXP (dest, 0);
|
||||||
|
|
||||||
if (GET_CODE (dest) == PARALLEL
|
/* If we have a PARALLEL, SET_DEST is a list of registers or
|
||||||
&& GET_MODE (dest) == BLKmode)
|
EXPR_LIST expressions, each of whose first operand is a register.
|
||||||
{
|
We can't know what precisely is being set in these cases, so
|
||||||
register int i;
|
make up a CLOBBER to pass to the function. */
|
||||||
|
if (GET_CODE (dest) == PARALLEL && GET_MODE (dest) == BLKmode)
|
||||||
for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
|
for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
|
||||||
(*fun) (SET_DEST (XVECEXP (dest, 0, i)), x, data);
|
{
|
||||||
|
rtx reg = XVECEXP (dest, 0, i);
|
||||||
|
|
||||||
|
if (GET_CODE (reg) == EXPR_LIST)
|
||||||
|
reg = XEXP (reg, 0);
|
||||||
|
|
||||||
|
(*fun) (reg, gen_rtx_CLOBBER (VOIDmode, reg), data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
(*fun) (dest, x, data);
|
(*fun) (dest, x, data);
|
||||||
}
|
}
|
||||||
else if (GET_CODE (x) == PARALLEL)
|
|
||||||
{
|
|
||||||
register int i;
|
|
||||||
for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
register rtx y = XVECEXP (x, 0, i);
|
|
||||||
if (GET_CODE (y) == COND_EXEC)
|
|
||||||
y = COND_EXEC_CODE (y);
|
|
||||||
if (GET_CODE (y) == SET || GET_CODE (y) == CLOBBER)
|
|
||||||
{
|
|
||||||
register rtx dest = SET_DEST (y);
|
|
||||||
while ((GET_CODE (dest) == SUBREG
|
|
||||||
&& (GET_CODE (SUBREG_REG (dest)) != REG
|
|
||||||
|| (REGNO (SUBREG_REG (dest))
|
|
||||||
>= FIRST_PSEUDO_REGISTER)))
|
|
||||||
|| GET_CODE (dest) == ZERO_EXTRACT
|
|
||||||
|| GET_CODE (dest) == SIGN_EXTRACT
|
|
||||||
|| GET_CODE (dest) == STRICT_LOW_PART)
|
|
||||||
dest = XEXP (dest, 0);
|
|
||||||
if (GET_CODE (dest) == PARALLEL
|
|
||||||
&& GET_MODE (dest) == BLKmode)
|
|
||||||
{
|
|
||||||
register int i;
|
|
||||||
|
|
||||||
for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
|
else if (GET_CODE (x) == PARALLEL)
|
||||||
(*fun) (SET_DEST (XVECEXP (dest, 0, i)), y, data);
|
for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
|
||||||
}
|
note_stores (XVECEXP (x, 0, i), fun, data);
|
||||||
else
|
|
||||||
(*fun) (dest, y, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return nonzero if X's old contents don't survive after INSN.
|
/* Return nonzero if X's old contents don't survive after INSN.
|
||||||
|
|
|
@ -551,12 +551,20 @@ sched_analyze_1 (deps, x, insn)
|
||||||
if (dest == 0)
|
if (dest == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (GET_CODE (dest) == PARALLEL
|
if (GET_CODE (dest) == PARALLEL && GET_MODE (dest) == BLKmode)
|
||||||
&& GET_MODE (dest) == BLKmode)
|
|
||||||
{
|
{
|
||||||
register int i;
|
register int i;
|
||||||
|
|
||||||
for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
|
for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
|
||||||
sched_analyze_1 (deps, XVECEXP (dest, 0, i), insn);
|
{
|
||||||
|
rtx reg = XVECEXP (dest, 0, i);
|
||||||
|
|
||||||
|
if (GET_CODE (reg) == EXPR_LIST)
|
||||||
|
reg = XEXP (reg, 0);
|
||||||
|
|
||||||
|
sched_analyze_1 (deps, reg, insn);
|
||||||
|
}
|
||||||
|
|
||||||
if (GET_CODE (x) == SET)
|
if (GET_CODE (x) == SET)
|
||||||
sched_analyze_2 (deps, SET_SRC (x), insn);
|
sched_analyze_2 (deps, SET_SRC (x), insn);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1396,13 +1396,21 @@ check_live_1 (src, x)
|
||||||
|| GET_CODE (reg) == STRICT_LOW_PART)
|
|| GET_CODE (reg) == STRICT_LOW_PART)
|
||||||
reg = XEXP (reg, 0);
|
reg = XEXP (reg, 0);
|
||||||
|
|
||||||
if (GET_CODE (reg) == PARALLEL
|
if (GET_CODE (reg) == PARALLEL && GET_MODE (reg) == BLKmode)
|
||||||
&& GET_MODE (reg) == BLKmode)
|
|
||||||
{
|
{
|
||||||
register int i;
|
register int i;
|
||||||
|
|
||||||
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
|
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
|
||||||
if (check_live_1 (src, XVECEXP (reg, 0, i)))
|
{
|
||||||
|
rtx dest = XVECEXP (reg, 0, i);
|
||||||
|
|
||||||
|
if (GET_CODE (dest) == EXPR_LIST)
|
||||||
|
dest = XEXP (dest, 0);
|
||||||
|
|
||||||
|
if (check_live_1 (src, dest))
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1474,12 +1482,20 @@ update_live_1 (src, x)
|
||||||
|| GET_CODE (reg) == STRICT_LOW_PART)
|
|| GET_CODE (reg) == STRICT_LOW_PART)
|
||||||
reg = XEXP (reg, 0);
|
reg = XEXP (reg, 0);
|
||||||
|
|
||||||
if (GET_CODE (reg) == PARALLEL
|
if (GET_CODE (reg) == PARALLEL && GET_MODE (reg) == BLKmode)
|
||||||
&& GET_MODE (reg) == BLKmode)
|
|
||||||
{
|
{
|
||||||
register int i;
|
register int i;
|
||||||
|
|
||||||
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
|
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
|
||||||
update_live_1 (src, XVECEXP (reg, 0, i));
|
{
|
||||||
|
rtx dest = XVECEXP (reg, 0, i);
|
||||||
|
|
||||||
|
if (GET_CODE (dest) == EXPR_LIST)
|
||||||
|
dest = XEXP (dest, 0);
|
||||||
|
|
||||||
|
update_live_1 (src, dest);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1915,15 +1931,17 @@ haifa_classify_insn (insn)
|
||||||
if (tmp_class == TRAP_RISKY)
|
if (tmp_class == TRAP_RISKY)
|
||||||
break;
|
break;
|
||||||
/* Test if it is a load. */
|
/* Test if it is a load. */
|
||||||
tmp_class =
|
tmp_class
|
||||||
WORST_CLASS (tmp_class,
|
= WORST_CLASS (tmp_class,
|
||||||
may_trap_exp (SET_SRC (XVECEXP (pat, 0, i)), 0));
|
may_trap_exp (SET_SRC (XVECEXP (pat, 0, i)),
|
||||||
|
0));
|
||||||
break;
|
break;
|
||||||
case COND_EXEC:
|
case COND_EXEC:
|
||||||
case TRAP_IF:
|
case TRAP_IF:
|
||||||
tmp_class = TRAP_RISKY;
|
tmp_class = TRAP_RISKY;
|
||||||
break;
|
break;
|
||||||
default:;
|
default:
|
||||||
|
;
|
||||||
}
|
}
|
||||||
insn_class = WORST_CLASS (insn_class, tmp_class);
|
insn_class = WORST_CLASS (insn_class, tmp_class);
|
||||||
if (insn_class == TRAP_RISKY || insn_class == IRISKY)
|
if (insn_class == TRAP_RISKY || insn_class == IRISKY)
|
||||||
|
|
Loading…
Reference in New Issue