aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2014-11-14 20:06:11 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2014-11-14 20:06:11 +0000
commit4ab74a01477d4089a3474d52479ed372c9b5ae29 (patch)
treebca0d7e49464e99d894d55c93bb521b4d91d4e18
parent44210a9672aed3212c0e289dddc5bd38c314290b (diff)
downloadgcc-4ab74a01477d4089a3474d52479ed372c9b5ae29.zip
gcc-4ab74a01477d4089a3474d52479ed372c9b5ae29.tar.gz
gcc-4ab74a01477d4089a3474d52479ed372c9b5ae29.tar.bz2
lra-int.h (lra_create_live_ranges): Add parameter.
2014-11-14 Vladimir Makarov <vmakarov@redhat.com> * lra-int.h (lra_create_live_ranges): Add parameter. * lra-lives.c (temp_bitmap): Move higher. (initiate_live_solver): Move temp_bitmap initialization into lra_live_ranges_init. (finish_live_solver): Move temp_bitmap clearing into live_ranges_finish. (process_bb_lives): Add parameter. Use it to control live info update and dead insn elimination. Pass it to mark_regno_live and mark_regno_dead. (lra_create_live_ranges): Add parameter. Pass it to process_bb_lives. (lra_live_ranges_init, lra_live_ranges_finish): See changes in initiate_live_solver and finish_live_solver. * lra-remat.c (do_remat): Process insn non-operand hard regs too. Use temp_bitmap to update avail_cands. * lra.c (lra): Pass new parameter to lra_create_live_ranges. Move check with lra_need_for_spill_p after live range pass. Switch on rematerialization pass. From-SVN: r217588
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/lra-int.h2
-rw-r--r--gcc/lra-lives.c88
-rw-r--r--gcc/lra-remat.c31
-rw-r--r--gcc/lra.c23
5 files changed, 113 insertions, 52 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c42a532..54610b6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+2014-11-14 Vladimir Makarov <vmakarov@redhat.com>
+
+ * lra-int.h (lra_create_live_ranges): Add parameter.
+ * lra-lives.c (temp_bitmap): Move higher.
+ (initiate_live_solver): Move temp_bitmap initialization into
+ lra_live_ranges_init.
+ (finish_live_solver): Move temp_bitmap clearing into
+ live_ranges_finish.
+ (process_bb_lives): Add parameter. Use it to control live info
+ update and dead insn elimination. Pass it to mark_regno_live and
+ mark_regno_dead.
+ (lra_create_live_ranges): Add parameter. Pass it to
+ process_bb_lives.
+ (lra_live_ranges_init, lra_live_ranges_finish): See changes in
+ initiate_live_solver and finish_live_solver.
+ * lra-remat.c (do_remat): Process insn non-operand hard regs too.
+ Use temp_bitmap to update avail_cands.
+ * lra.c (lra): Pass new parameter to lra_create_live_ranges. Move
+ check with lra_need_for_spill_p after live range pass. Switch on
+ rematerialization pass.
+
2014-11-14 Martin Jambor <mjambor@suse.cz>
* ipa-prop.h (ipa_get_jf_pass_through_type_preserved): use
diff --git a/gcc/lra-int.h b/gcc/lra-int.h
index 92dc40c..9422afc 100644
--- a/gcc/lra-int.h
+++ b/gcc/lra-int.h
@@ -353,7 +353,7 @@ extern int *lra_point_freq;
extern int lra_hard_reg_usage[FIRST_PSEUDO_REGISTER];
extern int lra_live_range_iter;
-extern void lra_create_live_ranges (bool);
+extern void lra_create_live_ranges (bool, bool);
extern lra_live_range_t lra_copy_live_range_list (lra_live_range_t);
extern lra_live_range_t lra_merge_live_ranges (lra_live_range_t,
lra_live_range_t);
diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c
index 9d1c189..5868be8 100644
--- a/gcc/lra-lives.c
+++ b/gcc/lra-lives.c
@@ -100,6 +100,9 @@ static sparseset start_living, start_dying;
insn. */
static sparseset unused_set, dead_set;
+/* Bitmap used for holding intermediate bitmap operation results. */
+static bitmap_head temp_bitmap;
+
/* Pool for pseudo live ranges. */
static alloc_pool live_range_pool;
@@ -420,9 +423,6 @@ get_bb_data_by_index (int index)
/* Bitmap with all hard regs. */
static bitmap_head all_hard_regs_bitmap;
-/* Bitmap used for holding intermediate bitmap operation results. */
-static bitmap_head temp_bitmap;
-
/* The transfer function used by the DF equation solver to propagate
live info through block with BB_INDEX according to the following
equation:
@@ -476,7 +476,6 @@ static bitmap_head all_blocks;
static void
initiate_live_solver (void)
{
- bitmap_initialize (&temp_bitmap, &reg_obstack);
bitmap_initialize (&all_hard_regs_bitmap, &reg_obstack);
bitmap_set_range (&all_hard_regs_bitmap, 0, FIRST_PSEUDO_REGISTER);
bb_data = XNEWVEC (struct bb_data_pseudos, last_basic_block_for_fn (cfun));
@@ -508,7 +507,6 @@ finish_live_solver (void)
}
free (bb_data);
bitmap_clear (&all_hard_regs_bitmap);
- bitmap_clear (&temp_bitmap);
}
@@ -640,10 +638,11 @@ check_pseudos_live_through_calls (int regno)
backward scan of BB insns. CURR_POINT is the program point where
BB ends. The function updates this counter and returns in
CURR_POINT the program point where BB starts. The function also
- can delete the dead insns. It returns true if pseudo live info was
+ does local live info updates and can delete the dead insns if
+ GLOBAL_LIVE_INFO_P. It returns true if pseudo live info was
changed at the BB start. */
static bool
-process_bb_lives (basic_block bb, int &curr_point)
+process_bb_lives (basic_block bb, int &curr_point, bool global_live_info_p)
{
int i, regno, freq;
unsigned int j;
@@ -663,11 +662,13 @@ process_bb_lives (basic_block bb, int &curr_point)
EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi)
mark_pseudo_live (j, curr_point);
- bb_gen_pseudos = &get_bb_data (bb)->gen_pseudos;
- bb_killed_pseudos = &get_bb_data (bb)->killed_pseudos;
- bitmap_clear (bb_gen_pseudos);
- bitmap_clear (bb_killed_pseudos);
-
+ if (global_live_info_p)
+ {
+ bb_gen_pseudos = &get_bb_data (bb)->gen_pseudos;
+ bb_killed_pseudos = &get_bb_data (bb)->killed_pseudos;
+ bitmap_clear (bb_gen_pseudos);
+ bitmap_clear (bb_killed_pseudos);
+ }
freq = REG_FREQ_FROM_BB (bb);
if (lra_dump_file != NULL)
@@ -700,7 +701,7 @@ process_bb_lives (basic_block bb, int &curr_point)
set = single_set (curr_insn);
- if (set != NULL_RTX
+ if (global_live_info_p && set != NULL_RTX
&& REG_P (SET_DEST (set)) && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
&& find_reg_note (curr_insn, REG_EH_REGION, NULL_RTX) == NULL_RTX
&& ! may_trap_p (PATTERN (curr_insn))
@@ -736,8 +737,8 @@ process_bb_lives (basic_block bb, int &curr_point)
unsigned int uid;
rtx_insn *insn;
- EXECUTE_IF_SET_IN_BITMAP
- (&lra_reg_info[dst_regno].insn_bitmap, 0, uid, bi)
+ bitmap_copy (&temp_bitmap, &lra_reg_info[dst_regno].insn_bitmap);
+ EXECUTE_IF_SET_IN_BITMAP (&temp_bitmap, 0, uid, bi)
{
insn = lra_insn_recog_data[uid]->insn;
lra_substitute_pseudo_within_insn (insn, dst_regno,
@@ -815,9 +816,9 @@ process_bb_lives (basic_block bb, int &curr_point)
for (reg = curr_id->regs; reg != NULL; reg = reg->next)
if (reg->type != OP_IN)
{
- need_curr_point_incr |= mark_regno_live (reg->regno,
- reg->biggest_mode,
- curr_point, true);
+ need_curr_point_incr
+ |= mark_regno_live (reg->regno, reg->biggest_mode,
+ curr_point, global_live_info_p);
check_pseudos_live_through_calls (reg->regno);
}
@@ -832,9 +833,9 @@ process_bb_lives (basic_block bb, int &curr_point)
/* See which defined values die here. */
for (reg = curr_id->regs; reg != NULL; reg = reg->next)
if (reg->type == OP_OUT && ! reg->early_clobber && ! reg->subreg_p)
- need_curr_point_incr |= mark_regno_dead (reg->regno,
- reg->biggest_mode,
- curr_point, true);
+ need_curr_point_incr
+ |= mark_regno_dead (reg->regno, reg->biggest_mode,
+ curr_point, global_live_info_p);
for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
if (reg->type == OP_OUT && ! reg->early_clobber && ! reg->subreg_p)
@@ -874,9 +875,9 @@ process_bb_lives (basic_block bb, int &curr_point)
for (reg = curr_id->regs; reg != NULL; reg = reg->next)
if (reg->type == OP_IN)
{
- need_curr_point_incr |= mark_regno_live (reg->regno,
- reg->biggest_mode,
- curr_point, true);
+ need_curr_point_incr
+ |= mark_regno_live (reg->regno, reg->biggest_mode,
+ curr_point, global_live_info_p);
check_pseudos_live_through_calls (reg->regno);
}
@@ -894,9 +895,9 @@ process_bb_lives (basic_block bb, int &curr_point)
/* Mark early clobber outputs dead. */
for (reg = curr_id->regs; reg != NULL; reg = reg->next)
if (reg->type == OP_OUT && reg->early_clobber && ! reg->subreg_p)
- need_curr_point_incr |= mark_regno_dead (reg->regno,
- reg->biggest_mode,
- curr_point, true);
+ need_curr_point_incr
+ |= mark_regno_dead (reg->regno, reg->biggest_mode,
+ curr_point, global_live_info_p);
for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
if (reg->type == OP_OUT && reg->early_clobber && ! reg->subreg_p)
@@ -969,19 +970,25 @@ process_bb_lives (basic_block bb, int &curr_point)
make_hard_regno_born (px);
}
- /* Check if bb border live info was changed. */
- unsigned int live_pseudos_num = 0;
bool live_change_p = false;
- EXECUTE_IF_SET_IN_BITMAP (df_get_live_in (bb), FIRST_PSEUDO_REGISTER, j, bi)
+ if (global_live_info_p)
{
- live_pseudos_num++;
- if (! sparseset_bit_p (pseudos_live, j))
+ /* Check if bb border live info was changed. */
+ unsigned int live_pseudos_num = 0;
+ EXECUTE_IF_SET_IN_BITMAP (df_get_live_in (bb),
+ FIRST_PSEUDO_REGISTER, j, bi)
{
- live_change_p = TRUE;
- break;
+ live_pseudos_num++;
+ if (! sparseset_bit_p (pseudos_live, j))
+ {
+ live_change_p = TRUE;
+ break;
+ }
}
+ live_change_p
+ = (live_change_p
+ || sparseset_cardinality (pseudos_live) != live_pseudos_num);
}
- live_change_p = live_change_p || sparseset_cardinality (pseudos_live) != live_pseudos_num;
/* See if we'll need an increment at the end of this basic block.
An increment is needed if the PSEUDOS_LIVE set is not empty,
@@ -1175,10 +1182,11 @@ int lra_live_range_iter;
/* The main entry function creates live ranges only for memory pseudos
(or for all ones if ALL_P), set up CONFLICT_HARD_REGS for the
- pseudos. It also does global live analysis only for pseudos and
- only if the pseudo live info was changed on a BB border. */
+ pseudos. It also does dead insn elimination and global live
+ analysis only for pseudos and only if GLOBAL_LIVE_INFO_P and the
+ pseudo live info was changed on a BB border. */
void
-lra_create_live_ranges (bool all_p)
+lra_create_live_ranges (bool all_p, bool global_live_info_p)
{
basic_block bb;
int i, hard_regno, max_regno = max_reg_num ();
@@ -1254,7 +1262,7 @@ lra_create_live_ranges (bool all_p)
if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun) || bb
== ENTRY_BLOCK_PTR_FOR_FN (cfun))
continue;
- if (process_bb_lives (bb, curr_point))
+ if (process_bb_lives (bb, curr_point, global_live_info_p))
bb_live_change_p = true;
}
if (bb_live_change_p)
@@ -1328,6 +1336,7 @@ lra_live_ranges_init (void)
{
live_range_pool = create_alloc_pool ("live ranges",
sizeof (struct lra_live_range), 100);
+ bitmap_initialize (&temp_bitmap, &reg_obstack);
initiate_live_solver ();
}
@@ -1336,5 +1345,6 @@ void
lra_live_ranges_finish (void)
{
finish_live_solver ();
+ bitmap_clear (&temp_bitmap);
free_alloc_pool (live_range_pool);
}
diff --git a/gcc/lra-remat.c b/gcc/lra-remat.c
index 51a94ca..f638a1d 100644
--- a/gcc/lra-remat.c
+++ b/gcc/lra-remat.c
@@ -1026,6 +1026,7 @@ do_remat (void)
continue;
lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
+ struct lra_static_insn_data *static_id = id->insn_static_data;
struct lra_insn_reg *reg;
cand_t cand;
unsigned int cid;
@@ -1059,7 +1060,10 @@ do_remat (void)
HOST_WIDE_INT cand_sp_offset = 0;
if (cand != NULL)
{
- lra_insn_recog_data_t cand_id = lra_get_insn_recog_data (cand->insn);
+ lra_insn_recog_data_t cand_id
+ = lra_get_insn_recog_data (cand->insn);
+ struct lra_static_insn_data *static_cand_id
+ = cand_id->insn_static_data;
rtx saved_op = *cand_id->operand_loc[cand->nop];
/* Check clobbers do not kill something living. */
@@ -1080,6 +1084,16 @@ do_remat (void)
if (reg == NULL)
{
+ for (reg = static_cand_id->hard_regs;
+ reg != NULL;
+ reg = reg->next)
+ if (reg->type != OP_IN
+ && TEST_HARD_REG_BIT (live_hard_regs, reg->regno))
+ break;
+ }
+
+ if (reg == NULL)
+ {
*cand_id->operand_loc[cand->nop] = SET_DEST (set);
lra_update_insn_regno_info (cand->insn);
bool ok_p = lra_constrain_insn (cand->insn);
@@ -1100,6 +1114,7 @@ do_remat (void)
}
}
+ bitmap_clear (&temp_bitmap);
/* Update avail_cands (see analogous code for
calculate_gen_cands). */
for (reg = id->regs; reg != NULL; reg = reg->next)
@@ -1115,7 +1130,7 @@ do_remat (void)
continue;
if (cand->regno == reg->regno
|| input_regno_present_p (cand->insn, reg->regno))
- bitmap_clear_bit (&avail_cands, cand->index);
+ bitmap_set_bit (&temp_bitmap, cand->index);
}
if (CALL_P (insn))
@@ -1124,9 +1139,10 @@ do_remat (void)
cand = all_cands[cid];
if (call_used_input_regno_present_p (cand->insn))
- bitmap_clear_bit (&avail_cands, cand->index);
+ bitmap_set_bit (&temp_bitmap, cand->index);
}
+ bitmap_and_compl_into (&avail_cands, &temp_bitmap);
if ((cand = insn_to_cand[INSN_UID (insn)]) != NULL)
bitmap_set_bit (&avail_cands, cand->index);
@@ -1160,6 +1176,15 @@ do_remat (void)
for (i = 0; i < nregs; i++)
SET_HARD_REG_BIT (live_hard_regs, hard_regno + i);
}
+ /* Process also hard regs (e.g. CC register) which are part
+ of insn definition. */
+ for (reg = static_id->hard_regs; reg != NULL; reg = reg->next)
+ if (reg->type == OP_IN
+ && find_regno_note (insn, REG_DEAD, reg->regno) != NULL)
+ CLEAR_HARD_REG_BIT (live_hard_regs, reg->regno);
+ else if (reg->type != OP_IN
+ && find_regno_note (insn, REG_UNUSED, reg->regno) == NULL)
+ SET_HARD_REG_BIT (live_hard_regs, reg->regno);
}
}
bitmap_clear (&avail_cands);
diff --git a/gcc/lra.c b/gcc/lra.c
index 6b99d5b..9309d5e 100644
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -2296,14 +2296,17 @@ lra (FILE *f)
/* As a side-effect of lra_create_live_ranges, we calculate
actual_call_used_reg_set, which is needed during
lra_inheritance. */
- lra_create_live_ranges (true);
+ lra_create_live_ranges (true, true);
}
lra_inheritance ();
}
if (live_p)
lra_clear_live_ranges ();
- /* We need live ranges for lra_assign -- so build them. */
- lra_create_live_ranges (true);
+ /* We need live ranges for lra_assign -- so build them. But
+ don't remove dead insns or change global live info as we
+ can undo inheritance transformations after inheritance
+ pseudo assigning. */
+ lra_create_live_ranges (true, false);
live_p = true;
/* If we don't spill non-reload and non-inheritance pseudos,
there is no sense to run memory-memory move coalescing.
@@ -2322,7 +2325,7 @@ lra (FILE *f)
{
if (! live_p)
{
- lra_create_live_ranges (true);
+ lra_create_live_ranges (true, true);
live_p = true;
}
if (lra_coalesce ())
@@ -2338,21 +2341,23 @@ lra (FILE *f)
bitmap_clear (&lra_subreg_reload_pseudos);
bitmap_clear (&lra_inheritance_pseudos);
bitmap_clear (&lra_split_regs);
- if (! lra_need_for_spills_p ())
- break;
if (! live_p)
{
/* We need full live info for spilling pseudos into
registers instead of memory. */
- lra_create_live_ranges (lra_reg_spill_p);
+ lra_create_live_ranges (lra_reg_spill_p, true);
live_p = true;
}
+ /* We should check necessity for spilling here as the above live
+ range pass can remove spilled pseudos. */
+ if (! lra_need_for_spills_p ())
+ break;
/* Now we know what pseudos should be spilled. Try to
rematerialize them first. */
- if (0 && lra_remat ())
+ if (lra_remat ())
{
/* We need full live info -- see the comment above. */
- lra_create_live_ranges (lra_reg_spill_p);
+ lra_create_live_ranges (lra_reg_spill_p, true);
live_p = true;
if (! lra_need_for_spills_p ())
break;