diff mbox

[2/6] combine: distribute_log_links for PARALLELs of SETs

Message ID b862dbe8d04d96eeccf34576c001dae81647ce2a.1417135737.git.segher@kernel.crashing.org
State New
Headers show

Commit Message

Segher Boessenkool Nov. 28, 2014, 1:44 a.m. UTC
Now that LOG_LINKS are per regno, we can distribute them on PARALLELs
just fine.  Do so.  This makes PARALLELs not lose their LOG_LINKS early
when e.g. a trivial reg-reg move is combined, so that they can be used
in more useful combinations as well.


2014-11-27  Segher Boessenkool  <segher@kernel.crashing.org>

gcc/
	* combine.c (distribute_links): Handle multiple SETs.

---
 gcc/combine.c | 52 +++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 37 insertions(+), 15 deletions(-)

Comments

Jeff Law Dec. 1, 2014, 5:42 p.m. UTC | #1
On 11/27/14 18:44, Segher Boessenkool wrote:
> Now that LOG_LINKS are per regno, we can distribute them on PARALLELs
> just fine.  Do so.  This makes PARALLELs not lose their LOG_LINKS early
> when e.g. a trivial reg-reg move is combined, so that they can be used
> in more useful combinations as well.
>
>
> 2014-11-27  Segher Boessenkool  <segher@kernel.crashing.org>
>
> gcc/
> 	* combine.c (distribute_links): Handle multiple SETs.
OK.
jeff
diff mbox

Patch

diff --git a/gcc/combine.c b/gcc/combine.c
index 9b53a93..7e3f4e6 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -13817,24 +13817,46 @@  distribute_links (struct insn_link *links)
 
       next_link = link->next;
 
-      /* If the insn that this link points to is a NOTE or isn't a single
-	 set, ignore it.  In the latter case, it isn't clear what we
-	 can do other than ignore the link, since we can't tell which
-	 register it was for.  Such links wouldn't be used by combine
-	 anyway.
-
-	 It is not possible for the destination of the target of the link to
-	 have been changed by combine.  The only potential of this is if we
-	 replace I3, I2, and I1 by I3 and I2.  But in that case the
-	 destination of I2 also remains unchanged.  */
-
-      if (NOTE_P (link->insn)
-	  || (set = single_set (link->insn)) == 0)
+      /* If the insn that this link points to is a NOTE, ignore it.  */
+      if (NOTE_P (link->insn))
+	continue;
+
+      set = 0;
+      rtx pat = PATTERN (link->insn);
+      if (GET_CODE (pat) == SET)
+	set = pat;
+      else if (GET_CODE (pat) == PARALLEL)
+	{
+	  int i;
+	  for (i = 0; i < XVECLEN (pat, 0); i++)
+	    {
+	      set = XVECEXP (pat, 0, i);
+	      if (GET_CODE (set) != SET)
+		continue;
+
+	      reg = SET_DEST (set);
+	      while (GET_CODE (reg) == ZERO_EXTRACT
+		     || GET_CODE (reg) == STRICT_LOW_PART
+		     || GET_CODE (reg) == SUBREG)
+		reg = XEXP (reg, 0);
+
+	      if (!REG_P (reg))
+		continue;
+
+	      if (REGNO (reg) == link->regno)
+		break;
+	    }
+	  if (i == XVECLEN (pat, 0))
+	    continue;
+	}
+      else
 	continue;
 
       reg = SET_DEST (set);
-      while (GET_CODE (reg) == SUBREG || GET_CODE (reg) == ZERO_EXTRACT
-	     || GET_CODE (reg) == STRICT_LOW_PART)
+
+      while (GET_CODE (reg) == ZERO_EXTRACT
+	     || GET_CODE (reg) == STRICT_LOW_PART
+	     || GET_CODE (reg) == SUBREG)
 	reg = XEXP (reg, 0);
 
       /* A LOG_LINK is defined as being placed on the first insn that uses