final.c (cleanup_subreg_operands): New function.
authorJeffrey A Law <law@cygnus.com>
Tue, 27 Oct 1998 23:19:31 +0000 (23:19 +0000)
committerJeff Law <law@gcc.gnu.org>
Tue, 27 Oct 1998 23:19:31 +0000 (16:19 -0700)
        * final.c (cleanup_subreg_operands): New function.
        (final_scan_insn): Use it.
        (alter_subreg): Clear the "used" field when we turn a SUBREG into
        a REG.
        * reload1.c (reload): Delete CLOBBER insns and also cleanup SUBREG
        operands when reload has finished.
        * reload.h (cleanup_subreg_operands): Declare..
        * flow.c (life_analysis_1): No longer delete CLOBBER insns after
        reload.  Handled in reload itself.
Should fix sh, sparc and probably other problems with post-reload life pass
and scheduling interactions.

From-SVN: r23377

gcc/ChangeLog
gcc/final.c
gcc/flow.c
gcc/reload.h
gcc/reload1.c

index 4cab3de6c71dd5dbd83756a2b7dbfaf757589beb..23af1029d6667a2d85602ba0d98b0754c801c1e7 100644 (file)
@@ -1,3 +1,15 @@
+Wed Oct 28 00:10:35 1998  Jeffrey A Law  (law@cygnus.com)
+
+       * final.c (cleanup_subreg_operands): New function.
+       (final_scan_insn): Use it.
+       (alter_subreg): Clear the "used" field when we turn a SUBREG into
+       a REG.
+       * reload1.c (reload): Delete CLOBBER insns and also cleanup SUBREG
+       operands when reload has finished.
+       * reload.h (cleanup_subreg_operands): Declare..
+       * flow.c (life_analysis_1): No longer delete CLOBBER insns after
+       reload.  Handled in reload itself.
+
 Tue Oct 27 23:32:34 1998  Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
 
        * reload.h (struct insn_chain): Add need_operand_change element.
index 5b7874e75876596a829c13cc029e013ec206dd47..4c19c84a9fdd1ca00fd020234d46b6e131bae577 100644 (file)
@@ -2844,23 +2844,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
 
        insn_code_number = recog_memoized (insn);
        insn_extract (insn);
-       for (i = 0; i < insn_n_operands[insn_code_number]; i++)
-         {
-           if (GET_CODE (recog_operand[i]) == SUBREG)
-             recog_operand[i] = alter_subreg (recog_operand[i]);
-           else if (GET_CODE (recog_operand[i]) == PLUS
-                    || GET_CODE (recog_operand[i]) == MULT)
-             recog_operand[i] = walk_alter_subreg (recog_operand[i]);
-         }
-
-       for (i = 0; i < insn_n_dups[insn_code_number]; i++)
-         {
-           if (GET_CODE (*recog_dup_loc[i]) == SUBREG)
-             *recog_dup_loc[i] = alter_subreg (*recog_dup_loc[i]);
-           else if (GET_CODE (*recog_dup_loc[i]) == PLUS
-                    || GET_CODE (*recog_dup_loc[i]) == MULT)
-             *recog_dup_loc[i] = walk_alter_subreg (*recog_dup_loc[i]);
-         }
+       cleanup_subreg_operands (insn);
 
 #ifdef REGISTER_CONSTRAINTS
        if (! constrain_operands (insn_code_number, 1))
@@ -3039,6 +3023,49 @@ output_source_line (file, insn)
     }
 }
 \f
+
+/* For each operand in INSN, simplify (subreg (reg)) so that it refers
+   directly to the desired hard register.  */
+void
+cleanup_subreg_operands (insn)
+     rtx insn;
+{
+  int insn_code_number, i;
+
+  /* Ignore things we can not handle.  */
+  if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
+      || GET_CODE (PATTERN (insn)) == USE
+      || GET_CODE (PATTERN (insn)) == ADDR_VEC
+      || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
+      || asm_noperands (PATTERN (insn)) >= 0)
+    return;
+
+  /* Try to recognize the instruction.
+     If successful, verify that the operands satisfy the
+     constraints for the instruction.  Crash if they don't,
+     since `reload' should have changed them so that they do.  */
+
+  insn_code_number = recog_memoized (insn);
+  insn_extract (insn);
+  for (i = 0; i < insn_n_operands[insn_code_number]; i++)
+    {
+      if (GET_CODE (recog_operand[i]) == SUBREG)
+        recog_operand[i] = alter_subreg (recog_operand[i]);
+      else if (GET_CODE (recog_operand[i]) == PLUS
+               || GET_CODE (recog_operand[i]) == MULT)
+       recog_operand[i] = walk_alter_subreg (recog_operand[i]);
+    }
+
+  for (i = 0; i < insn_n_dups[insn_code_number]; i++)
+    {
+      if (GET_CODE (*recog_dup_loc[i]) == SUBREG)
+        *recog_dup_loc[i] = alter_subreg (*recog_dup_loc[i]);
+      else if (GET_CODE (*recog_dup_loc[i]) == PLUS
+               || GET_CODE (*recog_dup_loc[i]) == MULT)
+        *recog_dup_loc[i] = walk_alter_subreg (*recog_dup_loc[i]);
+    }
+}
+
 /* If X is a SUBREG, replace it with a REG or a MEM,
    based on the thing it is a subreg of.  */
 
@@ -3072,6 +3099,9 @@ alter_subreg (x)
 #else
       REGNO (x) = REGNO (y) + SUBREG_WORD (x);
 #endif
+      /* This field has a different meaning for REGs and SUBREGs.  Make sure
+        to clear it!  */
+      x->used = 0;
     }
   else if (GET_CODE (y) == MEM)
     {
index 3fecc85713efdf10b392cbb37df042ee0b039536..51af041506e1a2fb9a0911baca1468711dacd943 100644 (file)
@@ -1358,23 +1358,6 @@ life_analysis_1 (f, nregs)
   if (reload_completed)
     bcopy (regs_ever_live, save_regs_ever_live, (sizeof (regs_ever_live)));
 
-  /* Also remove all CLOBBER insns after reload.  They can cause us to think
-     a value is dead when it really is not dead.  */
-  if (reload_completed)
-    {
-      rtx insn;
-
-      for (insn = f; insn; insn = NEXT_INSN (insn))
-       {
-         if (GET_CODE (insn) == INSN
-             && GET_CODE (PATTERN (insn)) == CLOBBER)
-           {
-              PUT_CODE (insn, NOTE);
-              NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
-              NOTE_SOURCE_FILE (insn) = 0;
-           }
-       }
-    }
   bzero (regs_ever_live, sizeof regs_ever_live);
 
   /* Allocate and zero out many data structures
index 5606a4ee74cb5e960353c3648713e27412b7fff2..968d3124af49a54b6c2f008a33e39f49aabc8473 100644 (file)
@@ -339,3 +339,6 @@ extern void setup_save_areas PROTO((void));
 
 /* Find the places where hard regs are live across calls and save them.  */
 extern void save_call_clobbered_regs PROTO((void));
+
+/* Replace (subreg (reg)) with the appropriate (reg) for any operands.  */
+extern void cleanup_subreg_operands PROTO ((rtx));
index ae0eb77137175163ce538b24e6b77c0d05b69468..7e702d30733295d681052743c1726f82a35aa91d 100644 (file)
@@ -1037,16 +1037,17 @@ reload (first, global, dumpfile)
     }
 
   /* Make a pass over all the insns and delete all USEs which we inserted
-     only to tag a REG_EQUAL note on them.  Also remove all REG_DEAD and
-     REG_UNUSED notes.  */
+     only to tag a REG_EQUAL note on them.  Remove all REG_DEAD and REG_UNUSED
+     notes.  Delete all CLOBBER insns and simplify (subreg (reg)) operands.  */
 
   for (insn = first; insn; insn = NEXT_INSN (insn))
     if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
       {
        rtx *pnote;
 
-       if (GET_CODE (PATTERN (insn)) == USE
-           && find_reg_note (insn, REG_EQUAL, NULL_RTX))
+       if ((GET_CODE (PATTERN (insn)) == USE
+            && find_reg_note (insn, REG_EQUAL, NULL_RTX))
+           || GET_CODE (PATTERN (insn)) == CLOBBER)
          {
            PUT_CODE (insn, NOTE);
            NOTE_SOURCE_FILE (insn) = 0;
@@ -1063,6 +1064,9 @@ reload (first, global, dumpfile)
            else
              pnote = &XEXP (*pnote, 1);
          }
+
+       /* And simplify (subreg (reg)) if it appears as an operand.  */
+       cleanup_subreg_operands (insn);
       }
 
   /* If we are doing stack checking, give a warning if this function's