aboutsummaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authorAndrew Haley <aph@redhat.com>2000-09-18 19:27:37 +0000
committerAndrew Haley <aph@gcc.gnu.org>2000-09-18 19:27:37 +0000
commit659e47fb241303d55e264111360d41aa132947e1 (patch)
tree614e4aa4487dc0588a17968047aee0e298b20627 /gcc/function.c
parentf2f90c63c8832dcf581120672567453b8e062d7a (diff)
downloadgcc-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.c66
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. */