static bitmap bb_killed_pseudos, bb_gen_pseudos;
/* Mark register REGNO (pseudo or hard register) in MODE as live at
- program point POINT. Update BB_GEN_PSEUDOS if LOCAL_SETS_P.
+ program point POINT. Update BB_GEN_PSEUDOS.
Return TRUE if the liveness tracking sets were modified, or FALSE
if nothing changed. */
static bool
-mark_regno_live (int regno, machine_mode mode, int point, bool local_sets_p)
+mark_regno_live (int regno, machine_mode mode, int point)
{
int last;
bool changed = false;
mark_pseudo_live (regno, point);
changed = true;
}
- if (local_sets_p)
- bitmap_set_bit (bb_gen_pseudos, regno);
+ bitmap_set_bit (bb_gen_pseudos, regno);
}
return changed;
}
/* Mark register REGNO in MODE as dead at program point POINT. Update
- BB_GEN_PSEUDOS and BB_KILLED_PSEUDOS if LOCAL_SETS_P. Return TRUE
- if the liveness tracking sets were modified, or FALSE if nothing
- changed. */
+ BB_GEN_PSEUDOS and BB_KILLED_PSEUDOS. Return TRUE if the liveness
+ tracking sets were modified, or FALSE if nothing changed. */
static bool
-mark_regno_dead (int regno, machine_mode mode, int point, bool local_sets_p)
+mark_regno_dead (int regno, machine_mode mode, int point)
{
int last;
bool changed = false;
mark_pseudo_dead (regno, point);
changed = true;
}
- if (local_sets_p)
- {
- bitmap_clear_bit (bb_gen_pseudos, regno);
- bitmap_set_bit (bb_killed_pseudos, regno);
- }
+ bitmap_clear_bit (bb_gen_pseudos, regno);
+ bitmap_set_bit (bb_killed_pseudos, regno);
}
return changed;
}
BB ends. The function updates this counter and returns in
CURR_POINT the program point where BB starts. The function also
does local live info updates and can delete the dead insns if
- GLOBAL_LIVE_INFO_P. It returns true if pseudo live info was
+ DEAD_INSN_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, bool global_live_info_p)
+process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
{
int i, regno, freq;
unsigned int j;
EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi)
mark_pseudo_live (j, curr_point);
- 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);
- }
+ 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)
set = single_set (curr_insn);
- if (global_live_info_p && set != NULL_RTX
+ if (dead_insn_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))
&& (pic_offset_table_rtx == NULL_RTX
|| pic_offset_table_rtx != SET_DEST (set)))
{
- bool dead_insn_p = true;
+ bool remove_p = true;
for (reg = curr_id->regs; reg != NULL; reg = reg->next)
if (reg->type != OP_IN && sparseset_bit_p (pseudos_live, reg->regno))
{
- dead_insn_p = false;
+ remove_p = false;
break;
}
for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
if (reg->type != OP_IN)
{
- dead_insn_p = false;
+ remove_p = false;
break;
}
- if (dead_insn_p && ! volatile_refs_p (PATTERN (curr_insn)))
+ if (remove_p && ! volatile_refs_p (PATTERN (curr_insn)))
{
dst_regno = REGNO (SET_DEST (set));
if (lra_dump_file != NULL)
{
need_curr_point_incr
|= mark_regno_live (reg->regno, reg->biggest_mode,
- curr_point, global_live_info_p);
+ curr_point);
check_pseudos_live_through_calls (reg->regno);
}
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, global_live_info_p);
+ curr_point);
for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
if (reg->type == OP_OUT && ! reg->early_clobber && ! reg->subreg_p)
{
need_curr_point_incr
|= mark_regno_live (reg->regno, reg->biggest_mode,
- curr_point, global_live_info_p);
+ curr_point);
check_pseudos_live_through_calls (reg->regno);
}
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, global_live_info_p);
+ curr_point);
for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
if (reg->type == OP_OUT && reg->early_clobber && ! reg->subreg_p)
}
bool live_change_p = false;
- if (global_live_info_p)
+ /* 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)
{
- /* 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_pseudos_num++;
+ if (! sparseset_bit_p (pseudos_live, j))
{
- live_pseudos_num++;
- if (! sparseset_bit_p (pseudos_live, j))
- {
- live_change_p = TRUE;
- break;
- }
+ 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,
to make sure the finish points are set up correctly. */
/* The number of the current live range pass. */
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 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, bool global_live_info_p)
+/* The 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 dead insn elimination if DEAD_INSN_P and global live
+ analysis only for pseudos and only if the pseudo live info was
+ changed on a BB border. Return TRUE if the live info was
+ changed. */
+static bool
+lra_create_live_ranges_1 (bool all_p, bool dead_insn_p)
{
basic_block bb;
int i, hard_regno, max_regno = max_reg_num ();
if (! have_referenced_pseudos)
{
timevar_pop (TV_LRA_CREATE_LIVE_RANGES);
- return;
+ return false;
}
pseudos_live = sparseset_alloc (max_regno);
if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun) || bb
== ENTRY_BLOCK_PTR_FOR_FN (cfun))
continue;
- if (process_bb_lives (bb, curr_point, global_live_info_p))
+ if (process_bb_lives (bb, curr_point, dead_insn_p))
bb_live_change_p = true;
}
if (bb_live_change_p)
sparseset_free (pseudos_live);
compress_live_ranges ();
timevar_pop (TV_LRA_CREATE_LIVE_RANGES);
+ return bb_live_change_p;
+}
+
+/* The main entry function creates live-ranges and other live info
+ necessary for the assignment sub-pass. It uses
+ lra_creates_live_ranges_1 -- so read comments for the
+ function. */
+void
+lra_create_live_ranges (bool all_p, bool dead_insn_p)
+{
+ if (! lra_create_live_ranges_1 (all_p, dead_insn_p))
+ return;
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file, "Live info was changed -- recalculate it\n");
+ /* Live info was changed on a bb border. It means that some info,
+ e.g. about conflict regs, calls crossed may be wrong, live
+ ranges. We need this info for allocation. So recalcualate it
+ again. */
+ lra_clear_live_ranges ();
+ bool res = lra_create_live_ranges_1 (all_p, dead_insn_p);
+ lra_assert (! res);
}
/* Finish all live ranges. */