aboutsummaryrefslogtreecommitdiff
path: root/gcc/reorg.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2015-01-17 14:00:57 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2015-01-17 14:00:57 +0000
commit33c2207d3fda2956ac036f306fc8bfc58b635da0 (patch)
treeac4ece778c84c9eedff72876de37513ec1cc220d /gcc/reorg.c
parentc6c1bfd99bbe6789b88f59c90c753206ca1cd3fd (diff)
downloadgcc-33c2207d3fda2956ac036f306fc8bfc58b635da0.zip
gcc-33c2207d3fda2956ac036f306fc8bfc58b635da0.tar.gz
gcc-33c2207d3fda2956ac036f306fc8bfc58b635da0.tar.bz2
reorg.c (fill_simple_delay_slots): If TARGET_FLAGS_REGNUM is valid...
* 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
Diffstat (limited to 'gcc/reorg.c')
-rw-r--r--gcc/reorg.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/gcc/reorg.c b/gcc/reorg.c
index 8f0e063..05b8444 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -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);
}
}