diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2015-01-17 14:00:57 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2015-01-17 14:00:57 +0000 |
commit | 33c2207d3fda2956ac036f306fc8bfc58b635da0 (patch) | |
tree | ac4ece778c84c9eedff72876de37513ec1cc220d /gcc/reorg.c | |
parent | c6c1bfd99bbe6789b88f59c90c753206ca1cd3fd (diff) | |
download | gcc-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.c | 31 |
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); } } |