fprintf (file, ")\n");
}
-
-
-/* Make sure that the seen_in_insn and seen_in_block sbitmaps are set
- up correctly. */
-
-static void
-df_set_seen (void)
-{
- seen_in_block = BITMAP_ALLOC (&df_bitmap_obstack);
- seen_in_insn = BITMAP_ALLOC (&df_bitmap_obstack);
-}
-
-
-static void
-df_unset_seen (void)
-{
- BITMAP_FREE (seen_in_block);
- BITMAP_FREE (seen_in_insn);
-}
-
-
\f
/*----------------------------------------------------------------------------
REACHING DEFINITIONS
bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
- df_set_seen ();
+ seen_in_block = BITMAP_ALLOC (&df_bitmap_obstack);
+ seen_in_insn = BITMAP_ALLOC (&df_bitmap_obstack);
df_maybe_reorganize_def_refs (DF_REF_ORDER_BY_REG);
DF_DEFS_BEGIN (regno),
DF_DEFS_COUNT (regno));
}
- df_unset_seen ();
+
+ BITMAP_FREE (seen_in_block);
+ BITMAP_FREE (seen_in_insn);
}
{
unsigned int uid = INSN_UID (insn);
- if (!INSN_P (insn))
+ if (!NONDEBUG_INSN_P (insn))
continue;
for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
rtx curr = old;
rtx prev = NULL;
+ gcc_assert (!DEBUG_INSN_P (insn));
+
while (curr)
if (XEXP (curr, 0) == reg)
{
static rtx
df_set_dead_notes_for_mw (rtx insn, rtx old, struct df_mw_hardreg *mws,
bitmap live, bitmap do_not_gen,
- bitmap artificial_uses)
+ bitmap artificial_uses, bool *added_notes_p)
{
unsigned int r;
+ bool is_debug = *added_notes_p;
+
+ *added_notes_p = false;
#ifdef REG_DEAD_DEBUGGING
if (dump_file)
if (df_whole_mw_reg_dead_p (mws, live, artificial_uses, do_not_gen))
{
/* Add a dead note for the entire multi word register. */
+ if (is_debug)
+ {
+ *added_notes_p = true;
+ return old;
+ }
old = df_set_note (REG_DEAD, insn, old, mws->mw_reg);
#ifdef REG_DEAD_DEBUGGING
df_print_note ("adding 1: ", insn, REG_NOTES (insn));
&& !bitmap_bit_p (artificial_uses, r)
&& !bitmap_bit_p (do_not_gen, r))
{
+ if (is_debug)
+ {
+ *added_notes_p = true;
+ return old;
+ }
old = df_set_note (REG_DEAD, insn, old, regno_reg_rtx[r]);
#ifdef REG_DEAD_DEBUGGING
df_print_note ("adding 2: ", insn, REG_NOTES (insn));
struct df_mw_hardreg **mws_rec;
rtx old_dead_notes;
rtx old_unused_notes;
+ int debug_insn;
if (!INSN_P (insn))
continue;
+ debug_insn = DEBUG_INSN_P (insn);
+
bitmap_clear (do_not_gen);
df_kill_notes (insn, &old_dead_notes, &old_unused_notes);
struct df_mw_hardreg *mws = *mws_rec;
if ((DF_MWS_REG_DEF_P (mws))
&& !df_ignore_stack_reg (mws->start_regno))
- old_dead_notes
- = df_set_dead_notes_for_mw (insn, old_dead_notes,
- mws, live, do_not_gen,
- artificial_uses);
+ {
+ bool really_add_notes = debug_insn != 0;
+
+ old_dead_notes
+ = df_set_dead_notes_for_mw (insn, old_dead_notes,
+ mws, live, do_not_gen,
+ artificial_uses,
+ &really_add_notes);
+
+ if (really_add_notes)
+ debug_insn = -1;
+ }
mws_rec++;
}
unsigned int uregno = DF_REF_REGNO (use);
#ifdef REG_DEAD_DEBUGGING
- if (dump_file)
+ if (dump_file && !debug_insn)
{
fprintf (dump_file, " regular looking at use ");
df_ref_debug (use, dump_file);
#endif
if (!bitmap_bit_p (live, uregno))
{
+ if (debug_insn)
+ {
+ debug_insn = -1;
+ break;
+ }
+
if ( (!(DF_REF_FLAGS (use) & DF_REF_MW_HARDREG))
&& (!bitmap_bit_p (do_not_gen, uregno))
&& (!bitmap_bit_p (artificial_uses, uregno))
free_EXPR_LIST_node (old_dead_notes);
old_dead_notes = next;
}
+
+ if (debug_insn == -1)
+ {
+ /* ??? We could probably do better here, replacing dead
+ registers with their definitions. */
+ INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
+ df_insn_rescan_debug_internal (insn);
+ }
}
}
df_ref *use_rec;
unsigned int uid = INSN_UID (insn);
+ if (DEBUG_INSN_P (insn))
+ return;
+
for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
{
df_ref use = *use_rec;
void
df_simulate_one_insn_backwards (basic_block bb, rtx insn, bitmap live)
{
- if (! INSN_P (insn))
+ if (!NONDEBUG_INSN_P (insn))
return;
df_simulate_defs (insn, live);
propagating the information to BB3's successors.
---------------------------------------------------------------------------*/
+/* Scratch var used by transfer functions. This is used to do md analysis
+ only for live registers. */
+static bitmap df_md_scratch;
+
/* Set basic block info. */
static void
sizeof (struct df_md_bb_info), 50);
df_grow_bb_info (df_md);
+ df_md_scratch = BITMAP_ALLOC (NULL);
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
basic_block bb;
bitmap *frontiers;
- df_set_seen ();
+ seen_in_insn = BITMAP_ALLOC (NULL);
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi1)
{
df_md_bb_local_compute (bb_index);
}
- df_unset_seen ();
+ BITMAP_FREE (seen_in_insn);
frontiers = XNEWVEC (bitmap, last_basic_block);
FOR_ALL_BB (bb)
bitmap kill = df_md_get_bb_info (bb_index)->kill;
EXECUTE_IF_SET_IN_BITMAP (frontiers[bb_index], 0, df_bb_index, bi2)
{
+ basic_block bb = BASIC_BLOCK (df_bb_index);
if (bitmap_bit_p (all_blocks, df_bb_index))
- bitmap_ior_into (df_md_get_bb_info (df_bb_index)->init, kill);
+ bitmap_ior_and_into (df_md_get_bb_info (df_bb_index)->init, kill,
+ df_get_live_in (bb));
}
}
static bool
df_md_transfer_function (int bb_index)
{
+ basic_block bb = BASIC_BLOCK (bb_index);
struct df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
bitmap in = bb_info->in;
bitmap out = bb_info->out;
bitmap gen = bb_info->gen;
bitmap kill = bb_info->kill;
- return bitmap_ior_and_compl (out, gen, in, kill);
+ /* We need to use a scratch set here so that the value returned from
+ this function invocation properly reflects if the sets changed in
+ a significant way; i.e. not just because the live set was anded
+ in. */
+ bitmap_and (df_md_scratch, gen, df_get_live_out (bb));
+
+ /* Multiple definitions of a register are not relevant if it is not
+ used. Thus we trim the result to the places where it is live. */
+ bitmap_and_into (in, df_get_live_in (bb));
+
+ return bitmap_ior_and_compl (out, df_md_scratch, in, kill);
}
/* Initialize the solution bit vectors for problem. */
}
}
+ BITMAP_FREE (df_md_scratch);
free_alloc_pool (df_md->block_pool);
df_md->block_info_size = 0;