aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/df-core.c48
-rw-r--r--gcc/df-problems.c115
-rw-r--r--gcc/df-scan.c28
-rw-r--r--gcc/df.h11
5 files changed, 209 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e3ebf98..8874f87 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2005-01-21 Kenneth Zadeck <zadeck@naturalbridge.com>
+
+ * 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 <bje@au.ibm.com>
* varasm.c (assemble_real): Initialise data array.
diff --git a/gcc/df-core.c b/gcc/df-core.c
index 87d9324..a0ed23c 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 ecc8eab..fdba180 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 8f19956..bba89e7 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 a353d36..f2e7bef 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. */