Il 07/10/2012 19:18, Steven Bosscher ha scritto: > Hello, > > The attached patch adds a DF changeable flag to compute a subset of > reaching definitions that are also live at the program points they > reach. This is an idea I discussed with Paolo many years ago already, > but until today it hadn't really ever been close to the top of my todo > list, but trying to compile the test case for PR54146 with -fweb > finally changed that :-) > > The idea is to prune the DF_RD_OUT set of each basic block by > registers live in DF_LR_OUT. I've implemented this pruning with the > same approach as the sparse formulation of RD dataflow, expanding the > regs in DF_LR_OUT to the corresponding set of DEFs and using that set > to mask out dead DEFs in DF_RD_OUT. This is a convenient formulation > because DF_LR is already expressed in terms of regnos (like > sparse_kill & friends), and the formulation also works fine for the > dense formulation, of course. > > The effect on compile time for a set of cc1-i files is negligible (not > measurable, anyway), but for crazy large test cases like PR54146 this > patch is the difference between triggering out-of-memory or completing > the pass (at least -fweb, probably also the other affected passes). > > Bootstrapped&tested on powerpc64-unknown-linux-gnu. OK for trunk?
Ok. I wonder if we actually need the non-pruned version anywhere... Paolo > df_rd_pruned.diff > > * 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. > > Index: bitmap.h > =================================================================== > --- bitmap.h (revision 192106) > +++ bitmap.h (working copy) > @@ -224,7 +224,7 @@ extern unsigned long bitmap_count_bits (const_bitm > 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) > Index: bitmap.c > =================================================================== > --- bitmap.c (revision 192106) > +++ bitmap.c (working copy) > @@ -916,17 +916,18 @@ bitmap_and (bitmap dst, const_bitmap a, const_bitm > 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; > } > > > Index: df.h > =================================================================== > --- df.h (revision 192106) > +++ df.h (working copy) > @@ -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 *); > Index: df-core.c > =================================================================== > --- df-core.c (revision 192106) > +++ df-core.c (working copy) > @@ -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,19 +2046,40 @@ df_dump_start (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; > > if (!df || !file) > @@ -2073,14 +2090,36 @@ 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) > { > Index: df-scan.c > =================================================================== > --- df-scan.c (revision 192106) > +++ df-scan.c (working copy) > @@ -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. */ > Index: df-problems.c > =================================================================== > --- df-problems.c (revision 192106) > +++ df-problems.c (working copy) > @@ -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,14 +578,34 @@ 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. */ > > -/* Free all storage associated with the problem. */ > - > static void > df_rd_free (void) > { > @@ -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,112 +2219,142 @@ 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)) > + df_chain_bb_dump (bb, file, /*top=*/false); > +} > + > +static void > +df_chain_insn_top_dump (const_rtx insn, FILE *file) > +{ > + if (df_chain_problem_p (DF_UD_CHAIN) && INSN_P (insn)) > { > - rtx insn; > - df_ref *use_rec = df_get_artificial_uses (bb->index); > - > - if (*use_rec) > + 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++; > } > + while (*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, ";; eq_note reg %d ", DF_REF_REGNO (use)); > + df_chain_dump (DF_REF_CHAIN (use), file); > + fprintf (file, "\n"); > + } > + eq_use_rec++; > + } > } > + } > +} > > - FOR_BB_INSNS (bb, insn) > +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) > { > - if (INSN_P (insn)) > + while (*def_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 def = *def_rec; > + if (! HARD_REGISTER_NUM_P (DF_REF_REGNO (def)) > + || !(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, ";; 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 = > { > DF_CHAIN, /* Problem id. */ > @@ -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. */ > Index: cfgrtl.c > =================================================================== > --- cfgrtl.c (revision 192106) > +++ cfgrtl.c (working copy) > @@ -1856,11 +1856,14 @@ rtl_dump_bb (FILE *outf, basic_block bb, int inden > 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 > 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) > { > Index: dce.c > =================================================================== > --- dce.c (revision 192106) > +++ dce.c (working copy) > @@ -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 (); > } > > Index: loop-invariant.c > =================================================================== > --- loop-invariant.c (revision 192106) > +++ loop-invariant.c (working copy) > @@ -659,20 +659,28 @@ > 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); > } > Index: loop-iv.c > =================================================================== > --- loop-iv.c (revision 192106) > +++ loop-iv.c (working copy) > @@ -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); > Index: ree.c > =================================================================== > --- ree.c (revision 192106) > +++ ree.c (working copy) > @@ -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); > Index: web.c > =================================================================== > --- web.c (revision 192106) > +++ web.c (working copy) > @@ -313,6 +313,7 @@ web_main (void) > rtx insn; > > df_set_flags (DF_NO_HARD_REGS + DF_EQ_NOTES); > + df_set_flags (DF_RD_PRUNE_DEAD_DEFS); > df_chain_add_problem (DF_UD_CHAIN); > df_analyze (); > df_set_flags (DF_DEFER_INSN_RESCAN);