unsigned int use_sites_size; /* Size of use_sites. */
/* The set of defs to regs invalidated by call. */
bitmap sparse_invalidated_by_call;
- /* The set of defs to regs invalidate by call for ru. */
+ /* The set of defs to regs invalidated by call for ru. */
bitmap dense_invalidated_by_call;
};
}
else
{
- struct df_ru_problem_data *problem_data =
- xmalloc (sizeof (struct df_ru_problem_data));
+ struct df_ru_problem_data *problem_data = XNEW (struct df_ru_problem_data);
dflow->problem_data = problem_data;
- problem_data->use_sites = xcalloc (reg_size, sizeof (bitmap));
+ problem_data->use_sites = XCNEWVEC (bitmap, reg_size);
problem_data->use_sites_size = reg_size;
problem_data->sparse_invalidated_by_call = BITMAP_ALLOC (NULL);
problem_data->dense_invalidated_by_call = BITMAP_ALLOC (NULL);
static void
df_ru_bb_local_compute_process_def (struct dataflow *dflow,
struct df_ru_bb_info *bb_info,
- struct df_ref *def)
+ struct df_ref *def,
+ enum df_ref_flags top_flag)
{
struct df *df = dflow->df;
while (def)
{
- unsigned int regno = DF_REF_REGNO (def);
- unsigned int begin = DF_REG_USE_GET (df, regno)->begin;
- unsigned int n_uses = DF_REG_USE_GET (df, regno)->n_refs;
- if (!bitmap_bit_p (seen_in_block, regno))
+ if (top_flag == (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
{
- /* The first def for regno, causes the kill info to be
- generated and the gen information to cleared. */
- if (!bitmap_bit_p (seen_in_insn, regno))
+ unsigned int regno = DF_REF_REGNO (def);
+ unsigned int begin = DF_REG_USE_GET (df, regno)->begin;
+ unsigned int n_uses = DF_REG_USE_GET (df, regno)->n_refs;
+ if (!bitmap_bit_p (seen_in_block, regno))
{
- if (n_uses > DF_SPARSE_THRESHOLD)
+ /* The first def for regno, causes the kill info to be
+ generated and the gen information to cleared. */
+ if (!bitmap_bit_p (seen_in_insn, regno))
{
- bitmap_set_bit (bb_info->sparse_kill, regno);
- bitmap_clear_range (bb_info->gen, begin, n_uses);
- }
- else
- {
- struct df_ru_problem_data *problem_data =
- (struct df_ru_problem_data *) dflow->problem_data;
- bitmap uses =
- df_ref_bitmap (problem_data->use_sites, regno,
- begin, n_uses);
- bitmap_ior_into (bb_info->kill, uses);
- bitmap_and_compl_into (bb_info->gen, uses);
+ if (n_uses > DF_SPARSE_THRESHOLD)
+ {
+ bitmap_set_bit (bb_info->sparse_kill, regno);
+ bitmap_clear_range (bb_info->gen, begin, n_uses);
+ }
+ else
+ {
+ struct df_ru_problem_data * problem_data =
+ (struct df_ru_problem_data *)dflow->problem_data;
+ bitmap uses =
+ df_ref_bitmap (problem_data->use_sites, regno,
+ begin, n_uses);
+ bitmap_ior_into (bb_info->kill, uses);
+ bitmap_and_compl_into (bb_info->gen, uses);
+ }
}
+ bitmap_set_bit (seen_in_insn, regno);
}
- bitmap_set_bit (seen_in_insn, regno);
}
def = def->next_ref;
}
df_get_artificial_uses (df, bb_index),
DF_REF_AT_TOP);
#endif
-
- /* Process the artificial defs first since these are at the top of
- the block. */
df_ru_bb_local_compute_process_def (dflow, bb_info,
- df_get_artificial_defs (df, bb_index));
+ df_get_artificial_defs (df, bb_index),
+ DF_REF_AT_TOP);
FOR_BB_INSNS (bb, insn)
{
continue;
df_ru_bb_local_compute_process_def (dflow, bb_info,
- DF_INSN_UID_GET (df, uid)->defs);
+ DF_INSN_UID_GET (df, uid)->defs, 0);
/* The use processing must happen after the defs processing even
though the uses logically happen first since the defs clear
/* Process the hardware registers that are always live. */
df_ru_bb_local_compute_process_use (bb_info,
df_get_artificial_uses (df, bb_index), 0);
+
+ df_ru_bb_local_compute_process_def (dflow, bb_info,
+ df_get_artificial_defs (df, bb_index), 0);
}
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. */
}
else
{
- struct df_rd_problem_data *problem_data =
- xmalloc (sizeof (struct df_rd_problem_data));
+ struct df_rd_problem_data *problem_data = XNEW (struct df_rd_problem_data);
dflow->problem_data = problem_data;
- problem_data->def_sites = xcalloc (reg_size, sizeof (bitmap));
+ problem_data->def_sites = XCNEWVEC (bitmap, reg_size);
problem_data->def_sites_size = reg_size;
problem_data->sparse_invalidated_by_call = BITMAP_ALLOC (NULL);
problem_data->dense_invalidated_by_call = BITMAP_ALLOC (NULL);
static void
df_rd_bb_local_compute_process_def (struct dataflow *dflow,
struct df_rd_bb_info *bb_info,
- struct df_ref *def)
+ struct df_ref *def,
+ enum df_ref_flags top_flag)
{
struct df *df = dflow->df;
while (def)
{
- unsigned int regno = DF_REF_REGNO (def);
- unsigned int begin = DF_REG_DEF_GET (df, regno)->begin;
- unsigned int n_defs = DF_REG_DEF_GET (df, regno)->n_refs;
-
- /* Only the last def(s) for a regno in the block has any
- effect. */
- if (!bitmap_bit_p (seen_in_block, regno))
+ if (top_flag == (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
{
- /* The first def for regno in insn gets to knock out the
- defs from other instructions. */
- if (!bitmap_bit_p (seen_in_insn, regno))
+ unsigned int regno = DF_REF_REGNO (def);
+ unsigned int begin = DF_REG_DEF_GET (df, regno)->begin;
+ unsigned int n_defs = DF_REG_DEF_GET (df, regno)->n_refs;
+
+ /* Only the last def(s) for a regno in the block has any
+ effect. */
+ if (!bitmap_bit_p (seen_in_block, regno))
{
- if (n_defs > DF_SPARSE_THRESHOLD)
+ /* The first def for regno in insn gets to knock out the
+ defs from other instructions. */
+ if (!bitmap_bit_p (seen_in_insn, regno))
{
- bitmap_set_bit (bb_info->sparse_kill, regno);
- bitmap_clear_range (bb_info->gen, begin, n_defs);
- }
- else
- {
- struct df_rd_problem_data *problem_data =
- (struct df_rd_problem_data *) dflow->problem_data;
- bitmap defs =
- df_ref_bitmap (problem_data->def_sites, regno,
- begin, n_defs);
- bitmap_ior_into (bb_info->kill, defs);
- bitmap_and_compl_into (bb_info->gen, defs);
+ if (n_defs > DF_SPARSE_THRESHOLD)
+ {
+ bitmap_set_bit (bb_info->sparse_kill, regno);
+ bitmap_clear_range(bb_info->gen, begin, n_defs);
+ }
+ else
+ {
+ struct df_rd_problem_data * problem_data =
+ (struct df_rd_problem_data *)dflow->problem_data;
+ bitmap defs =
+ df_ref_bitmap (problem_data->def_sites, regno,
+ begin, n_defs);
+ bitmap_ior_into (bb_info->kill, defs);
+ bitmap_and_compl_into (bb_info->gen, defs);
+ }
}
+
+ bitmap_set_bit (seen_in_insn, regno);
+ /* All defs for regno in the instruction may be put into
+ the gen set. */
+ if (! (DF_REF_FLAGS (def) & DF_REF_CLOBBER))
+ bitmap_set_bit (bb_info->gen, DF_REF_ID (def));
}
-
- bitmap_set_bit (seen_in_insn, regno);
- /* All defs for regno in the instruction may be put into
- the gen set. */
- if (! (DF_REF_FLAGS (def) & DF_REF_CLOBBER))
- bitmap_set_bit (bb_info->gen, DF_REF_ID (def));
}
def = def->next_ref;
}
bitmap_clear (seen_in_block);
bitmap_clear (seen_in_insn);
+ df_rd_bb_local_compute_process_def (dflow, bb_info,
+ df_get_artificial_defs (df, bb_index), 0);
+
FOR_BB_INSNS_REVERSE (bb, insn)
{
unsigned int uid = INSN_UID (insn);
continue;
df_rd_bb_local_compute_process_def (dflow, bb_info,
- DF_INSN_UID_GET (df, uid)->defs);
+ DF_INSN_UID_GET (df, uid)->defs, 0);
/* This complex dance with the two bitmaps is required because
instructions can assign twice to the same pseudo. This
bitmap_clear (seen_in_insn);
}
- /* Process the artificial defs last since we are going backwards
- thur the block and these are logically at the start. */
+ /* Process the artificial defs at the top of the block last since we
+ are going backwards through the block and these are logically at
+ the start. */
df_rd_bb_local_compute_process_def (dflow, bb_info,
- df_get_artificial_defs (df, bb_index));
+ df_get_artificial_defs (df, bb_index),
+ DF_REF_AT_TOP);
}
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. */
struct df_ref *def;
struct df_ref *use;
+ /* Process the registers set in an exception handler. */
+ for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
+ if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
+ {
+ unsigned int dregno = DF_REF_REGNO (def);
+ bitmap_set_bit (bb_info->def, dregno);
+ bitmap_clear_bit (bb_info->use, dregno);
+ }
+
/* Process the hardware registers that are always live. */
for (use = df_get_artificial_uses (df, bb_index); use; use = use->next_ref)
/* Add use to set of uses in this BB. */
/* Process the registers set in an exception handler. */
for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
- {
- unsigned int dregno = DF_REF_REGNO (def);
- bitmap_set_bit (bb_info->def, dregno);
- bitmap_clear_bit (bb_info->use, dregno);
- }
-
+ if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+ {
+ unsigned int dregno = DF_REF_REGNO (def);
+ bitmap_set_bit (bb_info->def, dregno);
+ bitmap_clear_bit (bb_info->use, dregno);
+ }
+
#ifdef EH_USES
/* Process the uses that are live into an exception handler. */
for (use = df_get_artificial_uses (df, bb_index); use; use = use->next_ref)
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. */
bitmap_clear (seen_in_block);
bitmap_clear (seen_in_insn);
+ for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
+ if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
+ {
+ unsigned int regno = DF_REF_REGNO (def);
+ if (!bitmap_bit_p (seen_in_block, regno))
+ {
+ bitmap_set_bit (seen_in_block, regno);
+ bitmap_set_bit (bb_info->gen, regno);
+ }
+ }
+
FOR_BB_INSNS_REVERSE (bb, insn)
{
unsigned int uid = INSN_UID (insn);
}
for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
- {
- unsigned int regno = DF_REF_REGNO (def);
- if (!bitmap_bit_p (seen_in_block, regno))
- {
- bitmap_set_bit (seen_in_block, regno);
- bitmap_set_bit (bb_info->gen, regno);
- }
- }
+ if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+ {
+ unsigned int regno = DF_REF_REGNO (def);
+ if (!bitmap_bit_p (seen_in_block, regno))
+ {
+ bitmap_set_bit (seen_in_block, regno);
+ bitmap_set_bit (bb_info->gen, regno);
+ }
+ }
}
struct df_ur_bb_info *bb_info = df_ur_get_bb_info (dflow, bb_index);
struct df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (lr_dflow, bb_index);
- bitmap_ior_into (bb_info->in, df_all_hard_regs);
- bitmap_ior_into (bb_info->out, df_all_hard_regs);
-
/* 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 (bb_info->in, bb_lr_info->in);
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. */
if (!dflow->problem_data)
{
- problem_data = xmalloc (sizeof (struct df_urec_problem_data));
+ problem_data = XNEW (struct df_urec_problem_data);
dflow->problem_data = problem_data;
}
problem_data->earlyclobbers_found = false;
struct df_ref *def;
for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
- {
- unsigned int regno = DF_REF_REGNO (def);
- bitmap_set_bit (bb_info->gen, regno);
- }
-
+ if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+ {
+ unsigned int regno = DF_REF_REGNO (def);
+ bitmap_set_bit (bb_info->gen, regno);
+ }
+
FOR_BB_INSNS (bb, insn)
{
if (INSN_P (insn))
}
}
}
+
+ for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
+ if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
+ {
+ unsigned int regno = DF_REF_REGNO (def);
+ bitmap_set_bit (bb_info->gen, regno);
+ }
+
}
{
struct df_urec_bb_info *bb_info = df_urec_get_bb_info (dflow, bb_index);
- /* FIXME: This is a hack, it has been copied over from
- make_accurate_live_analysis by Vlad. Most likely it is necessary
- because the generation of gen and kill information for hardware
- registers in ur is a subset of what is really necessary and what
- is done for the lr problem. */
-
- /* Inside the register allocator, partial availability is only
- allowed for the psuedo registers. To implement this, the rr is
- initially iored with a mask ones for the hard registers and zeros
- for the pseudos before being iterated. This means that each
- hardware register will be live unless explicitly killed by some
- statement. Eventually most of these bit will die because the
- results of rr are anded with the results of lr before being used.
- Outside of register allocation, a more conservative strategy of
- completely ignoring the unintialized registers is imployed in the
- finalizer function. */
- if (df_state & DF_SCAN_GLOBAL)
- {
- bitmap_ior (bb_info->out, bb_info->gen, df_all_hard_regs);
- bitmap_copy (bb_info->in, df_all_hard_regs);
- }
- else
- {
- bitmap_copy (bb_info->out, bb_info->gen);
- bitmap_clear (bb_info->in);
- }
+ bitmap_copy (bb_info->out, bb_info->gen);
+ bitmap_clear (bb_info->in);
}
}
#endif
}
- if (!(df_state & DF_SCAN_GLOBAL))
- {
- bitmap_ior_into (bb_info->in, df_all_hard_regs);
- bitmap_ior_into (bb_info->out, df_all_hard_regs);
- }
-
/* 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 (bb_info->in, bb_lr_info->in);
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. */
}
+/* 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
while (use)
{
- /* Do not want to go thur this for an uninitialized var. */
+ /* Do not want to go through this for an uninitialized var. */
unsigned int uregno = DF_REF_REGNO (use);
int count = DF_REG_DEF_GET (df, uregno)->n_refs;
if (count)
#endif
for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
- {
- unsigned int dregno = DF_REF_REGNO (def);
- bitmap_clear_range (cpy,
- DF_REG_DEF_GET (df, dregno)->begin,
- DF_REG_DEF_GET (df, dregno)->n_refs);
- if (! (DF_REF_FLAGS (def) & DF_REF_CLOBBER))
- bitmap_set_bit (cpy, DF_REF_ID (def));
- }
+ if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+ {
+ unsigned int dregno = DF_REF_REGNO (def);
+ bitmap_clear_range (cpy,
+ DF_REG_DEF_GET (df, dregno)->begin,
+ DF_REG_DEF_GET (df, dregno)->n_refs);
+ if (! (DF_REF_FLAGS (def) & DF_REF_CLOBBER))
+ bitmap_set_bit (cpy, DF_REF_ID (def));
+ }
/* Process the regular instructions next. */
FOR_BB_INSNS (bb, insn)
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. */
df_chain_add_problem (struct df *df, int flags)
{
struct df_chain_problem_data *problem_data =
- xmalloc (sizeof (struct df_chain_problem_data));
+ XNEW (struct df_chain_problem_data);
struct dataflow *dflow = df_add_problem (df, &problem_CHAIN);
dflow->problem_data = problem_data;
if (!dflow->problem_data)
{
- struct df_ri_problem_data *problem_data =
- xmalloc (sizeof (struct df_ri_problem_data));
+ struct df_ri_problem_data *problem_data = XNEW (struct df_ri_problem_data);
dflow->problem_data = problem_data;
}
{
unsigned int uregno = DF_REF_REGNO (use);
- /* This register is now live. */
- bitmap_set_bit (live, uregno);
+ if (!bitmap_bit_p (live, uregno))
+ {
+ use->flags |= DF_REF_DIES_AFTER_THIS_USE;
+ /* This register is now live. */
+ bitmap_set_bit (live, uregno);
+ }
+ else
+ use->flags &= ~DF_REF_DIES_AFTER_THIS_USE;
}
/* Increment lifetimes of all live registers. */
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. */