bitmap.h (bitmap_and_into): Update prototype.
* bitmap.h (bitmap_and_into): Update prototype. * bitmap.c (bitmap_and_into): Return true if the target bitmap changed, false otherwise. * df.h (df_dump_insn_problem_function): New function type. (struct df_problem): Add two functions, to dump just before and just after an insn. (DF_RD_PRUNE_DEAD_DEFS): New changable flag. (df_dump_insn_top, df_dump_insn_bottom): New prototypes. * df-core (df_dump_region): Use dump_bb. (df_dump_bb_problem_data): New function. (df_dump_top, df_dump_bottom): Rewrite using df_dump_bb_problem_data. (df_dump_insn_problem_data): New function. (df_dump_insn_top, df_dump_insn_bottom): New functions. * df-scan.c (problem_SCAN): Add NULL fields for new members. * df-problems.c (df_rd_local_compute): Ignore hard registers if DF_NO_HARD_REGS is in effect. (df_rd_transfer_function): If DF_RD_PRUNE_DEAD_DEFS is in effect, prune reaching defs using the LR problem. (df_rd_start_dump): Fix dumping of DEFs map. (df_rd_dump_defs_set): New function. (df_rd_top_dump, df_rd_bottom_dump): Use it. (problem_RD): Add NULL fields for new members. (problem_LR, problem_LIVE): Likewise. (df_chain_bb_dump): New function. (df_chain_top_dump): Dump only for artificial DEFs and USEs, using df_chain_bb_dump. (df_chain_bottom_dump): Likewise. (df_chain_insn_top_dump, df_chain_insn_bottom_dump): New functions. (problem_CHAIN): Add them as new members. (problem_WORD_LR, problem_NOTE): Add NULL fields for new members. (problem_MD): Likewise. * cfgrtl.c (rtl_dump_bb): Use df_dump_insn_top and df_dump_insn_bottom. (print_rtl_with_bb): Likewise. * dce.c (init_dce): Use DF_RD_PRUNE_DEAD_DEFS. * loop-invariant.c (find_defs): Likewise. * loop-iv.c (iv_analysis_loop_init): Likewise. * ree.c (find_and_remove_re): Likewise. * web.c (web_main): Likewise. From-SVN: r192213
This commit is contained in:
parent
76cee070fd
commit
7b19209f29
|
@ -1,3 +1,46 @@
|
|||
2012-10-08 Steven Bosscher <steven@gcc.gnu.org>
|
||||
|
||||
* bitmap.h (bitmap_and_into): Update prototype.
|
||||
* bitmap.c (bitmap_and_into): Return true if the target bitmap
|
||||
changed, false otherwise.
|
||||
|
||||
* df.h (df_dump_insn_problem_function): New function type.
|
||||
(struct df_problem): Add two functions, to dump just before and
|
||||
just after an insn.
|
||||
(DF_RD_PRUNE_DEAD_DEFS): New changable flag.
|
||||
(df_dump_insn_top, df_dump_insn_bottom): New prototypes.
|
||||
* df-core (df_dump_region): Use dump_bb.
|
||||
(df_dump_bb_problem_data): New function.
|
||||
(df_dump_top, df_dump_bottom): Rewrite using df_dump_bb_problem_data.
|
||||
(df_dump_insn_problem_data): New function.
|
||||
(df_dump_insn_top, df_dump_insn_bottom): New functions.
|
||||
* df-scan.c (problem_SCAN): Add NULL fields for new members.
|
||||
* df-problems.c (df_rd_local_compute): Ignore hard registers if
|
||||
DF_NO_HARD_REGS is in effect.
|
||||
(df_rd_transfer_function): If DF_RD_PRUNE_DEAD_DEFS is in effect,
|
||||
prune reaching defs using the LR problem.
|
||||
(df_rd_start_dump): Fix dumping of DEFs map.
|
||||
(df_rd_dump_defs_set): New function.
|
||||
(df_rd_top_dump, df_rd_bottom_dump): Use it.
|
||||
(problem_RD): Add NULL fields for new members.
|
||||
(problem_LR, problem_LIVE): Likewise.
|
||||
(df_chain_bb_dump): New function.
|
||||
(df_chain_top_dump): Dump only for artificial DEFs and USEs,
|
||||
using df_chain_bb_dump.
|
||||
(df_chain_bottom_dump): Likewise.
|
||||
(df_chain_insn_top_dump, df_chain_insn_bottom_dump): New functions.
|
||||
(problem_CHAIN): Add them as new members.
|
||||
(problem_WORD_LR, problem_NOTE): Add NULL fields for new members.
|
||||
(problem_MD): Likewise.
|
||||
* cfgrtl.c (rtl_dump_bb): Use df_dump_insn_top and df_dump_insn_bottom.
|
||||
(print_rtl_with_bb): Likewise.
|
||||
|
||||
* dce.c (init_dce): Use DF_RD_PRUNE_DEAD_DEFS.
|
||||
* loop-invariant.c (find_defs): Likewise.
|
||||
* loop-iv.c (iv_analysis_loop_init): Likewise.
|
||||
* ree.c (find_and_remove_re): Likewise.
|
||||
* web.c (web_main): Likewise.
|
||||
|
||||
2012-10-08 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* config/rs6000/rs6000.c (rs6000_code_end): Protect the use of
|
||||
|
@ -319,7 +362,7 @@
|
|||
|
||||
2012-10-04 Jeff Law <law@redhat.com>
|
||||
|
||||
* PR target/50356
|
||||
PR target/50356
|
||||
* config/h8300/h8300.c (h8300_rtx_costs): Fix typo in CONST_INT case.
|
||||
|
||||
2012-10-04 Jason Merrill <jason@redhat.com>
|
||||
|
@ -329,8 +372,8 @@
|
|||
|
||||
2012-10-04 Basile Starynkevitch <basile@starynkevitch.net>
|
||||
|
||||
* gengtype.c (walk_type): Emit mark_hook when inside a
|
||||
struct of a union member.
|
||||
* gengtype.c (walk_type): Emit mark_hook when inside a
|
||||
struct of a union member.
|
||||
|
||||
2012-10-04 Georg-Johann Lay <avr@gjlay.de>
|
||||
|
||||
|
|
21
gcc/bitmap.c
21
gcc/bitmap.c
|
@ -916,17 +916,18 @@ bitmap_and (bitmap dst, const_bitmap a, const_bitmap b)
|
|||
dst->indx = dst->current->indx;
|
||||
}
|
||||
|
||||
/* A &= B. */
|
||||
/* A &= B. Return true if A changed. */
|
||||
|
||||
void
|
||||
bool
|
||||
bitmap_and_into (bitmap a, const_bitmap b)
|
||||
{
|
||||
bitmap_element *a_elt = a->first;
|
||||
const bitmap_element *b_elt = b->first;
|
||||
bitmap_element *next;
|
||||
bool changed = false;
|
||||
|
||||
if (a == b)
|
||||
return;
|
||||
return false;
|
||||
|
||||
while (a_elt && b_elt)
|
||||
{
|
||||
|
@ -935,6 +936,7 @@ bitmap_and_into (bitmap a, const_bitmap b)
|
|||
next = a_elt->next;
|
||||
bitmap_element_free (a, a_elt);
|
||||
a_elt = next;
|
||||
changed = true;
|
||||
}
|
||||
else if (b_elt->indx < a_elt->indx)
|
||||
b_elt = b_elt->next;
|
||||
|
@ -947,7 +949,8 @@ bitmap_and_into (bitmap a, const_bitmap b)
|
|||
for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
|
||||
{
|
||||
BITMAP_WORD r = a_elt->bits[ix] & b_elt->bits[ix];
|
||||
|
||||
if (a_elt->bits[ix] != r)
|
||||
changed = true;
|
||||
a_elt->bits[ix] = r;
|
||||
ior |= r;
|
||||
}
|
||||
|
@ -958,9 +961,17 @@ bitmap_and_into (bitmap a, const_bitmap b)
|
|||
b_elt = b_elt->next;
|
||||
}
|
||||
}
|
||||
bitmap_elt_clear_from (a, a_elt);
|
||||
|
||||
if (a_elt)
|
||||
{
|
||||
changed = true;
|
||||
bitmap_elt_clear_from (a, a_elt);
|
||||
}
|
||||
|
||||
gcc_checking_assert (!a->current == !a->first
|
||||
&& (!a->current || a->indx == a->current->indx));
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -224,7 +224,7 @@ extern unsigned long bitmap_count_bits (const_bitmap);
|
|||
are three operand versions that to not destroy the source bitmaps.
|
||||
The operations supported are &, & ~, |, ^. */
|
||||
extern void bitmap_and (bitmap, const_bitmap, const_bitmap);
|
||||
extern void bitmap_and_into (bitmap, const_bitmap);
|
||||
extern bool bitmap_and_into (bitmap, const_bitmap);
|
||||
extern bool bitmap_and_compl (bitmap, const_bitmap, const_bitmap);
|
||||
extern bool bitmap_and_compl_into (bitmap, const_bitmap);
|
||||
#define bitmap_compl_and(DST, A, B) bitmap_and_compl (DST, B, A)
|
||||
|
|
|
@ -1856,11 +1856,14 @@ rtl_dump_bb (FILE *outf, basic_block bb, int indent, int flags)
|
|||
for (insn = BB_HEAD (bb), last = NEXT_INSN (BB_END (bb)); insn != last;
|
||||
insn = NEXT_INSN (insn))
|
||||
{
|
||||
if (flags & TDF_DETAILS)
|
||||
df_dump_insn_top (insn, outf);
|
||||
if (! (flags & TDF_SLIM))
|
||||
print_rtl_single (outf, insn);
|
||||
else
|
||||
dump_insn_slim (outf, insn);
|
||||
|
||||
if (flags & TDF_DETAILS)
|
||||
df_dump_insn_bottom (insn, outf);
|
||||
}
|
||||
|
||||
if (df && (flags & TDF_DETAILS))
|
||||
|
@ -1941,10 +1944,14 @@ print_rtl_with_bb (FILE *outf, const_rtx rtx_first, int flags)
|
|||
fprintf (outf, ";; Insn is in multiple basic blocks\n");
|
||||
}
|
||||
|
||||
if (flags & TDF_DETAILS)
|
||||
df_dump_insn_top (tmp_rtx, outf);
|
||||
if (! (flags & TDF_SLIM))
|
||||
print_rtl_single (outf, tmp_rtx);
|
||||
else
|
||||
dump_insn_slim (outf, tmp_rtx);
|
||||
if (flags & TDF_DETAILS)
|
||||
df_dump_insn_bottom (tmp_rtx, outf);
|
||||
|
||||
if (flags & TDF_BLOCKS)
|
||||
{
|
||||
|
|
|
@ -704,7 +704,10 @@ init_dce (bool fast)
|
|||
if (!df_in_progress)
|
||||
{
|
||||
if (!fast)
|
||||
df_chain_add_problem (DF_UD_CHAIN);
|
||||
{
|
||||
df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
|
||||
df_chain_add_problem (DF_UD_CHAIN);
|
||||
}
|
||||
df_analyze ();
|
||||
}
|
||||
|
||||
|
|
|
@ -1994,10 +1994,7 @@ df_dump_region (FILE *file)
|
|||
EXECUTE_IF_SET_IN_BITMAP (df->blocks_to_analyze, 0, bb_index, bi)
|
||||
{
|
||||
basic_block bb = BASIC_BLOCK (bb_index);
|
||||
|
||||
df_print_bb_index (bb, file);
|
||||
df_dump_top (bb, file);
|
||||
df_dump_bottom (bb, file);
|
||||
dump_bb (file, bb, 0, TDF_DETAILS);
|
||||
}
|
||||
fprintf (file, "\n");
|
||||
}
|
||||
|
@ -2035,10 +2032,9 @@ df_dump_start (FILE *file)
|
|||
}
|
||||
|
||||
|
||||
/* Dump the top of the block information for BB. */
|
||||
|
||||
void
|
||||
df_dump_top (basic_block bb, FILE *file)
|
||||
/* Dump the top or bottom of the block information for BB. */
|
||||
static void
|
||||
df_dump_bb_problem_data (basic_block bb, FILE *file, bool top)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -2050,18 +2046,39 @@ df_dump_top (basic_block bb, FILE *file)
|
|||
struct dataflow *dflow = df->problems_in_order[i];
|
||||
if (dflow->computed)
|
||||
{
|
||||
df_dump_bb_problem_function bbfun = dflow->problem->dump_top_fun;
|
||||
df_dump_bb_problem_function bbfun;
|
||||
|
||||
if (top)
|
||||
bbfun = dflow->problem->dump_top_fun;
|
||||
else
|
||||
bbfun = dflow->problem->dump_bottom_fun;
|
||||
|
||||
if (bbfun)
|
||||
bbfun (bb, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump the top of the block information for BB. */
|
||||
|
||||
void
|
||||
df_dump_top (basic_block bb, FILE *file)
|
||||
{
|
||||
df_dump_bb_problem_data (bb, file, /*top=*/true);
|
||||
}
|
||||
|
||||
/* Dump the bottom of the block information for BB. */
|
||||
|
||||
void
|
||||
df_dump_bottom (basic_block bb, FILE *file)
|
||||
{
|
||||
df_dump_bb_problem_data (bb, file, /*top=*/false);
|
||||
}
|
||||
|
||||
|
||||
/* Dump information about INSN just before or after dumping INSN itself. */
|
||||
static void
|
||||
df_dump_insn_problem_data (const_rtx insn, FILE *file, bool top)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -2073,13 +2090,35 @@ df_dump_bottom (basic_block bb, FILE *file)
|
|||
struct dataflow *dflow = df->problems_in_order[i];
|
||||
if (dflow->computed)
|
||||
{
|
||||
df_dump_bb_problem_function bbfun = dflow->problem->dump_bottom_fun;
|
||||
if (bbfun)
|
||||
bbfun (bb, file);
|
||||
df_dump_insn_problem_function insnfun;
|
||||
|
||||
if (top)
|
||||
insnfun = dflow->problem->dump_insn_top_fun;
|
||||
else
|
||||
insnfun = dflow->problem->dump_insn_bottom_fun;
|
||||
|
||||
if (insnfun)
|
||||
insnfun (insn, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump information about INSN before dumping INSN itself. */
|
||||
|
||||
void
|
||||
df_dump_insn_top (const_rtx insn, FILE *file)
|
||||
{
|
||||
df_dump_insn_problem_data (insn, file, /*top=*/true);
|
||||
}
|
||||
|
||||
/* Dump information about INSN after dumping INSN itself. */
|
||||
|
||||
void
|
||||
df_dump_insn_bottom (const_rtx insn, FILE *file)
|
||||
{
|
||||
df_dump_insn_problem_data (insn, file, /*top=*/false);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
df_ref_dump (df_ref ref, FILE *file)
|
||||
|
|
|
@ -152,6 +152,17 @@ df_print_bb_index (basic_block bb, FILE *file)
|
|||
pseudo reaches. In and out bitvectors are built for each basic
|
||||
block. The id field in the ref is used to index into these sets.
|
||||
See df.h for details.
|
||||
|
||||
If the DF_RD_PRUNE_DEAD_DEFS changable flag is set, only DEFs reaching
|
||||
existing uses are included in the global reaching DEFs set, or in other
|
||||
words only DEFs that are still live. This is a kind of pruned version
|
||||
of the traditional reaching definitions problem that is much less
|
||||
complex to compute and produces enough information to compute UD-chains.
|
||||
In this context, live must be interpreted in the DF_LR sense: Uses that
|
||||
are upward exposed but maybe not initialized on all paths through the
|
||||
CFG. For a USE that is not reached by a DEF on all paths, we still want
|
||||
to make those DEFs that do reach the USE visible, and pruning based on
|
||||
DF_LIVE would make that impossible.
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/* This problem plays a large number of games for the sake of
|
||||
|
@ -239,8 +250,7 @@ df_rd_alloc (bitmap all_blocks)
|
|||
df_grow_bb_info (df_rd);
|
||||
|
||||
/* Because of the clustering of all use sites for the same pseudo,
|
||||
we have to process all of the blocks before doing the
|
||||
analysis. */
|
||||
we have to process all of the blocks before doing the analysis. */
|
||||
|
||||
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
|
||||
{
|
||||
|
@ -450,12 +460,16 @@ df_rd_local_compute (bitmap all_blocks)
|
|||
/* Set up the knockout bit vectors to be applied across EH_EDGES. */
|
||||
EXECUTE_IF_SET_IN_BITMAP (regs_invalidated_by_call_regset, 0, regno, bi)
|
||||
{
|
||||
if (DF_DEFS_COUNT (regno) > DF_SPARSE_THRESHOLD)
|
||||
bitmap_set_bit (sparse_invalidated, regno);
|
||||
else
|
||||
bitmap_set_range (dense_invalidated,
|
||||
DF_DEFS_BEGIN (regno),
|
||||
DF_DEFS_COUNT (regno));
|
||||
if (! HARD_REGISTER_NUM_P (regno)
|
||||
|| !(df->changeable_flags & DF_NO_HARD_REGS))
|
||||
{
|
||||
if (DF_DEFS_COUNT (regno) > DF_SPARSE_THRESHOLD)
|
||||
bitmap_set_bit (sparse_invalidated, regno);
|
||||
else
|
||||
bitmap_set_range (dense_invalidated,
|
||||
DF_DEFS_BEGIN (regno),
|
||||
DF_DEFS_COUNT (regno));
|
||||
}
|
||||
}
|
||||
|
||||
bitmap_clear (&seen_in_block);
|
||||
|
@ -534,13 +548,13 @@ df_rd_transfer_function (int bb_index)
|
|||
bitmap gen = &bb_info->gen;
|
||||
bitmap kill = &bb_info->kill;
|
||||
bitmap sparse_kill = &bb_info->sparse_kill;
|
||||
bool changed = false;
|
||||
|
||||
if (bitmap_empty_p (sparse_kill))
|
||||
return bitmap_ior_and_compl (out, gen, in, kill);
|
||||
changed = bitmap_ior_and_compl (out, gen, in, kill);
|
||||
else
|
||||
{
|
||||
struct df_rd_problem_data *problem_data;
|
||||
bool changed = false;
|
||||
bitmap_head tmp;
|
||||
|
||||
/* Note that TMP is _not_ a temporary bitmap if we end up replacing
|
||||
|
@ -564,11 +578,31 @@ df_rd_transfer_function (int bb_index)
|
|||
bb_info->out = tmp;
|
||||
}
|
||||
else
|
||||
bitmap_clear (&tmp);
|
||||
return changed;
|
||||
bitmap_clear (&tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if (df->changeable_flags & DF_RD_PRUNE_DEAD_DEFS)
|
||||
{
|
||||
/* Create a mask of DEFs for all registers live at the end of this
|
||||
basic block, and mask out DEFs of registers that are not live.
|
||||
Computing the mask looks costly, but the benefit of the pruning
|
||||
outweighs the cost. */
|
||||
struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
|
||||
bitmap regs_live_out = &df_lr_get_bb_info (bb_index)->out;
|
||||
bitmap live_defs = BITMAP_ALLOC (&df_bitmap_obstack);
|
||||
unsigned int regno;
|
||||
bitmap_iterator bi;
|
||||
|
||||
EXECUTE_IF_SET_IN_BITMAP (regs_live_out, 0, regno, bi)
|
||||
bitmap_set_range (live_defs,
|
||||
DF_DEFS_BEGIN (regno),
|
||||
DF_DEFS_COUNT (regno));
|
||||
changed |= bitmap_and_into (&bb_info->out, live_defs);
|
||||
BITMAP_FREE (live_defs);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
/* Free all storage associated with the problem. */
|
||||
|
||||
|
@ -604,23 +638,66 @@ df_rd_start_dump (FILE *file)
|
|||
if (!df_rd->block_info)
|
||||
return;
|
||||
|
||||
fprintf (file, ";; Reaching defs:\n\n");
|
||||
fprintf (file, ";; Reaching defs:\n");
|
||||
|
||||
fprintf (file, " sparse invalidated \t");
|
||||
fprintf (file, ";; sparse invalidated \t");
|
||||
dump_bitmap (file, &problem_data->sparse_invalidated_by_call);
|
||||
fprintf (file, " dense invalidated \t");
|
||||
fprintf (file, ";; dense invalidated \t");
|
||||
dump_bitmap (file, &problem_data->dense_invalidated_by_call);
|
||||
|
||||
fprintf (file, ";; reg->defs[] map:\t");
|
||||
for (regno = 0; regno < m; regno++)
|
||||
if (DF_DEFS_COUNT (regno))
|
||||
fprintf (file, "%d[%d,%d] ", regno,
|
||||
DF_DEFS_BEGIN (regno),
|
||||
DF_DEFS_COUNT (regno));
|
||||
DF_DEFS_BEGIN (regno) + DF_DEFS_COUNT (regno) - 1);
|
||||
fprintf (file, "\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
df_rd_dump_defs_set (bitmap defs_set, const char *prefix, FILE *file)
|
||||
{
|
||||
bitmap_head tmp;
|
||||
unsigned int regno;
|
||||
unsigned int m = DF_REG_SIZE(df);
|
||||
bool first_reg = true;
|
||||
|
||||
fprintf (file, "%s\t(%d) ", prefix, (int) bitmap_count_bits (defs_set));
|
||||
|
||||
bitmap_initialize (&tmp, &df_bitmap_obstack);
|
||||
for (regno = 0; regno < m; regno++)
|
||||
{
|
||||
if (HARD_REGISTER_NUM_P (regno)
|
||||
&& (df->changeable_flags & DF_NO_HARD_REGS))
|
||||
continue;
|
||||
bitmap_set_range (&tmp, DF_DEFS_BEGIN (regno), DF_DEFS_COUNT (regno));
|
||||
bitmap_and_into (&tmp, defs_set);
|
||||
if (! bitmap_empty_p (&tmp))
|
||||
{
|
||||
bitmap_iterator bi;
|
||||
unsigned int ix;
|
||||
bool first_def = true;
|
||||
|
||||
if (! first_reg)
|
||||
fprintf (file, ",");
|
||||
first_reg = false;
|
||||
|
||||
fprintf (file, "%u[", regno);
|
||||
EXECUTE_IF_SET_IN_BITMAP (&tmp, 0, ix, bi)
|
||||
{
|
||||
fprintf (file, "%s%u", first_def ? "" : ",", ix);
|
||||
first_def = false;
|
||||
}
|
||||
fprintf (file, "]");
|
||||
}
|
||||
bitmap_clear (&tmp);
|
||||
}
|
||||
|
||||
fprintf (file, "\n");
|
||||
bitmap_clear (&tmp);
|
||||
}
|
||||
|
||||
/* Debugging info at top of bb. */
|
||||
|
||||
static void
|
||||
|
@ -630,16 +707,13 @@ df_rd_top_dump (basic_block bb, FILE *file)
|
|||
if (!bb_info)
|
||||
return;
|
||||
|
||||
fprintf (file, ";; rd in \t(%d)\n", (int) bitmap_count_bits (&bb_info->in));
|
||||
dump_bitmap (file, &bb_info->in);
|
||||
fprintf (file, ";; rd gen \t(%d)\n", (int) bitmap_count_bits (&bb_info->gen));
|
||||
dump_bitmap (file, &bb_info->gen);
|
||||
fprintf (file, ";; rd kill\t(%d)\n", (int) bitmap_count_bits (&bb_info->kill));
|
||||
dump_bitmap (file, &bb_info->kill);
|
||||
df_rd_dump_defs_set (&bb_info->in, ";; rd in ", file);
|
||||
df_rd_dump_defs_set (&bb_info->gen, ";; rd gen ", file);
|
||||
df_rd_dump_defs_set (&bb_info->kill, ";; rd kill", file);
|
||||
}
|
||||
|
||||
|
||||
/* Debugging info at top of bb. */
|
||||
/* Debugging info at bottom of bb. */
|
||||
|
||||
static void
|
||||
df_rd_bottom_dump (basic_block bb, FILE *file)
|
||||
|
@ -648,8 +722,7 @@ df_rd_bottom_dump (basic_block bb, FILE *file)
|
|||
if (!bb_info)
|
||||
return;
|
||||
|
||||
fprintf (file, ";; rd out \t(%d)\n", (int) bitmap_count_bits (&bb_info->out));
|
||||
dump_bitmap (file, &bb_info->out);
|
||||
df_rd_dump_defs_set (&bb_info->out, ";; rd out ", file);
|
||||
}
|
||||
|
||||
/* All of the information associated with every instance of the problem. */
|
||||
|
@ -673,6 +746,8 @@ static struct df_problem problem_RD =
|
|||
df_rd_start_dump, /* Debugging. */
|
||||
df_rd_top_dump, /* Debugging start block. */
|
||||
df_rd_bottom_dump, /* Debugging end block. */
|
||||
NULL, /* Debugging start insn. */
|
||||
NULL, /* Debugging end insn. */
|
||||
NULL, /* Incremental solution verify start. */
|
||||
NULL, /* Incremental solution verify end. */
|
||||
NULL, /* Dependent problem. */
|
||||
|
@ -1209,6 +1284,8 @@ static struct df_problem problem_LR =
|
|||
NULL, /* Debugging. */
|
||||
df_lr_top_dump, /* Debugging start block. */
|
||||
df_lr_bottom_dump, /* Debugging end block. */
|
||||
NULL, /* Debugging start insn. */
|
||||
NULL, /* Debugging end insn. */
|
||||
df_lr_verify_solution_start,/* Incremental solution verify start. */
|
||||
df_lr_verify_solution_end, /* Incremental solution verify end. */
|
||||
NULL, /* Dependent problem. */
|
||||
|
@ -1738,6 +1815,8 @@ static struct df_problem problem_LIVE =
|
|||
NULL, /* Debugging. */
|
||||
df_live_top_dump, /* Debugging start block. */
|
||||
df_live_bottom_dump, /* Debugging end block. */
|
||||
NULL, /* Debugging start insn. */
|
||||
NULL, /* Debugging end insn. */
|
||||
df_live_verify_solution_start,/* Incremental solution verify start. */
|
||||
df_live_verify_solution_end, /* Incremental solution verify end. */
|
||||
&problem_LR, /* Dependent problem. */
|
||||
|
@ -2140,111 +2219,141 @@ df_chain_free (void)
|
|||
/* Debugging info. */
|
||||
|
||||
static void
|
||||
df_chain_top_dump (basic_block bb, FILE *file)
|
||||
df_chain_bb_dump (basic_block bb, FILE *file, bool top)
|
||||
{
|
||||
/* Artificials are only hard regs. */
|
||||
if (df->changeable_flags & DF_NO_HARD_REGS)
|
||||
return;
|
||||
if (df_chain_problem_p (DF_UD_CHAIN))
|
||||
{
|
||||
fprintf (file,
|
||||
";; UD chains for artificial uses at %s\n",
|
||||
top ? "top" : "bottom");
|
||||
df_ref *use_rec = df_get_artificial_uses (bb->index);
|
||||
if (*use_rec)
|
||||
{
|
||||
while (*use_rec)
|
||||
{
|
||||
df_ref use = *use_rec;
|
||||
if ((top && (DF_REF_FLAGS (use) & DF_REF_AT_TOP))
|
||||
|| (!top && !(DF_REF_FLAGS (use) & DF_REF_AT_TOP)))
|
||||
{
|
||||
fprintf (file, ";; reg %d ", DF_REF_REGNO (use));
|
||||
df_chain_dump (DF_REF_CHAIN (use), file);
|
||||
fprintf (file, "\n");
|
||||
}
|
||||
use_rec++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (df_chain_problem_p (DF_DU_CHAIN))
|
||||
{
|
||||
rtx insn;
|
||||
fprintf (file,
|
||||
";; DU chains for artificial defs at %s\n",
|
||||
top ? "top" : "bottom");
|
||||
df_ref *def_rec = df_get_artificial_defs (bb->index);
|
||||
if (*def_rec)
|
||||
{
|
||||
|
||||
fprintf (file, ";; DU chains for artificial defs\n");
|
||||
while (*def_rec)
|
||||
{
|
||||
df_ref def = *def_rec;
|
||||
fprintf (file, ";; reg %d ", DF_REF_REGNO (def));
|
||||
df_chain_dump (DF_REF_CHAIN (def), file);
|
||||
fprintf (file, "\n");
|
||||
def_rec++;
|
||||
}
|
||||
}
|
||||
|
||||
FOR_BB_INSNS (bb, insn)
|
||||
{
|
||||
if (INSN_P (insn))
|
||||
{
|
||||
struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
|
||||
def_rec = DF_INSN_INFO_DEFS (insn_info);
|
||||
if (*def_rec)
|
||||
if ((top && (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
|
||||
|| (!top && !(DF_REF_FLAGS (def) & DF_REF_AT_TOP)))
|
||||
{
|
||||
fprintf (file, ";; DU chains for insn luid %d uid %d\n",
|
||||
DF_INSN_INFO_LUID (insn_info), INSN_UID (insn));
|
||||
|
||||
while (*def_rec)
|
||||
{
|
||||
df_ref def = *def_rec;
|
||||
fprintf (file, ";; reg %d ", DF_REF_REGNO (def));
|
||||
if (DF_REF_FLAGS (def) & DF_REF_READ_WRITE)
|
||||
fprintf (file, "read/write ");
|
||||
df_chain_dump (DF_REF_CHAIN (def), file);
|
||||
fprintf (file, "\n");
|
||||
def_rec++;
|
||||
}
|
||||
fprintf (file, ";; reg %d ", DF_REF_REGNO (def));
|
||||
df_chain_dump (DF_REF_CHAIN (def), file);
|
||||
fprintf (file, "\n");
|
||||
}
|
||||
def_rec++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
df_chain_top_dump (basic_block bb, FILE *file)
|
||||
{
|
||||
df_chain_bb_dump (bb, file, /*top=*/true);
|
||||
}
|
||||
|
||||
static void
|
||||
df_chain_bottom_dump (basic_block bb, FILE *file)
|
||||
{
|
||||
if (df_chain_problem_p (DF_UD_CHAIN))
|
||||
{
|
||||
rtx insn;
|
||||
df_ref *use_rec = df_get_artificial_uses (bb->index);
|
||||
df_chain_bb_dump (bb, file, /*top=*/false);
|
||||
}
|
||||
|
||||
if (*use_rec)
|
||||
static void
|
||||
df_chain_insn_top_dump (const_rtx insn, FILE *file)
|
||||
{
|
||||
if (df_chain_problem_p (DF_UD_CHAIN) && INSN_P (insn))
|
||||
{
|
||||
struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
|
||||
df_ref *use_rec = DF_INSN_INFO_USES (insn_info);
|
||||
df_ref *eq_use_rec = DF_INSN_INFO_EQ_USES (insn_info);
|
||||
fprintf (file, ";; UD chains for insn luid %d uid %d\n",
|
||||
DF_INSN_INFO_LUID (insn_info), INSN_UID (insn));
|
||||
if (*use_rec || *eq_use_rec)
|
||||
{
|
||||
fprintf (file, ";; UD chains for artificial uses\n");
|
||||
while (*use_rec)
|
||||
{
|
||||
df_ref use = *use_rec;
|
||||
fprintf (file, ";; reg %d ", DF_REF_REGNO (use));
|
||||
df_chain_dump (DF_REF_CHAIN (use), file);
|
||||
fprintf (file, "\n");
|
||||
if (! HARD_REGISTER_NUM_P (DF_REF_REGNO (use))
|
||||
|| !(df->changeable_flags & DF_NO_HARD_REGS))
|
||||
{
|
||||
fprintf (file, ";; reg %d ", DF_REF_REGNO (use));
|
||||
if (DF_REF_FLAGS (use) & DF_REF_READ_WRITE)
|
||||
fprintf (file, "read/write ");
|
||||
df_chain_dump (DF_REF_CHAIN (use), file);
|
||||
fprintf (file, "\n");
|
||||
}
|
||||
use_rec++;
|
||||
}
|
||||
}
|
||||
|
||||
FOR_BB_INSNS (bb, insn)
|
||||
{
|
||||
if (INSN_P (insn))
|
||||
while (*eq_use_rec)
|
||||
{
|
||||
struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
|
||||
df_ref *eq_use_rec = DF_INSN_INFO_EQ_USES (insn_info);
|
||||
use_rec = DF_INSN_INFO_USES (insn_info);
|
||||
if (*use_rec || *eq_use_rec)
|
||||
df_ref use = *eq_use_rec;
|
||||
if (! HARD_REGISTER_NUM_P (DF_REF_REGNO (use))
|
||||
|| !(df->changeable_flags & DF_NO_HARD_REGS))
|
||||
{
|
||||
fprintf (file, ";; UD chains for insn luid %d uid %d\n",
|
||||
DF_INSN_INFO_LUID (insn_info), INSN_UID (insn));
|
||||
|
||||
while (*use_rec)
|
||||
{
|
||||
df_ref use = *use_rec;
|
||||
fprintf (file, ";; reg %d ", DF_REF_REGNO (use));
|
||||
if (DF_REF_FLAGS (use) & DF_REF_READ_WRITE)
|
||||
fprintf (file, "read/write ");
|
||||
df_chain_dump (DF_REF_CHAIN (use), file);
|
||||
fprintf (file, "\n");
|
||||
use_rec++;
|
||||
}
|
||||
while (*eq_use_rec)
|
||||
{
|
||||
df_ref use = *eq_use_rec;
|
||||
fprintf (file, ";; eq_note reg %d ", DF_REF_REGNO (use));
|
||||
df_chain_dump (DF_REF_CHAIN (use), file);
|
||||
fprintf (file, "\n");
|
||||
eq_use_rec++;
|
||||
}
|
||||
fprintf (file, ";; eq_note reg %d ", DF_REF_REGNO (use));
|
||||
df_chain_dump (DF_REF_CHAIN (use), file);
|
||||
fprintf (file, "\n");
|
||||
}
|
||||
eq_use_rec++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
df_chain_insn_bottom_dump (const_rtx insn, FILE *file)
|
||||
{
|
||||
if (df_chain_problem_p (DF_DU_CHAIN) && INSN_P (insn))
|
||||
{
|
||||
struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
|
||||
df_ref *def_rec = DF_INSN_INFO_DEFS (insn_info);
|
||||
fprintf (file, ";; DU chains for insn luid %d uid %d\n",
|
||||
DF_INSN_INFO_LUID (insn_info), INSN_UID (insn));
|
||||
if (*def_rec)
|
||||
{
|
||||
while (*def_rec)
|
||||
{
|
||||
df_ref def = *def_rec;
|
||||
if (! HARD_REGISTER_NUM_P (DF_REF_REGNO (def))
|
||||
|| !(df->changeable_flags & DF_NO_HARD_REGS))
|
||||
{
|
||||
fprintf (file, ";; reg %d ", DF_REF_REGNO (def));
|
||||
if (DF_REF_FLAGS (def) & DF_REF_READ_WRITE)
|
||||
fprintf (file, "read/write ");
|
||||
df_chain_dump (DF_REF_CHAIN (def), file);
|
||||
fprintf (file, "\n");
|
||||
}
|
||||
def_rec++;
|
||||
}
|
||||
}
|
||||
fprintf (file, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
static struct df_problem problem_CHAIN =
|
||||
{
|
||||
|
@ -2265,6 +2374,8 @@ static struct df_problem problem_CHAIN =
|
|||
NULL, /* Debugging. */
|
||||
df_chain_top_dump, /* Debugging start block. */
|
||||
df_chain_bottom_dump, /* Debugging end block. */
|
||||
df_chain_insn_top_dump, /* Debugging start insn. */
|
||||
df_chain_insn_bottom_dump, /* Debugging end insn. */
|
||||
NULL, /* Incremental solution verify start. */
|
||||
NULL, /* Incremental solution verify end. */
|
||||
&problem_RD, /* Dependent problem. */
|
||||
|
@ -2643,9 +2754,11 @@ static struct df_problem problem_WORD_LR =
|
|||
NULL, /* Debugging. */
|
||||
df_word_lr_top_dump, /* Debugging start block. */
|
||||
df_word_lr_bottom_dump, /* Debugging end block. */
|
||||
NULL, /* Debugging start insn. */
|
||||
NULL, /* Debugging end insn. */
|
||||
NULL, /* Incremental solution verify start. */
|
||||
NULL, /* Incremental solution verify end. */
|
||||
NULL, /* Dependent problem. */
|
||||
NULL, /* Dependent problem. */
|
||||
sizeof (struct df_word_lr_bb_info),/* Size of entry of block_info array. */
|
||||
TV_DF_WORD_LR, /* Timing variable. */
|
||||
false /* Reset blocks on dropping out of blocks_to_analyze. */
|
||||
|
@ -3330,6 +3443,8 @@ static struct df_problem problem_NOTE =
|
|||
NULL, /* Debugging. */
|
||||
NULL, /* Debugging start block. */
|
||||
NULL, /* Debugging end block. */
|
||||
NULL, /* Debugging start insn. */
|
||||
NULL, /* Debugging end insn. */
|
||||
NULL, /* Incremental solution verify start. */
|
||||
NULL, /* Incremental solution verify end. */
|
||||
&problem_LR, /* Dependent problem. */
|
||||
|
@ -4382,6 +4497,8 @@ static struct df_problem problem_MD =
|
|||
NULL, /* Debugging. */
|
||||
df_md_top_dump, /* Debugging start block. */
|
||||
df_md_bottom_dump, /* Debugging end block. */
|
||||
NULL, /* Debugging start insn. */
|
||||
NULL, /* Debugging end insn. */
|
||||
NULL, /* Incremental solution verify start. */
|
||||
NULL, /* Incremental solution verify end. */
|
||||
NULL, /* Dependent problem. */
|
||||
|
|
|
@ -510,6 +510,8 @@ static struct df_problem problem_SCAN =
|
|||
df_scan_start_dump, /* Debugging. */
|
||||
df_scan_start_block, /* Debugging start block. */
|
||||
NULL, /* Debugging end block. */
|
||||
NULL, /* Debugging start insn. */
|
||||
NULL, /* Debugging end insn. */
|
||||
NULL, /* Incremental solution verify start. */
|
||||
NULL, /* Incremental solution verify end. */
|
||||
NULL, /* Dependent problem. */
|
||||
|
|
18
gcc/df.h
18
gcc/df.h
|
@ -239,6 +239,9 @@ typedef void (*df_dump_problem_function) (FILE *);
|
|||
/* Function to dump top or bottom of basic block results to FILE. */
|
||||
typedef void (*df_dump_bb_problem_function) (basic_block, FILE *);
|
||||
|
||||
/* Function to dump before or after an insn to FILE. */
|
||||
typedef void (*df_dump_insn_problem_function) (const_rtx, FILE *);
|
||||
|
||||
/* Function to dump top or bottom of basic block results to FILE. */
|
||||
typedef void (*df_verify_solution_start) (void);
|
||||
|
||||
|
@ -268,6 +271,8 @@ struct df_problem {
|
|||
df_dump_problem_function dump_start_fun;
|
||||
df_dump_bb_problem_function dump_top_fun;
|
||||
df_dump_bb_problem_function dump_bottom_fun;
|
||||
df_dump_insn_problem_function dump_insn_top_fun;
|
||||
df_dump_insn_problem_function dump_insn_bottom_fun;
|
||||
df_verify_solution_start verify_start_fun;
|
||||
df_verify_solution_end verify_end_fun;
|
||||
struct df_problem *dependent_problem;
|
||||
|
@ -463,7 +468,12 @@ enum df_changeable_flags
|
|||
rescans to be batched. */
|
||||
DF_DEFER_INSN_RESCAN = 1 << 5,
|
||||
|
||||
DF_VERIFY_SCHEDULED = 1 << 6
|
||||
/* Compute the reaching defs problem as "live and reaching defs" (LR&RD).
|
||||
A DEF is reaching and live at insn I if DEF reaches I and REGNO(DEF)
|
||||
is in LR_IN of the basic block containing I. */
|
||||
DF_RD_PRUNE_DEAD_DEFS = 1 << 6,
|
||||
|
||||
DF_VERIFY_SCHEDULED = 1 << 7
|
||||
};
|
||||
|
||||
/* Two of these structures are inline in df, one for the uses and one
|
||||
|
@ -773,7 +783,9 @@ struct df_scan_bb_info
|
|||
|
||||
|
||||
/* Reaching definitions. All bitmaps are indexed by the id field of
|
||||
the ref except sparse_kill which is indexed by regno. */
|
||||
the ref except sparse_kill which is indexed by regno. For the
|
||||
LR&RD problem, the kill set is not complete: It does not contain
|
||||
DEFs killed because the set register has died in the LR set. */
|
||||
struct df_rd_bb_info
|
||||
{
|
||||
/* Local sets to describe the basic blocks. */
|
||||
|
@ -918,6 +930,8 @@ extern void df_dump_region (FILE *);
|
|||
extern void df_dump_start (FILE *);
|
||||
extern void df_dump_top (basic_block, FILE *);
|
||||
extern void df_dump_bottom (basic_block, FILE *);
|
||||
extern void df_dump_insn_top (const_rtx, FILE *);
|
||||
extern void df_dump_insn_bottom (const_rtx, FILE *);
|
||||
extern void df_refs_chain_dump (df_ref *, bool, FILE *);
|
||||
extern void df_regs_chain_dump (df_ref, FILE *);
|
||||
extern void df_insn_debug (rtx, bool, FILE *);
|
||||
|
|
|
@ -659,20 +659,28 @@ find_defs (struct loop *loop, basic_block *body)
|
|||
for (i = 0; i < loop->num_nodes; i++)
|
||||
bitmap_set_bit (blocks, body[i]->index);
|
||||
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (dump_file,
|
||||
"*****starting processing of loop %d ******\n",
|
||||
loop->num);
|
||||
}
|
||||
|
||||
df_remove_problem (df_chain);
|
||||
df_process_deferred_rescans ();
|
||||
df_chain_add_problem (DF_UD_CHAIN);
|
||||
df_set_blocks (blocks);
|
||||
df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
|
||||
df_analyze ();
|
||||
check_invariant_table_size ();
|
||||
|
||||
if (dump_file)
|
||||
{
|
||||
df_dump_region (dump_file);
|
||||
fprintf (dump_file, "*****starting processing of loop ******\n");
|
||||
print_rtl_with_bb (dump_file, get_insns (), dump_flags);
|
||||
fprintf (dump_file, "*****ending processing of loop ******\n");
|
||||
fprintf (dump_file,
|
||||
"*****ending processing of loop %d ******\n",
|
||||
loop->num);
|
||||
}
|
||||
check_invariant_table_size ();
|
||||
|
||||
BITMAP_FREE (blocks);
|
||||
}
|
||||
|
|
|
@ -293,6 +293,7 @@ iv_analysis_loop_init (struct loop *loop)
|
|||
the problem back. */
|
||||
df_remove_problem (df_chain);
|
||||
df_process_deferred_rescans ();
|
||||
df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
|
||||
df_chain_add_problem (DF_UD_CHAIN);
|
||||
df_note_add_problem ();
|
||||
df_set_blocks (blocks);
|
||||
|
|
|
@ -868,6 +868,7 @@ find_and_remove_re (void)
|
|||
|
||||
/* Construct DU chain to get all reaching definitions of each
|
||||
extension instruction. */
|
||||
df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
|
||||
df_chain_add_problem (DF_UD_CHAIN + DF_DU_CHAIN);
|
||||
df_analyze ();
|
||||
df_set_flags (DF_DEFER_INSN_RESCAN);
|
||||
|
|
Loading…
Reference in New Issue