defs and uses are only there if DF_HARD_REGS was specified when the
df instance was created.
- Artificial defs and uses occur at the beginning blocks that are the
- destination of eh edges. The defs come from the registers
- specified in EH_RETURN_DATA_REGNO and the uses come from the
- registers specified in ED_USES. Logically these defs and uses
- should really occur along the eh edge, but there is no convienent
- way to do this. Artificial edges that occur at the beginning of
- the block have the DF_REF_AT_TOP flag set.
-
- Artificial uses also occur at the end of all blocks. These arise
- from the hard registers that are always live, such as the stack
- register and are put there to keep the code from forgetting about
- them.
+ Artificial defs and uses occur both at the beginning and ends of blocks.
+
+ For blocks that area at the destination of eh edges, the
+ artificial uses and defs occur at the beginning. The defs relate
+ to the registers specified in EH_RETURN_DATA_REGNO and the uses
+ relate to the registers specified in ED_USES. Logically these
+ defs and uses should really occur along the eh edge, but there is
+ no convenient way to do this. Artificial edges that occur at the
+ beginning of the block have the DF_REF_AT_TOP flag set.
+
+ Artificial uses occur at the end of all blocks. These arise from
+ the hard registers that are always live, such as the stack
+ register and are put there to keep the code from forgetting about
+ them.
+
+ Artifical defs occur at the end of the entry block. These arise
+ from registers that are live at entry to the function.
2) All of the uses and defs associated with each pseudo or hard
register are linked in a bidirectional chain. These are called
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.
----------------------------------------------------------------------------*/
struct df *
df_init (int flags)
{
- struct df *df = xcalloc (1, sizeof (struct df));
+ struct df *df = XCNEW (struct df);
df->flags = flags;
/* This is executed once per compilation to initialize platform
return dflow;
/* Make a new one and add it to the end. */
- dflow = xcalloc (1, sizeof (struct dataflow));
+ dflow = XCNEW (struct dataflow);
dflow->df = df;
dflow->problem = problem;
df->problems_in_order[df->num_problems_defined++] = dflow;
{
if (blocks)
{
- if (!df->blocks_to_analyze)
- df->blocks_to_analyze = BITMAP_ALLOC (NULL);
+ if (df->blocks_to_analyze)
+ {
+ int p;
+ bitmap diff = BITMAP_ALLOC (NULL);
+ bitmap_and_compl (diff, df->blocks_to_analyze, blocks);
+ for (p = df->num_problems_defined - 1; p >= 0 ;p--)
+ {
+ struct dataflow *dflow = df->problems_in_order[p];
+ 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;
+
+ EXECUTE_IF_SET_IN_BITMAP (diff, 0, bb_index, bi)
+ {
+ basic_block bb = BASIC_BLOCK (bb_index);
+ 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 (diff);
+ }
+ else
+ {
+ /* 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
int i;
for (i = 0; i < df->num_problems_defined; i++)
- (*df->problems_in_order[i]->problem->free_fun) (df->problems_in_order[i]);
+ df->problems_in_order[i]->problem->free_fun (df->problems_in_order[i]);
free (df);
}
if (!TEST_BIT (dataflow->considered, e->src->index))
continue;
- (*dataflow->problem->con_fun_n) (dataflow, e);
+ dataflow->problem->con_fun_n (dataflow, e);
}
- else if (*dataflow->problem->con_fun_0)
- (*dataflow->problem->con_fun_0) (dataflow, bb);
+ else if (dataflow->problem->con_fun_0)
+ dataflow->problem->con_fun_0 (dataflow, bb);
- result_changed = (*dataflow->problem->trans_fun) (dataflow, i);
+ result_changed = dataflow->problem->trans_fun (dataflow, i);
if (!result_changed || single_pass)
return;
if (!TEST_BIT (dataflow->considered, e->dest->index))
continue;
- (*dataflow->problem->con_fun_n) (dataflow, e);
+ dataflow->problem->con_fun_n (dataflow, e);
}
- else if (*dataflow->problem->con_fun_0)
- (*dataflow->problem->con_fun_0) (dataflow, bb);
+ else if (dataflow->problem->con_fun_0)
+ dataflow->problem->con_fun_0 (dataflow, bb);
- result_changed = (*dataflow->problem->trans_fun) (dataflow, i);
+ result_changed = dataflow->problem->trans_fun (dataflow, i);
if (!result_changed || single_pass)
return;
SET_BIT (pending, idx);
};
- (*dataflow->problem->init_fun) (dataflow, blocks_to_init);
+ dataflow->problem->init_fun (dataflow, blocks_to_init);
while (1)
{
int *postorder, int n_blocks, bool single_pass)
{
/* (Re)Allocate the datastructures necessary to solve the problem. */
- if (*dflow->problem->alloc_fun)
- (*dflow->problem->alloc_fun) (dflow, blocks_to_scan);
+ if (dflow->problem->alloc_fun)
+ dflow->problem->alloc_fun (dflow, blocks_to_scan);
/* Set up the problem and compute the local information. This
function is passed both the blocks_to_consider and the
blocks_to_scan because the RD and RU problems require the entire
function to be rescanned if they are going to be updated. */
- if (*dflow->problem->local_compute_fun)
- (*dflow->problem->local_compute_fun) (dflow, blocks_to_consider, blocks_to_scan);
+ if (dflow->problem->local_compute_fun)
+ dflow->problem->local_compute_fun (dflow, blocks_to_consider, blocks_to_scan);
/* Solve the equations. */
- if (*dflow->problem->dataflow_fun)
- (*dflow->problem->dataflow_fun) (dflow, blocks_to_consider, blocks_to_init,
- postorder, n_blocks, single_pass);
+ if (dflow->problem->dataflow_fun)
+ dflow->problem->dataflow_fun (dflow, blocks_to_consider, blocks_to_init,
+ postorder, n_blocks, single_pass);
/* Massage the solution. */
- if (*dflow->problem->finalize_fun)
- (*dflow->problem->finalize_fun) (dflow, blocks_to_consider);
+ if (dflow->problem->finalize_fun)
+ dflow->problem->finalize_fun (dflow, blocks_to_consider);
}
void
df_analyze (struct df *df)
{
- int *postorder = xmalloc (sizeof (int) *last_basic_block);
+ int *postorder = XNEWVEC (int, last_basic_block);
bitmap current_all_blocks = BITMAP_ALLOC (NULL);
int n_blocks;
int i;
BITMAP_FREE (df->blocks_to_scan);
df->blocks_to_scan = NULL;
+ free (postorder);
}
for (p = 0; p < df->num_problems_defined; p++)
{
struct dataflow *dflow = df->problems_in_order[p];
- if (*dflow->problem->free_bb_fun)
+ if (dflow->problem->free_bb_fun)
{
df_grow_bb_info (dflow);
memcpy (problem_temps, dflow->block_info, size);
These are from orphaned blocks. */
for (i = NUM_FIXED_BLOCKS; i < last_basic_block; i++)
{
- if (problem_temps[i])
- (*dflow->problem->free_bb_fun) (dflow, problem_temps[i]);
+ basic_block bb = BASIC_BLOCK (i);
+ if (problem_temps[i] && bb)
+ dflow->problem->free_bb_fun
+ (dflow, bb, problem_temps[i]);
}
}
}
df->def_info.bitmap_size, df->use_info.bitmap_size);
for (i = 0; i < df->num_problems_defined; i++)
- (*df->problems_in_order[i]->problem->dump_fun) (df->problems_in_order[i], file);
+ df->problems_in_order[i]->problem->dump_fun (df->problems_in_order[i], file);
fprintf (file, "\n");
}