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> 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>

View File

@ -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)

View File

@ -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)) {
return 1; rtx reg = XVECEXP (x, 0, i);
return 0;
if (GET_CODE (reg) == EXPR_LIST)
reg = XEXP (reg, 0);
if (reg_overlap_mentioned_p (reg, in))
return 1;
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. */
for (i = XVECLEN (dest, 0) - 1; i >= 0; i--) if (GET_CODE (dest) == PARALLEL && GET_MODE (dest) == BLKmode)
(*fun) (SET_DEST (XVECEXP (dest, 0, i)), x, data); 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 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.

View File

@ -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;

View File

@ -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))) {
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; 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)