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:
Richard Kenner 2001-01-18 13:14:34 +00:00 committed by Richard Kenner
parent 8eeb855e2b
commit 90d036a050
5 changed files with 103 additions and 77 deletions

View File

@ -1,5 +1,14 @@
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.
2001-01-18 Neil Booth <neil@daikokuya.demon.co.uk>

View File

@ -4651,23 +4651,30 @@ mark_set_1 (pbi, code, reg, cond, insn, flags)
int not_dead = 0;
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
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. */
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 SIGN_EXTRACT:
case STRICT_LOW_PART:
@ -5964,8 +5971,8 @@ mark_used_regs (pbi, x, cond, insn)
testreg = XEXP (testreg, 0);
}
/* If this is a store into a register, recursively scan the
value being stored. */
/* If this is a store into a register or group of registers,
recursively scan the value being stored. */
if ((GET_CODE (testreg) == PARALLEL
&& GET_MODE (testreg) == BLKmode)

View File

@ -1182,20 +1182,21 @@ reg_overlap_mentioned_p (x, in)
case PARALLEL:
{
int i, n;
/* 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;
int i;
/* If any register in here refers to it we return true. */
for (n = XVECLEN (x, 0); i < n; ++i)
if (reg_overlap_mentioned_p (XEXP (XVECEXP (x, 0, i), 0), in))
return 1;
return 0;
for (i = XVECLEN (x, 0); i >= 0; i--)
{
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 0;
}
}
default:
@ -1270,11 +1271,15 @@ note_stores (x, fun, data)
void (*fun) PARAMS ((rtx, rtx, void *));
void *data;
{
int i;
if (GET_CODE (x) == COND_EXEC)
x = COND_EXEC_CODE (x);
if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
{
register rtx dest = SET_DEST (x);
while ((GET_CODE (dest) == SUBREG
&& (GET_CODE (SUBREG_REG (dest)) != REG
|| REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER))
@ -1283,48 +1288,27 @@ note_stores (x, fun, data)
|| 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--)
(*fun) (SET_DEST (XVECEXP (dest, 0, i)), x, data);
}
/* If we have a PARALLEL, SET_DEST is a list of registers or
EXPR_LIST expressions, each of whose first operand is a register.
We can't know what precisely is being set in these cases, so
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--)
{
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
(*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--)
(*fun) (SET_DEST (XVECEXP (dest, 0, i)), y, data);
}
else
(*fun) (dest, y, data);
}
}
}
else if (GET_CODE (x) == PARALLEL)
for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
note_stores (XVECEXP (x, 0, i), fun, data);
}
/* Return nonzero if X's old contents don't survive after INSN.

View File

@ -551,12 +551,20 @@ sched_analyze_1 (deps, x, insn)
if (dest == 0)
return;
if (GET_CODE (dest) == PARALLEL
&& GET_MODE (dest) == BLKmode)
if (GET_CODE (dest) == PARALLEL && GET_MODE (dest) == BLKmode)
{
register int 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)
sched_analyze_2 (deps, SET_SRC (x), insn);
return;

View File

@ -1396,13 +1396,21 @@ check_live_1 (src, x)
|| GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0);
if (GET_CODE (reg) == PARALLEL
&& GET_MODE (reg) == BLKmode)
if (GET_CODE (reg) == PARALLEL && GET_MODE (reg) == BLKmode)
{
register int i;
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
if (check_live_1 (src, XVECEXP (reg, 0, i)))
return 1;
{
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 0;
}
@ -1474,12 +1482,20 @@ update_live_1 (src, x)
|| GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0);
if (GET_CODE (reg) == PARALLEL
&& GET_MODE (reg) == BLKmode)
if (GET_CODE (reg) == PARALLEL && GET_MODE (reg) == BLKmode)
{
register int 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;
}
@ -1915,15 +1931,17 @@ haifa_classify_insn (insn)
if (tmp_class == TRAP_RISKY)
break;
/* Test if it is a load. */
tmp_class =
WORST_CLASS (tmp_class,
may_trap_exp (SET_SRC (XVECEXP (pat, 0, i)), 0));
tmp_class
= WORST_CLASS (tmp_class,
may_trap_exp (SET_SRC (XVECEXP (pat, 0, i)),
0));
break;
case COND_EXEC:
case TRAP_IF:
tmp_class = TRAP_RISKY;
break;
default:;
default:
;
}
insn_class = WORST_CLASS (insn_class, tmp_class);
if (insn_class == TRAP_RISKY || insn_class == IRISKY)