OSDN Git Service

2000-09-15 Andrew Haley <aph@redhat.com>
authoraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 18 Sep 2000 19:27:37 +0000 (19:27 +0000)
committeraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 18 Sep 2000 19:27:37 +0000 (19:27 +0000)
        * 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36511 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/function.c
gcc/rtl.h
gcc/toplev.c

index 4c0edc7..4e99ee9 100644 (file)
@@ -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.
index 6a9bdc9..969887f 100644 (file)
@@ -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 ());
 }
 \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.  */
 
index a866595..190e971 100644 (file)
--- 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));
index 333cde6..74e0e3e 100644 (file)
@@ -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;