aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2016-04-30 09:28:17 +0930
committerAlan Modra <amodra@gcc.gnu.org>2016-04-30 09:28:17 +0930
commit10e044468a4e0599c4f52ced069d39bbef8bee62 (patch)
tree469249cb2530cae37ba53bdb8bff82d185b6d2ac
parentc7a99fc66328d85bcda9eb1625143e8e7b20e533 (diff)
downloadgcc-10e044468a4e0599c4f52ced069d39bbef8bee62.zip
gcc-10e044468a4e0599c4f52ced069d39bbef8bee62.tar.gz
gcc-10e044468a4e0599c4f52ced069d39bbef8bee62.tar.bz2
ira.c combine_and_move_insns, and ordering of functions
Notes added by add_store_equivs are not used directly or indirectly by combine_and_move_insns. add_store_equivs can therefore run later without affecting the output of combine_and_move_insns, and thus add_store_equivs need not take into account potentially moved insns. Since not all potentially combined/moved insns are in fact combined or moved, this may allow add_store_equivs to add more REG_EQUIV notes. grow_reg_equivs isn't needed until the reload reg_equivs array is changed. ira.c (combine_and_move_insns): Move invariant conditions.. (ira.c): ..to here. Call combine_and_move_insns before add_store_equivs. Call grow_reg_equivs later. Allocate req_equiv later using max_reg_num() rather than global max_regno. (contains_replace_regs): Delete. (add_store_equivs): Remove contains_replace_regs test. From-SVN: r235659
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/ira.c84
2 files changed, 25 insertions, 68 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 47b86f1..fca7901 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,14 @@
2016-04-30 Alan Modra <amodra@gmail.com>
+ ira.c (combine_and_move_insns): Move invariant conditions..
+ (ira.c): ..to here. Call combine_and_move_insns before
+ add_store_equivs. Call grow_reg_equivs later. Allocate
+ req_equiv later using max_reg_num() rather than global max_regno.
+ (contains_replace_regs): Delete.
+ (add_store_equivs): Remove contains_replace_regs test.
+
+2016-04-30 Alan Modra <amodra@gmail.com>
+
* ira.c (struct equiv_mem_data): New.
(equiv_mem, equiv_mem_modified): Delete static vars.
(validate_equiv_mem_from_store): Use "data" param to communicate..
diff --git a/gcc/ira.c b/gcc/ira.c
index 8ef780a..91225f6 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -3120,51 +3120,6 @@ equiv_init_movable_p (rtx x, int regno)
return 1;
}
-/* TRUE if X uses any registers for which reg_equiv[REGNO].replace is
- true. */
-static int
-contains_replace_regs (rtx x)
-{
- int i, j;
- const char *fmt;
- enum rtx_code code = GET_CODE (x);
-
- switch (code)
- {
- case CONST:
- case LABEL_REF:
- case SYMBOL_REF:
- CASE_CONST_ANY:
- case PC:
- case CC0:
- case HIGH:
- return 0;
-
- case REG:
- return reg_equiv[REGNO (x)].replace;
-
- default:
- break;
- }
-
- fmt = GET_RTX_FORMAT (code);
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- switch (fmt[i])
- {
- case 'e':
- if (contains_replace_regs (XEXP (x, i)))
- return 1;
- break;
- case 'E':
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- if (contains_replace_regs (XVECEXP (x, i, j)))
- return 1;
- break;
- }
-
- return 0;
-}
-
/* TRUE if X references a memory location that would be affected by a store
to MEMREF. */
static int
@@ -3634,13 +3589,7 @@ add_store_equivs (void)
src = SET_SRC (set);
/* Don't add a REG_EQUIV note if the insn already has one. The existing
- REG_EQUIV is likely more useful than the one we are adding.
-
- If one of the regs in the address has reg_equiv[REGNO].replace set,
- then we can't add this REG_EQUIV note. The reg_equiv[REGNO].replace
- optimization may move the set of this register immediately before
- insn, which puts it after reg_equiv[REGNO].init_insns, and hence the
- mention in the REG_EQUIV note would be to an uninitialized pseudo. */
+ REG_EQUIV is likely more useful than the one we are adding. */
if (MEM_P (dest) && REG_P (src)
&& (regno = REGNO (src)) >= FIRST_PSEUDO_REGISTER
&& REG_BASIC_BLOCK (regno) >= NUM_FIXED_BLOCKS
@@ -3650,7 +3599,6 @@ add_store_equivs (void)
&& (init_insn = reg_equiv[regno].init_insns->insn ()) != 0
&& bitmap_bit_p (&seen_insns, INSN_UID (init_insn))
&& ! find_reg_note (init_insn, REG_EQUIV, NULL_RTX)
- && ! contains_replace_regs (XEXP (dest, 0))
&& validate_equiv_mem (init_insn, src, dest)
&& ! memref_used_between_p (dest, init_insn, insn)
/* Attaching a REG_EQUIV note will fail if INIT_INSN has
@@ -3714,14 +3662,7 @@ combine_and_move_insns (void)
rtx equiv_insn;
if (! reg_equiv[regno].replace
- || reg_equiv[regno].loop_depth < (short) loop_depth
- /* There is no sense to move insns if live range
- shrinkage or register pressure-sensitive
- scheduling were done because it will not
- improve allocation but worsen insn schedule
- with a big probability. */
- || flag_live_range_shrinkage
- || (flag_sched_pressure && flag_schedule_insns))
+ || reg_equiv[regno].loop_depth < (short) loop_depth)
continue;
/* reg_equiv[REGNO].replace gets set only when
@@ -5222,20 +5163,27 @@ ira (FILE *f)
if (resize_reg_info () && flag_ira_loop_pressure)
ira_set_pseudo_classes (true, ira_dump_file);
- reg_equiv = XCNEWVEC (struct equivalence, max_regno);
- grow_reg_equivs ();
init_alias_analysis ();
+ reg_equiv = XCNEWVEC (struct equivalence, max_reg_num ());
update_equiv_regs ();
+
+ /* Don't move insns if live range shrinkage or register
+ pressure-sensitive scheduling were done because it will not
+ improve allocation but likely worsen insn scheduling. */
+ if (optimize
+ && !flag_live_range_shrinkage
+ && !(flag_sched_pressure && flag_schedule_insns))
+ combine_and_move_insns ();
+
+ /* Gather additional equivalences with memory. */
if (optimize)
- {
- /* Gather additional equivalences with memory. */
- add_store_equivs ();
- combine_and_move_insns ();
- }
+ add_store_equivs ();
+
end_alias_analysis ();
free (reg_equiv);
setup_reg_equiv ();
+ grow_reg_equivs ();
setup_reg_equiv_init ();
allocated_reg_info_size = max_reg_num ();