+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.
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
unshare_all_rtl_again (get_insns ());
}
\f
+/* 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;
+ }
+ }
+ }
+}
+\f
/* Pass through the INSNS of function FNDECL and convert virtual register
references to hard register references. */
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;