diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e3ebf98c1b1..8874f87c856 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2005-01-21 Kenneth Zadeck + + * df-scan.c (problem_SCAN): Added NULL reset function. + (df_scan_reset_blocks): Added code to call reset block function + (df_bb_refs_delete) Fixed comment. + (df_insn_refs_delete): Made tolerant of deleting non existent info + for dataflow problems that need to be reset. + * df-core.c (df_set_blocks): Ditto. + * df.h (struct df_problem): Added reset_fun. + * df-problems.c (problem_RU, problem_RD, problem_LR, problem_UR, + problem_UREC, problem_CHAIN, problem_RI): Initialized reset_fun field. + (df_chain_insn_reset, df_chain_bb_reset, df_chain_reset): New + functions to clear out all references to def-use or use-def chains. + 2006-01-21 Ben Elliston * varasm.c (assemble_real): Initialise data array. diff --git a/gcc/df-core.c b/gcc/df-core.c index 87d9324d80f..a0ed23caa16 100644 --- a/gcc/df-core.c +++ b/gcc/df-core.c @@ -292,6 +292,8 @@ are write-only operations. static struct df *ddf = NULL; struct df *shared_df = NULL; +static void * df_get_bb_info (struct dataflow *, unsigned int); +static void df_set_bb_info (struct dataflow *, unsigned int, void *); /*---------------------------------------------------------------------------- Functions to create, destroy and manipulate an instance of df. ----------------------------------------------------------------------------*/ @@ -358,11 +360,14 @@ df_set_blocks (struct df *df, bitmap blocks) { int p; bitmap diff = BITMAP_ALLOC (NULL); + bitmap all = BITMAP_ALLOC (NULL); bitmap_and_compl (diff, df->blocks_to_analyze, blocks); - for (p = 0; p < df->num_problems_defined; p++) + for (p = df->num_problems_defined - 1; p >= 0 ;p--) { struct dataflow *dflow = df->problems_in_order[p]; - if (*dflow->problem->free_bb_fun) + if (*dflow->problem->reset_fun) + (*dflow->problem->reset_fun) (dflow, df->blocks_to_analyze); + else if (*dflow->problem->free_bb_fun) { bitmap_iterator bi; unsigned int bb_index; @@ -370,15 +375,50 @@ df_set_blocks (struct df *df, bitmap blocks) EXECUTE_IF_SET_IN_BITMAP (diff, 0, bb_index, bi) { basic_block bb = BASIC_BLOCK (bb_index); - (*dflow->problem->free_bb_fun) (dflow, bb, diff); + if (bb) + { + (*dflow->problem->free_bb_fun) + (dflow, bb, df_get_bb_info (dflow, bb_index)); + df_set_bb_info (dflow, bb_index, NULL); + } } } } + BITMAP_FREE (all); BITMAP_FREE (diff); } else - df->blocks_to_analyze = BITMAP_ALLOC (NULL); + { + /* If we have not actually run scanning before, do not try + to clear anything. */ + struct dataflow *scan_dflow = df->problems_by_index [DF_SCAN]; + if (scan_dflow->problem_data) + { + bitmap blocks_to_reset = NULL; + int p; + for (p = df->num_problems_defined - 1; p >= 0 ;p--) + { + struct dataflow *dflow = df->problems_in_order[p]; + if (*dflow->problem->reset_fun) + { + if (!blocks_to_reset) + { + basic_block bb; + blocks_to_reset = BITMAP_ALLOC (NULL); + FOR_ALL_BB(bb) + { + bitmap_set_bit (blocks_to_reset, bb->index); + } + } + (*dflow->problem->reset_fun) (dflow, blocks_to_reset); + } + } + if (blocks_to_reset) + BITMAP_FREE (blocks_to_reset); + } + df->blocks_to_analyze = BITMAP_ALLOC (NULL); + } bitmap_copy (df->blocks_to_analyze, blocks); } else diff --git a/gcc/df-problems.c b/gcc/df-problems.c index ecc8eab6627..fdba180906e 100644 --- a/gcc/df-problems.c +++ b/gcc/df-problems.c @@ -777,6 +777,7 @@ static struct df_problem problem_RU = DF_RU, /* Problem id. */ DF_BACKWARD, /* Direction. */ df_ru_alloc, /* Allocate the problem specific data. */ + NULL, /* Reset global information. */ df_ru_free_bb_info, /* Free basic block info. */ df_ru_local_compute, /* Local compute function. */ df_ru_init_solution, /* Init the solution specific data. */ @@ -1269,6 +1270,7 @@ static struct df_problem problem_RD = DF_RD, /* Problem id. */ DF_FORWARD, /* Direction. */ df_rd_alloc, /* Allocate the problem specific data. */ + NULL, /* Reset global information. */ df_rd_free_bb_info, /* Free basic block info. */ df_rd_local_compute, /* Local compute function. */ df_rd_init_solution, /* Init the solution specific data. */ @@ -1655,6 +1657,7 @@ static struct df_problem problem_LR = DF_LR, /* Problem id. */ DF_BACKWARD, /* Direction. */ df_lr_alloc, /* Allocate the problem specific data. */ + NULL, /* Reset global information. */ df_lr_free_bb_info, /* Free basic block info. */ df_lr_local_compute, /* Local compute function. */ df_lr_init, /* Init the solution specific data. */ @@ -1991,6 +1994,7 @@ static struct df_problem problem_UR = DF_UR, /* Problem id. */ DF_FORWARD, /* Direction. */ df_ur_alloc, /* Allocate the problem specific data. */ + NULL, /* Reset global information. */ df_ur_free_bb_info, /* Free basic block info. */ df_ur_local_compute, /* Local compute function. */ df_ur_init, /* Init the solution specific data. */ @@ -2615,6 +2619,7 @@ static struct df_problem problem_UREC = DF_UREC, /* Problem id. */ DF_FORWARD, /* Direction. */ df_urec_alloc, /* Allocate the problem specific data. */ + NULL, /* Reset global information. */ df_urec_free_bb_info, /* Free basic block info. */ df_urec_local_compute, /* Local compute function. */ df_urec_init, /* Init the solution specific data. */ @@ -2702,6 +2707,114 @@ df_chain_alloc (struct dataflow *dflow, } +/* Reset all def_use and use_def chains in INSN. */ + +static void +df_chain_insn_reset (struct dataflow *dflow, rtx insn) +{ + struct df *df = dflow->df; + struct df_chain_problem_data *problem_data = + (struct df_chain_problem_data *) dflow->problem_data; + unsigned int uid = INSN_UID (insn); + struct df_insn_info *insn_info = NULL; + struct df_ref *ref; + + if (uid < df->insns_size) + insn_info = DF_INSN_UID_GET (df, uid); + + if (insn_info) + { + if (problem_data->flags & DF_DU_CHAIN) + { + ref = insn_info->defs; + while (ref) + { + ref->chain = NULL; + ref = ref->next_ref; + } + } + + if (problem_data->flags & DF_UD_CHAIN) + { + ref = insn_info->uses; + while (ref) + { + ref->chain = NULL; + ref = ref->next_ref; + } + } + } +} + + +/* Reset all def_use and use_def chains in basic block. */ + +static void +df_chain_bb_reset (struct dataflow *dflow, unsigned int bb_index) +{ + struct df *df = dflow->df; + struct df_chain_problem_data *problem_data = + (struct df_chain_problem_data *) dflow->problem_data; + rtx insn; + basic_block bb = BASIC_BLOCK (bb_index); + + /* Some one deleted the basic block out from under us. */ + if (!bb) + return; + + FOR_BB_INSNS (bb, insn) + { + if (INSN_P (insn)) + { + /* Record defs within INSN. */ + df_chain_insn_reset (dflow, insn); + } + } + + /* Get rid of any chains in artifical uses or defs. */ + if (problem_data->flags & DF_DU_CHAIN) + { + struct df_ref *def; + def = df_get_artificial_defs (df, bb_index); + while (def) + { + def->chain = NULL; + def = def->next_ref; + } + } + + if (problem_data->flags & DF_UD_CHAIN) + { + struct df_ref *use; + use = df_get_artificial_uses (df, bb_index); + while (use) + { + use->chain = NULL; + use = use->next_ref; + } + } +} + + +/* Reset all of the chains when the set of basic blocks changes. */ + + +static void +df_chain_reset (struct dataflow *dflow, bitmap blocks_to_clear) +{ + bitmap_iterator bi; + unsigned int bb_index; + + EXECUTE_IF_SET_IN_BITMAP (blocks_to_clear, 0, bb_index, bi) + { + df_chain_bb_reset (dflow, bb_index); + } + + free_alloc_pool (dflow->block_pool); + dflow->block_pool = NULL; +} + + /* Create the chains for a list of USEs. */ static void @@ -2917,6 +3030,7 @@ static struct df_problem problem_CHAIN = DF_CHAIN, /* Problem id. */ DF_NONE, /* Direction. */ df_chain_alloc, /* Allocate the problem specific data. */ + df_chain_reset, /* Reset global information. */ NULL, /* Free basic block info. */ NULL, /* Local compute function. */ NULL, /* Init the solution specific data. */ @@ -3092,6 +3206,7 @@ static struct df_problem problem_RI = DF_RI, /* Problem id. */ DF_NONE, /* Direction. */ df_ri_alloc, /* Allocate the problem specific data. */ + NULL, /* Reset global information. */ NULL, /* Free basic block info. */ df_ri_compute, /* Local compute function. */ NULL, /* Init the solution specific data. */ diff --git a/gcc/df-scan.c b/gcc/df-scan.c index 8f1995660a3..bba89e7c891 100644 --- a/gcc/df-scan.c +++ b/gcc/df-scan.c @@ -304,6 +304,7 @@ static struct df_problem problem_SCAN = DF_SCAN, /* Problem id. */ DF_NONE, /* Direction. */ df_scan_alloc, /* Allocate the problem specific data. */ + NULL, /* Reset global information. */ df_scan_free_bb_info, /* Free basic block info. */ NULL, /* Local compute function. */ NULL, /* Init the solution specific data. */ @@ -426,6 +427,8 @@ df_rescan_blocks (struct df *df, bitmap blocks) if (blocks) { + int i; + /* Need to assure that there are space in all of the tables. */ unsigned int insn_num = get_max_uid () + 1; insn_num += insn_num / 4; @@ -443,6 +446,24 @@ df_rescan_blocks (struct df *df, bitmap blocks) df->def_info.add_refs_inline = true; df->use_info.add_refs_inline = true; + for (i = df->num_problems_defined; i; i--) + { + bitmap blocks_to_reset = NULL; + if (*dflow->problem->reset_fun) + { + if (!blocks_to_reset) + { + blocks_to_reset = BITMAP_ALLOC (NULL); + bitmap_copy (blocks_to_reset, local_blocks_to_scan); + if (df->blocks_to_scan) + bitmap_ior_into (blocks_to_reset, df->blocks_to_scan); + } + (*dflow->problem->reset_fun) (dflow, blocks_to_reset); + } + if (blocks_to_reset) + BITMAP_FREE (blocks_to_reset); + } + df_refs_delete (dflow, local_blocks_to_scan); /* This may be a mistake, but if an explicit blocks is passed in @@ -727,11 +748,14 @@ df_insn_refs_delete (struct dataflow *dflow, rtx insn) { struct df *df = dflow->df; unsigned int uid = INSN_UID (insn); - struct df_insn_info *insn_info = DF_INSN_UID_GET (df, uid); + struct df_insn_info *insn_info = NULL; struct df_ref *ref; struct df_scan_problem_data *problem_data = (struct df_scan_problem_data *) dflow->problem_data; + if (uid < df->insns_size) + insn_info = DF_INSN_UID_GET (df, uid); + if (insn_info) { ref = insn_info->defs; @@ -769,7 +793,7 @@ df_bb_refs_delete (struct dataflow *dflow, int bb_index) } } - /* Get rid of any artifical uses. */ + /* Get rid of any artifical uses or defs. */ if (bb_info) { def = bb_info->artificial_defs; diff --git a/gcc/df.h b/gcc/df.h index a353d36ce11..f2e7bef787a 100644 --- a/gcc/df.h +++ b/gcc/df.h @@ -67,6 +67,14 @@ enum df_flow_dir /* Allocate the problem specific data. */ typedef void (*df_alloc_function) (struct dataflow *, bitmap); +/* This function is called if the problem has global data that needs + to be cleared when ever the set of blocks changes. The bitmap + contains the set of blocks that may require special attention. + This call is only made if some of the blocks are going to change. + If everything is to be deleted, the wholesale deletion mechanisms + apply. */ +typedef void (*df_reset_function) (struct dataflow *, bitmap); + /* Free the basic block info. Called from the block reordering code to get rid of the blocks that have been squished down. */ typedef void (*df_free_bb_function) (struct dataflow *, basic_block, void *); @@ -108,6 +116,7 @@ struct df_problem { unsigned int id; enum df_flow_dir dir; /* Dataflow direction. */ df_alloc_function alloc_fun; + df_reset_function reset_fun; df_free_bb_function free_bb_fun; df_local_compute_function local_compute_fun; df_init_function init_fun; @@ -216,7 +225,7 @@ struct df_ref basic_block bb; /* Basic block containing the instruction. */ rtx insn; /* Insn containing ref. NB: THIS MAY BE NULL. */ rtx *loc; /* The location of the reg. */ - struct df_link *chain; /* Head of def-use, use-def or bi chain. */ + struct df_link *chain; /* Head of def-use, use-def. */ unsigned int id; /* Location in table. */ enum df_ref_type type; /* Type of ref. */ enum df_ref_flags flags; /* Various flags. */