X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fdf-problems.c;h=46aa9e03f4c07df2ce0ae5d72b9408eb4e13ae29;hb=7e507322dc5a06590b17700cdb55eb71e6921710;hp=dd56399be50b144f30c0af809ecd63545d6edef3;hpb=dea7b504afdd99c98883a1e47226e805beb752b3;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/df-problems.c b/gcc/df-problems.c index dd56399be50..46aa9e03f4c 100644 --- a/gcc/df-problems.c +++ b/gcc/df-problems.c @@ -482,6 +482,9 @@ df_rd_confluence_n (edge e) bitmap op1 = df_rd_get_bb_info (e->dest->index)->in; bitmap op2 = df_rd_get_bb_info (e->src->index)->out; + if (e->flags & EDGE_FAKE) + return; + if (e->flags & EDGE_EH) { struct df_rd_problem_data *problem_data @@ -1015,7 +1018,7 @@ df_lr_transfer_function (int bb_index) /* Run the fast dce as a side effect of building LR. */ static void -df_lr_local_finalize (bitmap all_blocks ATTRIBUTE_UNUSED) +df_lr_finalize (bitmap all_blocks ATTRIBUTE_UNUSED) { if (df->changeable_flags & DF_LR_RUN_DCE) { @@ -1161,7 +1164,7 @@ df_lr_verify_solution_end (void) if (df_lr->solutions_dirty) /* Do not check if the solution is still dirty. See the comment - in df_lr_local_finalize for details. */ + in df_lr_finalize for details. */ df_lr->solutions_dirty = false; else FOR_ALL_BB (bb) @@ -1204,7 +1207,7 @@ static struct df_problem problem_LR = df_lr_confluence_0, /* Confluence operator 0. */ df_lr_confluence_n, /* Confluence operator n. */ df_lr_transfer_function, /* Transfer function. */ - df_lr_local_finalize, /* Finalize function. */ + df_lr_finalize, /* Finalize function. */ df_lr_free, /* Free all of the problem information. */ NULL, /* Remove this problem from the stack of dataflow problems. */ NULL, /* Debugging. */ @@ -1304,16 +1307,22 @@ df_lr_verify_transfer_functions (void) /*---------------------------------------------------------------------------- - COMBINED LIVE REGISTERS AND UNINITIALIZED REGISTERS. - - First find the set of uses for registers that are reachable from - the entry block without passing thru a definition. In and out - bitvectors are built for each basic block. The regnum is used to - index into these sets. See df.h for details. - - Then the in and out sets here are the anded results of the in and - out sets from the lr and ur - problems. + LIVE AND MUST-INITIALIZED REGISTERS. + + This problem first computes the IN and OUT bitvectors for the + must-initialized registers problems, which is a forward problem. + It gives the set of registers for which we MUST have an available + definition on any path from the entry block to the entry/exit of + a basic block. Sets generate a definition, while clobbers kill + a definition. + + In and out bitvectors are built for each basic block and are indexed by + regnum (see df.h for details). In and out bitvectors in struct + df_live_bb_info actually refers to the must-initialized problem; + + Then, the in and out sets for the LIVE problem itself are computed. + These are the logical AND of the IN and OUT sets from the LR problem + and the must-initialized problem. ----------------------------------------------------------------------------*/ /* Private data used to verify the solution for this problem. */ @@ -1323,6 +1332,10 @@ struct df_live_problem_data bitmap *out; }; +/* Scratch var used by transfer functions. This is used to implement + an optimization to reduce the amount of space used to compute the + combined lr and live analysis. */ +static bitmap df_live_scratch; /* Set basic block info. */ @@ -1366,6 +1379,8 @@ df_live_alloc (bitmap all_blocks ATTRIBUTE_UNUSED) if (!df_live->block_pool) df_live->block_pool = create_alloc_pool ("df_live_block pool", sizeof (struct df_live_bb_info), 100); + if (!df_live_scratch) + df_live_scratch = BITMAP_ALLOC (NULL); df_grow_bb_info (df_live); @@ -1401,7 +1416,7 @@ df_live_reset (bitmap all_blocks) EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi) { - struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index); + struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index); gcc_assert (bb_info); bitmap_clear (bb_info->in); bitmap_clear (bb_info->out); @@ -1420,13 +1435,6 @@ df_live_bb_local_compute (unsigned int bb_index) struct df_ref **def_rec; int luid = 0; - for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++) - { - struct df_ref *def = *def_rec; - if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) - bitmap_set_bit (bb_info->gen, DF_REF_REGNO (def)); - } - FOR_BB_INSNS (bb, insn) { unsigned int uid = INSN_UID (insn); @@ -1467,8 +1475,7 @@ df_live_bb_local_compute (unsigned int bb_index) for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++) { struct df_ref *def = *def_rec; - if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0) - bitmap_set_bit (bb_info->gen, DF_REF_REGNO (def)); + bitmap_set_bit (bb_info->gen, DF_REF_REGNO (def)); } } @@ -1504,13 +1511,16 @@ df_live_init (bitmap all_blocks) EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi) { struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index); + struct df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (bb_index); - bitmap_copy (bb_info->out, bb_info->gen); + /* No register may reach a location where it is not used. Thus + we trim the rr result to the places where it is used. */ + bitmap_and (bb_info->out, bb_info->gen, bb_lr_info->out); bitmap_clear (bb_info->in); } } -/* Confluence function that ignores fake edges. */ +/* Forward confluence function that ignores fake edges. */ static void df_live_confluence_n (edge e) @@ -1525,25 +1535,35 @@ df_live_confluence_n (edge e) } -/* Transfer function. */ +/* Transfer function for the forwards must-initialized problem. */ static bool df_live_transfer_function (int bb_index) { struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index); + struct df_lr_bb_info *bb_lr_info = df_lr_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 lr set was anded + in. */ + bitmap_and (df_live_scratch, gen, bb_lr_info->out); + /* No register may reach a location where it is not used. Thus + we trim the rr result to the places where it is used. */ + bitmap_and_into (in, bb_lr_info->in); + + return bitmap_ior_and_compl (out, df_live_scratch, in, kill); } -/* And the LR and UR info to produce the LIVE info. */ +/* And the LR info with the must-initialized registers, to produce the LIVE info. */ static void -df_live_local_finalize (bitmap all_blocks) +df_live_finalize (bitmap all_blocks) { if (df_live->solutions_dirty) @@ -1591,6 +1611,9 @@ df_live_free (void) free_alloc_pool (df_live->block_pool); df_live->block_info_size = 0; free (df_live->block_info); + + if (df_live_scratch) + BITMAP_FREE (df_live_scratch); } BITMAP_FREE (df_live->out_of_date_transfer_functions); free (df_live); @@ -1731,7 +1754,7 @@ static struct df_problem problem_LIVE = NULL, /* Confluence operator 0. */ df_live_confluence_n, /* Confluence operator n. */ df_live_transfer_function, /* Transfer function. */ - df_live_local_finalize, /* Finalize function. */ + df_live_finalize, /* Finalize function. */ df_live_free, /* Free all of the problem information. */ df_live_free, /* Remove this problem from the stack of dataflow problems. */ NULL, /* Debugging. */ @@ -2916,10 +2939,6 @@ static struct df_problem problem_NOTE = NULL, /* Debugging end block. */ NULL, /* Incremental solution verify start. */ NULL, /* Incremental solution verify end. */ - - /* Technically this is only dependent on the live registers problem - but it will produce information if built one of uninitialized - register problems (UR, UREC) is also run. */ &problem_LR, /* Dependent problem. */ TV_DF_NOTE, /* Timing variable. */ false /* Reset blocks on dropping out of blocks_to_analyze. */