diff mbox

Fail entire blocks less often in regrename.c

Message ID 4DFA15A2.50105@codesourcery.com
State New
Headers show

Commit Message

Bernd Schmidt June 16, 2011, 2:39 p.m. UTC
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.

Comments

Bernd Schmidt June 16, 2011, 3:16 p.m. UTC | #1
On 06/16/2011 04:39 PM, Bernd Schmidt wrote:
> +	  if (subset)
> +	    head->cannot_rename = 1;

I confused myself here by having too many trees, and tested & posted an
old version the patch. This (and another instance) needs to read (subset
&& !superset) since these aren't strict super-/subsets.

I'll retest with that change - it works on 4.5 c6x-elf.


Bernd
Richard Henderson June 16, 2011, 3:20 p.m. UTC | #2
On 06/16/2011 07:39 AM, Bernd Schmidt wrote:
> 	* regrename.c (scan_rtx_reg): Handle the case where we write to an
> 	open chain in a smaller mode without failing the entire block.

Ok.


r~
diff mbox

Patch

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)
 	{