aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2014-12-01 19:28:07 +0100
committerSegher Boessenkool <segher@gcc.gnu.org>2014-12-01 19:28:07 +0100
commit9838117b0d6537073d830006db15bc981749da97 (patch)
treee7c0548ca452a22543189199a5be20d62e411fc8 /gcc
parent66d4b012463b627a233bdae5349d27dc7ea5c5bf (diff)
downloadgcc-9838117b0d6537073d830006db15bc981749da97.zip
gcc-9838117b0d6537073d830006db15bc981749da97.tar.gz
gcc-9838117b0d6537073d830006db15bc981749da97.tar.bz2
* combine.c (distribute_links): Handle multiple SETs.
From-SVN: r218242
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/combine.c52
2 files changed, 41 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bd31731..f1e029e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,9 @@
2014-12-01 Segher Boessenkool <segher@kernel.crashing.org>
+ * combine.c (distribute_links): Handle multiple SETs.
+
+2014-12-01 Segher Boessenkool <segher@kernel.crashing.org>
+
* combine.c (struct insn_link): New field `regno'.
(alloc_insn_link): New parameter `regno'. Use it.
(find_single_use): Check the new field.
diff --git a/gcc/combine.c b/gcc/combine.c
index f94d877..afcb91e 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