diff options
author | Andrew Haley <aph@redhat.com> | 2000-09-18 19:27:37 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 2000-09-18 19:27:37 +0000 |
commit | 659e47fb241303d55e264111360d41aa132947e1 (patch) | |
tree | 614e4aa4487dc0588a17968047aee0e298b20627 /gcc/function.c | |
parent | f2f90c63c8832dcf581120672567453b8e062d7a (diff) | |
download | gcc-659e47fb241303d55e264111360d41aa132947e1.zip gcc-659e47fb241303d55e264111360d41aa132947e1.tar.gz gcc-659e47fb241303d55e264111360d41aa132947e1.tar.bz2 |
toplev.c (rest_of_compilation): Call purge_hard_subreg_sets to remove all SETs of SUBREGs of hard registers.
2000-09-15 Andrew Haley <aph@redhat.com>
* toplev.c (rest_of_compilation): Call purge_hard_subreg_sets to
remove all SETs of SUBREGs of hard registers.
* function.c (purge_hard_subreg_sets): New function.
(purge_single_hard_subreg_set): New function.
* rtl.h: (purge_hard_subreg_sets): New function.
From-SVN: r36511
Diffstat (limited to 'gcc/function.c')
-rw-r--r-- | gcc/function.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/gcc/function.c b/gcc/function.c index 6a9bdc9..969887f 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -294,6 +294,7 @@ static void emit_return_into_block PARAMS ((basic_block, rtx)); static void put_addressof_into_stack PARAMS ((rtx, struct hash_table *)); static boolean purge_addressof_1 PARAMS ((rtx *, rtx, int, int, struct hash_table *)); +static void purge_single_hard_subreg_set PARAMS ((rtx)); #ifdef HAVE_epilogue static void keep_stack_depressed PARAMS ((rtx)); #endif @@ -3393,6 +3394,71 @@ purge_addressof (insns) unshare_all_rtl_again (get_insns ()); } +/* Convert a SET of a hard subreg to a set of the appropriet hard + register. A subroutine of purge_hard_subreg_sets. */ + +static void +purge_single_hard_subreg_set (pattern) + rtx pattern; +{ + rtx reg = SET_DEST (pattern); + enum machine_mode mode = GET_MODE (SET_DEST (pattern)); + int word = 0; + + while (GET_CODE (reg) == SUBREG) + { + word += SUBREG_WORD (reg); + reg = SUBREG_REG (reg); + } + + if (REGNO (reg) < FIRST_PSEUDO_REGISTER) + { + reg = gen_rtx_REG (mode, REGNO (reg) + word); + SET_DEST (pattern) = reg; + } +} + +/* Eliminate all occurrences of SETs of hard subregs from INSNS. The + only such SETs that we expect to see are those left in because + integrate can't handle sets of parts of a return value register. + + We don't use alter_subreg because we only want to eliminate subregs + of hard registers. */ + +void +purge_hard_subreg_sets (insn) + rtx insn; +{ + for (; insn; insn = NEXT_INSN (insn)) + { + if (INSN_P (insn)) + { + rtx pattern = PATTERN (insn); + switch (GET_CODE (pattern)) + { + case SET: + if (GET_CODE (SET_DEST (pattern)) == SUBREG) + purge_single_hard_subreg_set (pattern); + break; + case PARALLEL: + { + int j; + for (j = XVECLEN (pattern, 0) - 1; j >= 0; j--) + { + rtx inner_pattern = XVECEXP (pattern, 0, j); + if (GET_CODE (inner_pattern) == SET + && GET_CODE (SET_DEST (inner_pattern)) == SUBREG) + purge_single_hard_subreg_set (inner_pattern); + } + } + break; + default: + break; + } + } + } +} + /* Pass through the INSNS of function FNDECL and convert virtual register references to hard register references. */ |