diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6848e8ec0d5..51cb1866feb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ Thu Jan 18 06:43:04 2001 Richard Kenner + * 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 diff --git a/gcc/flow.c b/gcc/flow.c index 4d0bdff92ed..aa37d05de56 100644 --- a/gcc/flow.c +++ b/gcc/flow.c @@ -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) diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 8bdd23cdfc2..eec8b6af501 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -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. diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index 67ea68bedf3..9b566a0ec26 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -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; diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c index 46c734cf7da..71c4018bb1c 100644 --- a/gcc/sched-rgn.c +++ b/gcc/sched-rgn.c @@ -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)