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>
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:
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)
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:
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))
|| 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);
}
\f
/* Return nonzero if X's old contents don't survive after 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;
|| 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;
}
|| 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;
}
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)