diff options
author | David S. Miller <davem@pierdol.cobaltmicro.com> | 1998-09-12 01:03:36 +0000 |
---|---|---|
committer | David S. Miller <davem@gcc.gnu.org> | 1998-09-11 18:03:36 -0700 |
commit | 86465af7347851ef4d3473eabb4c7088b5443e6d (patch) | |
tree | 6a94719da1d0636b9e8e23c1c16030b3eb36f44a /gcc/flow.c | |
parent | b5754a68c62048dc0e0dd34afbe5a99a3df042f9 (diff) | |
download | gcc-86465af7347851ef4d3473eabb4c7088b5443e6d.zip gcc-86465af7347851ef4d3473eabb4c7088b5443e6d.tar.gz gcc-86465af7347851ef4d3473eabb4c7088b5443e6d.tar.bz2 |
flow.c (mark_set_1): Recognize multi-register structure return values in CALL insns.
* flow.c (mark_set_1): Recognize multi-register structure return
values in CALL insns.
(mark_used_regs): Likewise.
(count_reg_sets_1): Likewise.
(count_reg_references): Likewise.
* rtlanal.c (note_stores): Likewise.
From-SVN: r22395
Diffstat (limited to 'gcc/flow.c')
-rw-r--r-- | gcc/flow.c | 38 |
1 files changed, 32 insertions, 6 deletions
@@ -2133,6 +2133,19 @@ mark_set_1 (needed, dead, x, insn, significant) register int regno; register rtx reg = SET_DEST (x); + /* 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) + { + register int i; + + for (i = XVECLEN (reg, 0) - 1; i >= 0; i--) + mark_set_1 (needed, dead, XVECEXP (reg, 0, i), insn, significant); + 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. @@ -2794,15 +2807,17 @@ mark_used_regs (needed, live, x, final, insn) /* If this is a store into a register, recursively scan the value being stored. */ - if (GET_CODE (testreg) == REG - && (regno = REGNO (testreg), regno != FRAME_POINTER_REGNUM) + if ((GET_CODE (testreg) == PARALLEL + && GET_MODE (testreg) == BLKmode) + || (GET_CODE (testreg) == REG + && (regno = REGNO (testreg), regno != FRAME_POINTER_REGNUM) #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM - && regno != HARD_FRAME_POINTER_REGNUM + && regno != HARD_FRAME_POINTER_REGNUM #endif #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM - && ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno]) + && ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno]) #endif - ) + )) /* We used to exclude global_regs here, but that seems wrong. Storing in them is like storing in mem. */ { @@ -4043,6 +4058,15 @@ count_reg_sets_1 (x) || GET_CODE (reg) == STRICT_LOW_PART) reg = XEXP (reg, 0); + if (GET_CODE (reg) == PARALLEL + && GET_MODE (reg) == BLKmode) + { + register int i; + for (i = XVECLEN (reg, 0) - 1; i >= 0; i--) + count_reg_sets_1 (XVECEXP (reg, 0, i)); + return; + } + if (GET_CODE (reg) == REG) { regno = REGNO (reg); @@ -4175,7 +4199,9 @@ count_reg_references (x) /* If this is a store into a register, recursively scan the value being stored. */ - if (GET_CODE (testreg) == REG) + if ((GET_CODE (testreg) == PARALLEL + && GET_MODE (testreg) == BLKmode) + || GET_CODE (testreg) == REG) { count_reg_references (SET_SRC (x)); if (mark_dest) |