Someday I'll perform the computation and figure it out. */
/* Total size of the expression hash table, in elements. */
-static int expr_hash_table_size;
+static unsigned int expr_hash_table_size;
+
/* The table itself.
This is an array of `expr_hash_table_size' elements. */
static struct expr **expr_hash_table;
static int max_uid;
/* Get the cuid of an insn. */
+#ifdef ENABLE_CHECKING
+#define INSN_CUID(INSN) (INSN_UID (INSN) > max_uid ? (abort (), 0) : uid_cuid[INSN_UID (INSN)])
+#else
#define INSN_CUID(INSN) (uid_cuid[INSN_UID (INSN)])
+#endif
/* Number of cuids. */
static int max_cuid;
Normally they'd be defined a bit later, but `rd_gen' needs to
be declared sooner. */
-/* A bitmap of all ones for implementing the algorithm for available
- expressions and reaching definitions. */
-/* ??? Available expression bitmaps have a different size than reaching
- definition bitmaps. This should be the larger of the two, however, it
- is not currently used for reaching definitions. */
-static sbitmap u_bitmap;
-
/* Each block has a bitmap of each type.
The length of each blocks bitmap is:
static void alloc_set_hash_table PARAMS ((int));
static void free_set_hash_table PARAMS ((void));
static void compute_set_hash_table PARAMS ((void));
-static void alloc_expr_hash_table PARAMS ((int));
+static void alloc_expr_hash_table PARAMS ((unsigned int));
static void free_expr_hash_table PARAMS ((void));
static void compute_expr_hash_table PARAMS ((void));
static void dump_hash_table PARAMS ((FILE *, const char *, struct expr **,
bzero ((char *) uid_cuid, n);
for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
{
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
- INSN_CUID (insn) = i++;
+ if (INSN_P (insn))
+ uid_cuid[INSN_UID (insn)] = i++;
else
- INSN_CUID (insn) = i;
+ uid_cuid[INSN_UID (insn)] = i;
}
/* Create a table mapping cuids to insns. */
cuid_insn = (rtx *) gmalloc (n);
bzero ((char *) cuid_insn, n);
for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ if (INSN_P (insn))
CUID_INSN (i++) = insn;
/* Allocate vars to track sets of regs. */
sbitmap *antloc;
int setp;
{
- int i, hash_table_size;
+ unsigned int i, hash_table_size;
struct expr **hash_table;
/* Initialize any bitmaps that were passed in. */
rtx insn;
{
/* allocate a new reg_set element and link it onto the list */
- struct reg_set *new_reg_info, *reg_info_ptr1, *reg_info_ptr2;
+ struct reg_set *new_reg_info;
/* If the table isn't big enough, enlarge it. */
if (regno >= reg_set_table_size)
sizeof (struct reg_set));
bytes_used += sizeof (struct reg_set);
new_reg_info->insn = insn;
- new_reg_info->next = NULL;
- if (reg_set_table[regno] == NULL)
- reg_set_table[regno] = new_reg_info;
- else
- {
- reg_info_ptr1 = reg_info_ptr2 = reg_set_table[regno];
- /* ??? One could keep a "last" pointer to speed this up. */
- while (reg_info_ptr1 != NULL)
- {
- reg_info_ptr2 = reg_info_ptr1;
- reg_info_ptr1 = reg_info_ptr1->next;
- }
-
- reg_info_ptr2->next = new_reg_info;
- }
+ new_reg_info->next = reg_set_table[regno];
+ reg_set_table[regno] = new_reg_info;
}
/* Called from compute_sets via note_stores to handle one SET or CLOBBER in
rtx insn;
for (insn = f; insn != 0; insn = NEXT_INSN (insn))
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ if (INSN_P (insn))
note_stores (PATTERN (insn), record_set_info, insn);
}
\f
case PRE_INC:
case POST_DEC:
case POST_INC:
+ case PRE_MODIFY:
+ case POST_MODIFY:
return 0;
case PC:
}
#endif
- if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
+ if (! INSN_P (insn))
continue;
if (GET_CODE (insn) == CALL_INSN)
for (insn = BLOCK_HEAD (bb), in_libcall_block = 0;
insn && insn != NEXT_INSN (BLOCK_END (bb));
insn = NEXT_INSN (insn))
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ if (INSN_P (insn))
{
if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
in_libcall_block = 1;
static void
alloc_expr_hash_table (n_insns)
- int n_insns;
+ unsigned int n_insns;
{
int n;
ae_out = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
sbitmap_vector_zero (ae_out, n_basic_blocks);
-
- u_bitmap = (sbitmap) sbitmap_alloc (n_exprs);
- sbitmap_ones (u_bitmap);
}
static void
free (ae_gen);
free (ae_in);
free (ae_out);
- free (u_bitmap);
}
/* Compute the set of available expressions generated in each basic block. */
static void
compute_ae_gen ()
{
- int i;
+ unsigned int i;
struct expr *expr;
struct occr *occr;
compute_ae_kill (ae_gen, ae_kill)
sbitmap *ae_gen, *ae_kill;
{
- int bb, i;
+ int bb;
+ unsigned int i;
struct expr *expr;
for (bb = 0; bb < n_basic_blocks; bb++)
/* Keep track of everything modified by this insn. */
/* ??? Need to be careful w.r.t. mods done to INSN. */
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ if (INSN_P (insn))
mark_oprs_set (insn);
}
}
{
rtx simplified;
+ if (!validate_replace_rtx_subexp (from, to, insn, &XEXP (note, 0)))
+ abort();
+
src = XEXP (note, 0);
- replace_rtx (src, from, to);
/* Try to simplify resulting note. */
simplified = simplify_rtx (src);
insn != NULL && insn != NEXT_INSN (BLOCK_END (bb));
insn = NEXT_INSN (insn))
{
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ if (INSN_P (insn))
{
changed |= cprop_insn (insn, alter_jumps);
/* Contains the edge_list returned by pre_edge_lcm. */
static struct edge_list *edge_list;
-static sbitmap *temp_bitmap;
-
/* Redundant insns. */
static sbitmap pre_redundant_insns;
transp = sbitmap_vector_alloc (n_blocks, n_exprs);
comp = sbitmap_vector_alloc (n_blocks, n_exprs);
antloc = sbitmap_vector_alloc (n_blocks, n_exprs);
- temp_bitmap = sbitmap_vector_alloc (n_blocks, n_exprs);
pre_optimal = NULL;
pre_redundant = NULL;
pre_delete_map = NULL;
ae_in = NULL;
ae_out = NULL;
- u_bitmap = NULL;
- transpout = sbitmap_vector_alloc (n_blocks, n_exprs);
ae_kill = sbitmap_vector_alloc (n_blocks, n_exprs);
/* pre_insert and pre_delete are allocated later. */
{
free (transp);
free (comp);
- free (antloc);
- free (temp_bitmap);
+
+ /* ANTLOC and AE_KILL are freed just after pre_lcm finishes. */
if (pre_optimal)
free (pre_optimal);
free (pre_insert_map);
if (pre_delete_map)
free (pre_delete_map);
- if (transpout)
- free (transpout);
if (ae_in)
free (ae_in);
if (ae_out)
free (ae_out);
- if (ae_kill)
- free (ae_kill);
- if (u_bitmap)
- free (u_bitmap);
- transp = comp = antloc = NULL;
+ transp = comp = NULL;
pre_optimal = pre_redundant = pre_insert_map = pre_delete_map = NULL;
- transpout = ae_in = ae_out = ae_kill = NULL;
- u_bitmap = NULL;
-
+ ae_in = ae_out = NULL;
}
/* Top level routine to do the dataflow analysis needed by PRE. */
static void
compute_pre_data ()
{
+ int i;
+
compute_local_properties (transp, comp, antloc, 0);
- compute_transpout ();
sbitmap_vector_zero (ae_kill, n_basic_blocks);
- compute_ae_kill (comp, ae_kill);
+
+ /* Compute ae_kill for each basic block using:
+
+ ~(TRANSP | COMP)
+
+ This is significantly faster than compute_ae_kill. */
+
+ for (i = 0; i < n_basic_blocks; i++)
+ {
+ sbitmap_a_or_b (ae_kill[i], transp[i], comp[i]);
+ sbitmap_not (ae_kill[i], ae_kill[i]);
+ }
+
edge_list = pre_edge_lcm (gcse_file, n_exprs, transp, comp, antloc,
ae_kill, &pre_insert_map, &pre_delete_map);
+ free (antloc);
+ antloc = NULL;
+ free (ae_kill);
+ ae_kill = NULL;
}
\f
/* PRE utilities */
{
rtx maybe_cc0_setter = prev_nonnote_insn (insn);
if (maybe_cc0_setter
- && GET_RTX_CLASS (GET_CODE (maybe_cc0_setter)) == 'i'
+ && INSN_P (maybe_cc0_setter)
&& sets_cc0_p (PATTERN (maybe_cc0_setter)))
insn = maybe_cc0_setter;
}
If we inserted before the CODE_LABEL, then we would be putting
the insn in the wrong basic block. In that case, put the insn
after the CODE_LABEL. Also, respect NOTE_INSN_BASIC_BLOCK. */
- if (GET_CODE (insn) == CODE_LABEL)
- insn = NEXT_INSN (insn);
- else if (GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK)
+ while (GET_CODE (insn) == CODE_LABEL
+ || NOTE_INSN_BASIC_BLOCK_P (insn))
insn = NEXT_INSN (insn);
new_insn = emit_block_insn_before (pat, insn, BASIC_BLOCK (bb));
rtx insn = XVECEXP (pat, 0, i);
set_block_num (insn, bb);
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ if (INSN_P (insn))
add_label_notes (PATTERN (insn), new_insn);
note_stores (PATTERN (insn), record_set_info, insn);
static void
pre_insert_copies ()
{
- int i;
+ unsigned int i;
struct expr *expr;
struct occr *occr;
struct occr *avail;
static int
pre_delete ()
{
- int i, bb, changed;
+ unsigned int i;
+ int changed;
struct expr *expr;
struct occr *occr;
- /* Compute the expressions which are redundant and need to be replaced by
- copies from the reaching reg to the target reg. */
- for (bb = 0; bb < n_basic_blocks; bb++)
- sbitmap_copy (temp_bitmap[bb], pre_delete_map[bb]);
-
changed = 0;
for (i = 0; i < expr_hash_table_size; i++)
for (expr = expr_hash_table[i]; expr != NULL; expr = expr->next_same_hash)
rtx set;
int bb = BLOCK_NUM (insn);
- if (TEST_BIT (temp_bitmap[bb], indx))
+ if (TEST_BIT (pre_delete_map[bb], indx))
{
set = single_set (insn);
if (! set)
static int
pre_gcse ()
{
- int i, did_insert;
- int changed;
+ unsigned int i;
+ int did_insert, changed;
struct expr **index_map;
struct expr *expr;
compute_transpout ()
{
int bb;
- int i;
+ unsigned int i;
struct expr *expr;
sbitmap_vector_ones (transpout, n_basic_blocks);
rtx reg;
/* Ignore anything that is not a normal insn. */
- if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
+ if (! INSN_P (insn))
continue;
/* Basically ignore anything that is not a simple SET. We do have
void
delete_null_pointer_checks (f)
- rtx f;
+ rtx f ATTRIBUTE_UNUSED;
{
sbitmap *nonnull_avin, *nonnull_avout;
unsigned int *block_reg;
/* Go through the basic blocks, seeing whether or not each block
ends with a conditional branch whose condition is a comparison
against zero. Record the register compared in BLOCK_REG. */
- block_reg = (int *) xcalloc (n_basic_blocks, sizeof (int));
+ block_reg = (unsigned int *) xcalloc (n_basic_blocks, sizeof (int));
for (bb = 0; bb < n_basic_blocks; bb++)
{
rtx last_insn = BLOCK_END (bb);
/* We only want conditional branches. */
if (GET_CODE (last_insn) != JUMP_INSN
- || !condjump_p (last_insn)
- || simplejump_p (last_insn))
+ || !any_condjump_p (last_insn)
+ || !onlyjump_p (last_insn))
continue;
/* LAST_INSN is a conditional jump. Get its condition. */
static void
hoist_code ()
{
- int bb, dominated, i;
+ int bb, dominated;
+ unsigned int i;
struct expr **index_map;
struct expr *expr;