Regrename tends to fall on its face if multiword registers are accessed
both in their full width and in subparts. However, there's one case
where it's relatively easy to improve the current situation - when
tracking a wide register, and it's written to in a narrower mode, we can
just close the chain, mark it as non-renameable, and move every involved
register to live_hardregs.

Bootstrapped and tested along with the earlier REG_DEAD patch. I've been
testing these and other changes in a 4.5 C6X tree as well.


Bernd
        * regrename.c (scan_rtx_reg): Handle the case where we write to an
        open chain in a smaller mode without failing the entire block.

Index: gcc/regrename.c
===================================================================
--- gcc/regrename.c     (revision 174842)
+++ gcc/regrename.c     (working copy)
@@ -753,25 +721,34 @@ scan_rtx_reg (rtx insn, rtx *loc, enum r
         In either case, we remove this element from open_chains.  */
 
       if ((action == terminate_dead || action == terminate_write)
-         && superset)
+         && (superset || subset))
        {
          unsigned nregs;
 
          head->terminated = 1;
+         if (subset)
+           head->cannot_rename = 1;
          head->next_chain = closed_chains;
          closed_chains = head;
          bitmap_clear_bit (&open_chains_set, head->id);
 
          nregs = head->nregs;
          while (nregs-- > 0)
-           CLEAR_HARD_REG_BIT (live_in_chains, head->regno + nregs);
+           {
+             CLEAR_HARD_REG_BIT (live_in_chains, head->regno + nregs);
+             if (subset
+                 && (head->regno + nregs < this_regno
+                     || head->regno + nregs >= this_regno + this_nregs))
+               SET_HARD_REG_BIT (live_hard_regs, head->regno + nregs);
+           }
 
          *p = next;
          if (dump_file)
            fprintf (dump_file,
-                    "Closing chain %s (%d) at insn %d (%s)\n",
+                    "Closing chain %s (%d) at insn %d (%s%s)\n",
                     reg_names[head->regno], head->id, INSN_UID (insn),
-                    scan_actions_name[(int) action]);
+                    scan_actions_name[(int) action],
+                    superset ? ", superset" : subset ? ", subset" : "");
        }
       else if (action == terminate_dead || action == terminate_write)
        {

Reply via email to