/* Coalesce spilled pseudos.
- Copyright (C) 2010, 2011, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 2010-2015 Free Software Foundation, Inc.
Contributed by Vladimir Makarov <vmakarov@redhat.com>.
This file is part of GCC.
#include "hard-reg-set.h"
#include "flags.h"
#include "function.h"
+#include "symtab.h"
+#include "alias.h"
+#include "tree.h"
+#include "expmed.h"
+#include "dojump.h"
+#include "explow.h"
+#include "calls.h"
+#include "emit-rtl.h"
+#include "varasm.h"
+#include "stmt.h"
#include "expr.h"
+#include "predict.h"
+#include "dominance.h"
+#include "cfg.h"
#include "basic-block.h"
#include "except.h"
#include "timevar.h"
#include "ira.h"
+#include "alloc-pool.h"
#include "lra-int.h"
#include "df.h"
static int
move_freq_compare_func (const void *v1p, const void *v2p)
{
- rtx mv1 = *(const rtx *) v1p;
- rtx mv2 = *(const rtx *) v2p;
+ rtx_insn *mv1 = *(rtx_insn * const *) v1p;
+ rtx_insn *mv2 = *(rtx_insn * const *) v2p;
int pri1, pri2;
-
- pri1 = BLOCK_FOR_INSN (mv1)->frequency;
- pri2 = BLOCK_FOR_INSN (mv2)->frequency;
+
+ pri1 = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (mv1));
+ pri2 = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (mv2));
if (pri2 - pri1)
return pri2 - pri1;
return res;
}
+/* Specialize "substitute" for use on an insn. This can't change
+ the insn ptr, just the contents of the insn. */
+
+static bool
+substitute_within_insn (rtx_insn *insn)
+{
+ rtx loc = insn;
+ return substitute (&loc);
+}
+
/* The current iteration (1, 2, ...) of the coalescing pass. */
int lra_coalesce_iter;
}
}
-/* Return true if pseudo REGNO can be potentially coalesced. Use
- SPLIT_PSEUDO_BITMAP to find pseudos whose live ranges were
- split. */
+/* Return true if pseudo REGNO can be potentially coalesced. */
static bool
-coalescable_pseudo_p (int regno, bitmap split_origin_bitmap)
+coalescable_pseudo_p (int regno)
{
lra_assert (regno >= FIRST_PSEUDO_REGISTER);
- /* Don't coalesce inheritance pseudos because spilled inheritance
- pseudos will be removed in subsequent 'undo inheritance'
- pass. */
- return (lra_reg_info[regno].restore_regno < 0
- /* We undo splits for spilled pseudos whose live ranges were
- split. So don't coalesce them, it is not necessary and
- the undo transformations would be wrong. */
- && ! bitmap_bit_p (split_origin_bitmap, regno)
- /* We don't want to coalesce regnos with equivalences, at
+ return (/* We don't want to coalesce regnos with equivalences, at
least without updating this info. */
- && ira_reg_equiv[regno].constant == NULL_RTX
+ ira_reg_equiv[regno].constant == NULL_RTX
&& ira_reg_equiv[regno].memory == NULL_RTX
&& ira_reg_equiv[regno].invariant == NULL_RTX);
}
lra_coalesce (void)
{
basic_block bb;
- rtx mv, set, insn, next, *sorted_moves;
- int i, mv_num, sregno, dregno, restore_regno;
+ rtx_insn *mv, *insn, *next, **sorted_moves;
+ rtx set;
+ int i, mv_num, sregno, dregno;
unsigned int regno;
int coalesced_moves;
int max_regno = max_reg_num ();
- bitmap_head involved_insns_bitmap, split_origin_bitmap;
+ bitmap_head involved_insns_bitmap;
+ bitmap_head result_pseudo_vals_bitmap;
bitmap_iterator bi;
timevar_push (TV_LRA_COALESCE);
next_coalesced_pseudo = XNEWVEC (int, max_regno);
for (i = 0; i < max_regno; i++)
first_coalesced_pseudo[i] = next_coalesced_pseudo[i] = i;
- sorted_moves = XNEWVEC (rtx, get_max_uid ());
+ sorted_moves = XNEWVEC (rtx_insn *, get_max_uid ());
mv_num = 0;
- /* Collect pseudos whose live ranges were split. */
- bitmap_initialize (&split_origin_bitmap, ®_obstack);
- EXECUTE_IF_SET_IN_BITMAP (&lra_split_regs, 0, regno, bi)
- if ((restore_regno = lra_reg_info[regno].restore_regno) >= 0)
- bitmap_set_bit (&split_origin_bitmap, restore_regno);
/* Collect moves. */
coalesced_moves = 0;
- FOR_EACH_BB (bb)
+ FOR_EACH_BB_FN (bb, cfun)
{
FOR_BB_INSNS_SAFE (bb, insn, next)
if (INSN_P (insn)
&& (sregno = REGNO (SET_SRC (set))) >= FIRST_PSEUDO_REGISTER
&& (dregno = REGNO (SET_DEST (set))) >= FIRST_PSEUDO_REGISTER
&& mem_move_p (sregno, dregno)
- && coalescable_pseudo_p (sregno, &split_origin_bitmap)
- && coalescable_pseudo_p (dregno, &split_origin_bitmap)
+ && coalescable_pseudo_p (sregno) && coalescable_pseudo_p (dregno)
&& ! side_effects_p (set)
&& !(lra_intersected_live_ranges_p
(lra_reg_info[sregno].live_ranges,
lra_reg_info[dregno].live_ranges)))
sorted_moves[mv_num++] = insn;
}
- bitmap_clear (&split_origin_bitmap);
qsort (sorted_moves, mv_num, sizeof (rtx), move_freq_compare_func);
/* Coalesced copies, most frequently executed first. */
bitmap_initialize (&coalesced_pseudos_bitmap, ®_obstack);
fprintf
(lra_dump_file, " Coalescing move %i:r%d-r%d (freq=%d)\n",
INSN_UID (mv), sregno, dregno,
- BLOCK_FOR_INSN (mv)->frequency);
+ REG_FREQ_FROM_BB (BLOCK_FOR_INSN (mv)));
/* We updated involved_insns_bitmap when doing the merge. */
}
else if (!(lra_intersected_live_ranges_p
" Coalescing move %i:r%d(%d)-r%d(%d) (freq=%d)\n",
INSN_UID (mv), sregno, ORIGINAL_REGNO (SET_SRC (set)),
dregno, ORIGINAL_REGNO (SET_DEST (set)),
- BLOCK_FOR_INSN (mv)->frequency);
+ REG_FREQ_FROM_BB (BLOCK_FOR_INSN (mv)));
bitmap_ior_into (&involved_insns_bitmap,
&lra_reg_info[sregno].insn_bitmap);
bitmap_ior_into (&involved_insns_bitmap,
}
}
bitmap_initialize (&used_pseudos_bitmap, ®_obstack);
- FOR_EACH_BB (bb)
+ FOR_EACH_BB_FN (bb, cfun)
{
update_live_info (df_get_live_in (bb));
update_live_info (df_get_live_out (bb));
if (INSN_P (insn)
&& bitmap_bit_p (&involved_insns_bitmap, INSN_UID (insn)))
{
- if (! substitute (&insn))
+ if (! substitute_within_insn (insn))
continue;
lra_update_insn_regno_info (insn);
if ((set = single_set (insn)) != NULL_RTX && set_noop_p (set))
/* Coalesced move. */
if (lra_dump_file != NULL)
fprintf (lra_dump_file, " Removing move %i (freq=%d)\n",
- INSN_UID (insn), BLOCK_FOR_INSN (insn)->frequency);
+ INSN_UID (insn),
+ REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)));
lra_set_insn_deleted (insn);
}
}
}
+ /* If we have situation after inheritance pass:
+
+ r1 <- ... insn originally setting p1
+ i1 <- r1 setting inheritance i1 from reload r1
+ ...
+ ... <- ... p2 ... dead p2
+ ..
+ p1 <- i1
+ r2 <- i1
+ ...<- ... r2 ...
+
+ And we are coalescing p1 and p2 using p1. In this case i1 and p1
+ should have different values, otherwise they can get the same
+ hard reg and this is wrong for insn using p2 before coalescing.
+ So invalidate such inheritance pseudo values. */
+ bitmap_initialize (&result_pseudo_vals_bitmap, ®_obstack);
+ EXECUTE_IF_SET_IN_BITMAP (&coalesced_pseudos_bitmap, 0, regno, bi)
+ bitmap_set_bit (&result_pseudo_vals_bitmap,
+ lra_reg_info[first_coalesced_pseudo[regno]].val);
+ EXECUTE_IF_SET_IN_BITMAP (&lra_inheritance_pseudos, 0, regno, bi)
+ if (bitmap_bit_p (&result_pseudo_vals_bitmap, lra_reg_info[regno].val))
+ {
+ lra_set_regno_unique_value (regno);
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file,
+ " Make unique value for inheritance r%d\n", regno);
+ }
+ bitmap_clear (&result_pseudo_vals_bitmap);
bitmap_clear (&used_pseudos_bitmap);
bitmap_clear (&involved_insns_bitmap);
bitmap_clear (&coalesced_pseudos_bitmap);