aboutsummaryrefslogtreecommitdiff
path: root/gcc
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
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')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/function.c66
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/toplev.c11
4 files changed, 82 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4c0edc7..4e99ee9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+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.
+
2000-09-18 Richard Henderson <rth@cygnus.com>
* config/ia64/ia64-protos.h: Update.
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. */
diff --git a/gcc/rtl.h b/gcc/rtl.h
index a866595..190e971 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1776,6 +1776,7 @@ extern void preserve_rtl_expr_result PARAMS ((rtx));
extern void mark_temp_addr_taken PARAMS ((rtx));
extern void update_temp_slot_address PARAMS ((rtx, rtx));
extern void purge_addressof PARAMS ((rtx));
+extern void purge_hard_subreg_sets PARAMS ((rtx));
/* In reload.c */
extern int operands_match_p PARAMS ((rtx, rtx));
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 333cde6..74e0e3eb 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -2829,11 +2829,14 @@ rest_of_compilation (decl)
if (! DECL_DEFER_OUTPUT (decl))
TREE_ASM_WRITTEN (decl) = 1;
- /* Now that integrate will no longer see our rtl, we need not distinguish
- between the return value of this function and the return value of called
- functions. */
+ /* Now that integrate will no longer see our rtl, we need not
+ distinguish between the return value of this function and the
+ return value of called functions. Also, we can remove all SETs
+ of subregs of hard registers; they are only here because of
+ integrate.*/
rtx_equal_function_value_matters = 0;
-
+ purge_hard_subreg_sets (get_insns ());
+
/* Don't return yet if -Wreturn-type; we need to do jump_optimize. */
if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)
goto exit_rest_of_compilation;