reorg.c (fill_simple_delay_slots): If TARGET_FLAGS_REGNUM is valid...
authorEric Botcazou <ebotcazou@adacore.com>
Sat, 17 Jan 2015 14:00:57 +0000 (14:00 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sat, 17 Jan 2015 14:00:57 +0000 (14:00 +0000)
* reorg.c (fill_simple_delay_slots): If TARGET_FLAGS_REGNUM is valid,
implement a more precise life analysis for it during backward scan.

From-SVN: r219800

gcc/ChangeLog
gcc/reorg.c

index 1efbd469e405e6489a97bb61bdc8151ac007e455..c1489923d32a1b83906da3758da1568aba90d7b9 100644 (file)
@@ -1,3 +1,8 @@
+2015-01-17  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * reorg.c (fill_simple_delay_slots): If TARGET_FLAGS_REGNUM is valid,
+       implement a more precise life analysis for it during backward scan.
+
 2015-01-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * dwarf2out.c (gen_producer_string): Ignore also OPT_fpreprocessed.
index 8f0e063f3e70edd870af04d416e84b249e14f858..05b84442f2f5a8bfa431e3dc16026f7919ebbf43 100644 (file)
@@ -2072,9 +2072,24 @@ fill_simple_delay_slots (int non_jumps_p)
 
       if (slots_filled < slots_to_fill)
        {
+         /* If the flags register is dead after the insn, then we want to be
+            able to accept a candidate that clobbers it.  For this purpose,
+            we need to filter the flags register during life analysis, so
+            that it doesn't create RAW and WAW dependencies, while still
+            creating the necessary WAR dependencies.  */
+         bool filter_flags
+           = (slots_to_fill == 1
+              && targetm.flags_regnum != INVALID_REGNUM
+              && find_regno_note (insn, REG_DEAD, targetm.flags_regnum));
+         struct resources fset;
          CLEAR_RESOURCE (&needed);
          CLEAR_RESOURCE (&set);
          mark_set_resources (insn, &set, 0, MARK_SRC_DEST);
+         if (filter_flags)
+           {
+             CLEAR_RESOURCE (&fset);
+             mark_set_resources (insn, &fset, 0, MARK_SRC_DEST);
+           }
          mark_referenced_resources (insn, &needed, false);
 
          for (trial = prev_nonnote_insn (insn); ! stop_search_p (trial, 1);
@@ -2092,7 +2107,9 @@ fill_simple_delay_slots (int non_jumps_p)
              /* Check for resource conflict first, to avoid unnecessary
                 splitting.  */
              if (! insn_references_resource_p (trial, &set, true)
-                 && ! insn_sets_resource_p (trial, &set, true)
+                 && ! insn_sets_resource_p (trial,
+                                            filter_flags ? &fset : &set,
+                                            true)
                  && ! insn_sets_resource_p (trial, &needed, true)
 #ifdef HAVE_cc0
                  /* Can't separate set of cc0 from its use.  */
@@ -2121,6 +2138,18 @@ fill_simple_delay_slots (int non_jumps_p)
                }
 
              mark_set_resources (trial, &set, 0, MARK_SRC_DEST_CALL);
+             if (filter_flags)
+               {
+                 mark_set_resources (trial, &fset, 0, MARK_SRC_DEST_CALL);
+                 /* If the flags register is set, then it doesn't create RAW
+                    dependencies any longer and it also doesn't create WAW
+                    dependencies since it's dead after the original insn.  */
+                 if (TEST_HARD_REG_BIT (fset.regs, targetm.flags_regnum))
+                   {
+                     CLEAR_HARD_REG_BIT (needed.regs, targetm.flags_regnum);
+                     CLEAR_HARD_REG_BIT (fset.regs, targetm.flags_regnum);
+                   }
+               }
              mark_referenced_resources (trial, &needed, true);
            }
        }