Wed Nov 10 15:56:16 1999 Jeffrey A Law (law@cygnus.com)
+ * flow.c (compute_flow_dominators): Initially put all blocks on
+ the worklist.
+ * lcm.c (compute_antinout_edge, compute_available): Similarly.
+ * gcse.c (compute_cprop_avinout): Remove.
+ (compute_cprop_data): Use compute_available.
+ (delete_null_pointer_checks_1): Use compute_available.
+
* basic-block.h (compute_available): Returns a void now.
* gcse.c (one_classic_gcse_pass): Do not expect compute_available
to return a value anymore.
if (dominators)
{
- /* Clear the AUX field for each basic block. */
+ /* The optimistic setting of dominators requires us to put every
+ block on the work list initially. */
for (bb = 0; bb < n_basic_blocks; bb++)
- BASIC_BLOCK (bb)->aux = NULL;
+ {
+ *tos++ = BASIC_BLOCK (bb);
+ BASIC_BLOCK (bb)->aux = BASIC_BLOCK (bb);
+ }
/* We want a maximal solution, so initially assume everything dominates
everything else. */
sbitmap_vector_ones (dominators, n_basic_blocks);
- /* Put the successors of the entry block on the worklist. */
+ /* Mark successors of the entry block so we can identify them below. */
for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
- {
- *tos++ = e->dest;
-
- /* We use the block's aux field to track blocks which are in
- the worklist; we also use it to quickly determine which blocks
- are successors of the ENTRY block. */
- e->dest->aux = ENTRY_BLOCK_PTR;
- }
+ e->dest->aux = ENTRY_BLOCK_PTR;
/* Iterate until the worklist is empty. */
while (tos != worklist)
if (post_dominators)
{
- /* Clear the AUX field for each basic block. */
+ /* The optimistic setting of dominators requires us to put every
+ block on the work list initially. */
for (bb = 0; bb < n_basic_blocks; bb++)
- BASIC_BLOCK (bb)->aux = NULL;
+ {
+ *tos++ = BASIC_BLOCK (bb);
+ BASIC_BLOCK (bb)->aux = BASIC_BLOCK (bb);
+ }
/* We want a maximal solution, so initially assume everything post
dominates everything else. */
sbitmap_vector_ones (post_dominators, n_basic_blocks);
- /* Put the predecessors of the exit block on the worklist. */
+ /* Mark predecessors of the exit block so we can identify them below. */
for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
- {
- *tos++ = e->src;
-
- /* We use the block's aux field to track blocks which are in
- the worklist; we also use it to quickly determine which blocks
- are predecessors of the EXIT block. */
- e->src->aux = EXIT_BLOCK_PTR;
- }
+ e->src->aux = EXIT_BLOCK_PTR;
/* Iterate until the worklist is empty. */
while (tos != worklist)
static void compute_transpout PROTO ((void));
static void compute_local_properties PROTO ((sbitmap *, sbitmap *,
sbitmap *, int));
-static void compute_cprop_avinout PROTO ((void));
static void compute_cprop_data PROTO ((void));
static void find_used_regs PROTO ((rtx));
static int try_replace_reg PROTO ((rtx, rtx, rtx));
}
}
-/* Compute the available expressions at the start and end of each
- basic block for cprop. This particular dataflow equation is
- used often enough that we might want to generalize it and make
- as a subroutine for other global optimizations that need available
- in/out information. */
-static void
-compute_cprop_avinout ()
-{
- int bb, changed, passes;
-
- sbitmap_zero (cprop_avin[0]);
- sbitmap_vector_ones (cprop_avout, n_basic_blocks);
-
- passes = 0;
- changed = 1;
- while (changed)
- {
- changed = 0;
- for (bb = 0; bb < n_basic_blocks; bb++)
- {
- if (bb != 0)
- sbitmap_intersection_of_preds (cprop_avin[bb], cprop_avout, bb);
- changed |= sbitmap_union_of_diff (cprop_avout[bb],
- cprop_pavloc[bb],
- cprop_avin[bb],
- cprop_absaltered[bb]);
- }
- passes++;
- }
-
- if (gcse_file)
- fprintf (gcse_file, "cprop avail expr computation: %d passes\n", passes);
-}
-
/* Top level routine to do the dataflow analysis needed by copy/const
propagation. */
compute_cprop_data ()
{
compute_local_properties (cprop_absaltered, cprop_pavloc, NULL, 1);
- compute_cprop_avinout ();
+ compute_available (cprop_pavloc, cprop_absaltered,
+ cprop_avout, cprop_avin);
}
\f
/* Copy/constant propagation. */
sbitmap *nonnull_avout;
struct null_pointer_info *npi;
{
- int changed, bb;
+ int bb;
int current_block;
sbitmap *nonnull_local = npi->nonnull_local;
sbitmap *nonnull_killed = npi->nonnull_killed;
/* Now compute global properties based on the local properties. This
is a classic global availablity algorithm. */
- sbitmap_zero (nonnull_avin[0]);
- sbitmap_vector_ones (nonnull_avout, n_basic_blocks);
- changed = 1;
- while (changed)
- {
- changed = 0;
-
- for (bb = 0; bb < n_basic_blocks; bb++)
- {
- if (bb != 0)
- sbitmap_intersect_of_predecessors (nonnull_avin[bb],
- nonnull_avout, bb, s_preds);
-
- changed |= sbitmap_union_of_diff (nonnull_avout[bb],
- nonnull_local[bb],
- nonnull_avin[bb],
- nonnull_killed[bb]);
- }
- }
+ compute_available (nonnull_local, nonnull_killed,
+ nonnull_avout, nonnull_avin);
/* Now look at each bb and see if it ends with a compare of a value
against zero. */
ANTIN. */
sbitmap_vector_ones (antin, n_basic_blocks);
- /* Put the predecessors of the exit block on the worklist. */
- for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
+ /* Put every block on the worklist; this is necessary because of the
+ optimistic initialization of ANTIN above. */
+ for (bb = 0; bb < n_basic_blocks; bb++)
{
- *tos++ = e->src;
-
- /* We use the block's aux field to track blocks which are in
- the worklist; we also use it to quickly determine which blocks
- are predecessors of the EXIT block. */
- e->src->aux = EXIT_BLOCK_PTR;
+ *tos++ = BASIC_BLOCK (bb);
+ BASIC_BLOCK (bb)->aux = BASIC_BLOCK (bb);
}
+ /* Mark blocks which are predecessors of the exit block so that we
+ can easily identify them below. */
+ for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
+ e->src->aux = EXIT_BLOCK_PTR;
+
/* Iterate until the worklist is empty. */
while (tos != worklist)
{
/* We want a maximal solution. */
sbitmap_vector_ones (avout, n_basic_blocks);
- /* Put the successors of the entry block on the worklist. */
- for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
+ /* Put every block on the worklist; this is necessary because of the
+ optimistic initialization of AVOUT above. */
+ for (bb = n_basic_blocks - 1; bb >= 0; bb--)
{
- *tos++ = e->dest;
-
- /* We use the block's aux field to track blocks which are in
- the worklist; we also use it to quickly determine which blocks
- are successors of the ENTRY block. */
- e->dest->aux = ENTRY_BLOCK_PTR;
+ *tos++ = BASIC_BLOCK (bb);
+ BASIC_BLOCK (bb)->aux = BASIC_BLOCK (bb);
}
+ /* Mark blocks which are successors of the entry block so that we
+ can easily identify them below. */
+ for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
+ e->dest->aux = ENTRY_BLOCK_PTR;
+
/* Iterate until the worklist is empty. */
while (tos != worklist)
{