gcse.c (hash_scan_set): Do not pick up a REG_EQUAL value if SRC is a REG.
authorSteven Bosscher <stevenb.gcc@gmail.com>
Sun, 25 May 2008 11:58:18 +0000 (11:58 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Sun, 25 May 2008 11:58:18 +0000 (11:58 +0000)
2008-05-25  Steven Bosscher  <stevenb.gcc@gmail.com>

* gcse.c (hash_scan_set): Do not pick up a REG_EQUAL value if
SRC is a REG.

From-SVN: r135860

gcc/ChangeLog
gcc/gcse.c

index 5c4a0b3ebdb4688d186ab0f657c8bba16cb955d5..0588af6fc5a57fddca99166e72c6518213d6de46 100644 (file)
@@ -1,3 +1,8 @@
+2008-05-25  Steven Bosscher  <stevenb.gcc@gmail.com>
+
+       * gcse.c (hash_scan_set): Do not pick up a REG_EQUAL value if
+       SRC is a REG.
+
 2008-05-25  Alan Modra  <amodra@bigpond.net.au>
 
        * c-common.c (strip_array_types): Move function to..
index 77efc44769bc981a4268f1253269874854970d1f..f6837bf1f606493ff61c5d0ae2a4f64e31a828bd 100644 (file)
@@ -1692,12 +1692,25 @@ hash_scan_set (rtx pat, rtx insn, struct hash_table *table)
       unsigned int regno = REGNO (dest);
       rtx tmp;
 
-      /* See if a REG_NOTE shows this equivalent to a simpler expression.
+      /* See if a REG_EQUAL note shows this equivalent to a simpler expression.
+
         This allows us to do a single GCSE pass and still eliminate
         redundant constants, addresses or other expressions that are
-        constructed with multiple instructions.  */
+        constructed with multiple instructions.
+
+        However, keep the original SRC if INSN is a simple reg-reg move.  In
+        In this case, there will almost always be a REG_EQUAL note on the
+        insn that sets SRC.  By recording the REG_EQUAL value here as SRC
+        for INSN, we miss copy propagation opportunities and we perform the
+        same PRE GCSE operation repeatedly on the same REG_EQUAL value if we
+        do more than one PRE GCSE pass.
+
+        Note that this does not impede profitale constant propagations.  We
+        "look through" reg-reg sets in lookup_avail_set.  */
       note = find_reg_equal_equiv_note (insn);
       if (note != 0
+         && REG_NOTE_KIND (note) == REG_EQUAL
+         && !REG_P (src)
          && (table->set_p
              ? gcse_constant_p (XEXP (note, 0))
              : want_to_gcse_p (XEXP (note, 0))))