/* Dataflow support routines.
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz,
mhayes@redhat.com)
the reg-def lists contain all the refs that define a given register
while the insn-use lists contain all the refs used by an insn.
-Note that the reg-def and reg-use chains are generally short (except for the
-hard registers) and thus it is much faster to search these chains
+Note that the reg-def and reg-use chains are generally short (except for
+the hard registers) and thus it is much faster to search these chains
rather than searching the def or use bitmaps.
If the insns are in SSA form then the reg-def and use-def lists
even though reg 41 is decremented before it is used for the memory
address in this second example.
-A set to a REG inside a ZERO_EXTRACT, SIGN_EXTRACT, or SUBREG invokes
-a read-modify write operation. We generate both a use and a def
-and again mark them read/write.
-*/
+A set to a REG inside a ZERO_EXTRACT, or a set to a non-paradoxical SUBREG
+for which the number of word_mode units covered by the outer mode is
+smaller than that covered by the inner mode, invokes a read-modify-write.
+operation. We generate both a use and a def and again mark them
+read/write.
+Paradoxical subreg writes don't leave a trace of the old content, so they
+are write-only operations. */
#include "config.h"
#include "system.h"
do \
{ \
unsigned int node_; \
- EXECUTE_IF_SET_IN_BITMAP (BITMAP, MIN, node_, \
- {(BB) = BASIC_BLOCK (node_); CODE;}); \
+ bitmap_iterator bi; \
+ EXECUTE_IF_SET_IN_BITMAP (BITMAP, MIN, node_, bi) \
+ { \
+ (BB) = BASIC_BLOCK (node_); \
+ CODE; \
+ } \
} \
while (0)
if (! df->insns_modified)
{
- df->insns_modified = BITMAP_XMALLOC ();
+ df->insns_modified = BITMAP_ALLOC (NULL);
bitmap_zero (df->insns_modified);
}
}
if (!bb_info->rd_in)
{
/* Allocate bitmaps for reaching definitions. */
- bb_info->rd_kill = BITMAP_XMALLOC ();
- bb_info->rd_gen = BITMAP_XMALLOC ();
- bb_info->rd_in = BITMAP_XMALLOC ();
- bb_info->rd_out = BITMAP_XMALLOC ();
+ bb_info->rd_kill = BITMAP_ALLOC (NULL);
+ bb_info->rd_gen = BITMAP_ALLOC (NULL);
+ bb_info->rd_in = BITMAP_ALLOC (NULL);
+ bb_info->rd_out = BITMAP_ALLOC (NULL);
}
else
{
if (!bb_info->ru_in)
{
/* Allocate bitmaps for upward exposed uses. */
- bb_info->ru_kill = BITMAP_XMALLOC ();
- bb_info->ru_gen = BITMAP_XMALLOC ();
- bb_info->ru_in = BITMAP_XMALLOC ();
- bb_info->ru_out = BITMAP_XMALLOC ();
+ bb_info->ru_kill = BITMAP_ALLOC (NULL);
+ bb_info->ru_gen = BITMAP_ALLOC (NULL);
+ bb_info->ru_in = BITMAP_ALLOC (NULL);
+ bb_info->ru_out = BITMAP_ALLOC (NULL);
}
else
{
if (!bb_info->lr_in)
{
/* Allocate bitmaps for live variables. */
- bb_info->lr_def = BITMAP_XMALLOC ();
- bb_info->lr_use = BITMAP_XMALLOC ();
- bb_info->lr_in = BITMAP_XMALLOC ();
- bb_info->lr_out = BITMAP_XMALLOC ();
+ bb_info->lr_def = BITMAP_ALLOC (NULL);
+ bb_info->lr_use = BITMAP_ALLOC (NULL);
+ bb_info->lr_in = BITMAP_ALLOC (NULL);
+ bb_info->lr_out = BITMAP_ALLOC (NULL);
}
else
{
if ((flags & DF_RD) && bb_info->rd_in)
{
/* Free bitmaps for reaching definitions. */
- BITMAP_XFREE (bb_info->rd_kill);
+ BITMAP_FREE (bb_info->rd_kill);
bb_info->rd_kill = NULL;
- BITMAP_XFREE (bb_info->rd_gen);
+ BITMAP_FREE (bb_info->rd_gen);
bb_info->rd_gen = NULL;
- BITMAP_XFREE (bb_info->rd_in);
+ BITMAP_FREE (bb_info->rd_in);
bb_info->rd_in = NULL;
- BITMAP_XFREE (bb_info->rd_out);
+ BITMAP_FREE (bb_info->rd_out);
bb_info->rd_out = NULL;
}
if ((flags & DF_RU) && bb_info->ru_in)
{
/* Free bitmaps for upward exposed uses. */
- BITMAP_XFREE (bb_info->ru_kill);
+ BITMAP_FREE (bb_info->ru_kill);
bb_info->ru_kill = NULL;
- BITMAP_XFREE (bb_info->ru_gen);
+ BITMAP_FREE (bb_info->ru_gen);
bb_info->ru_gen = NULL;
- BITMAP_XFREE (bb_info->ru_in);
+ BITMAP_FREE (bb_info->ru_in);
bb_info->ru_in = NULL;
- BITMAP_XFREE (bb_info->ru_out);
+ BITMAP_FREE (bb_info->ru_out);
bb_info->ru_out = NULL;
}
if ((flags & DF_LR) && bb_info->lr_in)
{
/* Free bitmaps for live variables. */
- BITMAP_XFREE (bb_info->lr_def);
+ BITMAP_FREE (bb_info->lr_def);
bb_info->lr_def = NULL;
- BITMAP_XFREE (bb_info->lr_use);
+ BITMAP_FREE (bb_info->lr_use);
bb_info->lr_use = NULL;
- BITMAP_XFREE (bb_info->lr_in);
+ BITMAP_FREE (bb_info->lr_in);
bb_info->lr_in = NULL;
- BITMAP_XFREE (bb_info->lr_out);
+ BITMAP_FREE (bb_info->lr_out);
bb_info->lr_out = NULL;
}
}
df_reg_table_realloc (df, df->n_regs);
- df->bbs_modified = BITMAP_XMALLOC ();
+ df->bbs_modified = BITMAP_ALLOC (NULL);
bitmap_zero (df->bbs_modified);
df->flags = 0;
df->bbs = xcalloc (last_basic_block, sizeof (struct bb_info));
- df->all_blocks = BITMAP_XMALLOC ();
+ df->all_blocks = BITMAP_ALLOC (NULL);
FOR_EACH_BB (bb)
bitmap_set_bit (df->all_blocks, bb->index);
}
df->regs = 0;
df->reg_size = 0;
- if (df->bbs_modified)
- BITMAP_XFREE (df->bbs_modified);
+ BITMAP_FREE (df->bbs_modified);
df->bbs_modified = 0;
- if (df->insns_modified)
- BITMAP_XFREE (df->insns_modified);
+ BITMAP_FREE (df->insns_modified);
df->insns_modified = 0;
- BITMAP_XFREE (df->all_blocks);
+ BITMAP_FREE (df->all_blocks);
df->all_blocks = 0;
free_alloc_pool (df_ref_pool);
}
-/* Return nonzero if writes to paradoxical SUBREGs, or SUBREGs which
- are too narrow, are read-modify-write. */
+/* A set to a non-paradoxical SUBREG for which the number of word_mode units
+ covered by the outer mode is smaller than that covered by the inner mode,
+ is a read-modify-write operation.
+ This function returns true iff the SUBREG X is such a SUBREG. */
bool
read_modify_subreg_p (rtx x)
{
return false;
isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
osize = GET_MODE_SIZE (GET_MODE (x));
- /* Paradoxical subreg writes don't leave a trace of the old content. */
return (isize > osize && isize > UNITS_PER_WORD);
}
be handy for the reg allocator. */
while (GET_CODE (dst) == STRICT_LOW_PART
|| GET_CODE (dst) == ZERO_EXTRACT
- || GET_CODE (dst) == SIGN_EXTRACT
- || ((df->flags & DF_FOR_REGALLOC) == 0
- && read_modify_subreg_p (dst)))
+ || read_modify_subreg_p (dst))
{
/* Strict low part always contains SUBREG, but we do not want to make
it appear outside, as whole register is always considered. */
switch (GET_CODE (dst))
{
case SUBREG:
- if ((df->flags & DF_FOR_REGALLOC) == 0
- && read_modify_subreg_p (dst))
+ if (read_modify_subreg_p (dst))
{
df_uses_record (df, &SUBREG_REG (dst), DF_REF_REG_USE, bb,
insn, DF_REF_READ_WRITE);
if (global_regs[i])
{
x = df_reg_use_gen (i);
- df_uses_record (df, &SET_DEST (x),
+ df_uses_record (df, &XEXP (x, 0),
DF_REF_REG_USE, bb, insn, 0);
}
}
bitmap ru;
basic_block bb;
- ru = BITMAP_XMALLOC ();
+ ru = BITMAP_ALLOC (NULL);
FOR_EACH_BB_IN_BITMAP (blocks, 0, bb,
{
df_bb_du_chain_create (df, bb, ru);
});
- BITMAP_XFREE (ru);
+ BITMAP_FREE (ru);
}
void *out, void *gen, void *kill,
void *data ATTRIBUTE_UNUSED)
{
- *changed = bitmap_union_of_diff (out, gen, in, kill);
+ *changed = bitmap_ior_and_compl (out, gen, in, kill);
}
void *out, void *gen, void *kill,
void *data ATTRIBUTE_UNUSED)
{
- *changed = bitmap_union_of_diff (in, gen, out, kill);
+ *changed = bitmap_ior_and_compl (in, gen, out, kill);
}
void *out, void *use, void *def,
void *data ATTRIBUTE_UNUSED)
{
- *changed = bitmap_union_of_diff (in, use, out, def);
+ *changed = bitmap_ior_and_compl (in, use, out, def);
}
{
struct bb_info *bb_info = DF_BB_INFO (df, bb);
rtx insn;
- bitmap seen = BITMAP_XMALLOC ();
+ bitmap seen = BITMAP_ALLOC (NULL);
bool call_seen = false;
FOR_BB_INSNS_REVERSE (bb, insn)
if (CALL_P (insn) && (df->flags & DF_HARD_REGS))
{
- bitmap_operation (bb_info->rd_kill, bb_info->rd_kill,
- call_killed_defs, BITMAP_IOR);
+ bitmap_ior_into (bb_info->rd_kill, call_killed_defs);
call_seen = 1;
}
}
- BITMAP_XFREE (seen);
+ BITMAP_FREE (seen);
}
if (df->flags & DF_HARD_REGS)
{
- killed_by_call = BITMAP_XMALLOC ();
+ killed_by_call = BITMAP_ALLOC (NULL);
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
{
if (!TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
});
if (df->flags & DF_HARD_REGS)
- BITMAP_XFREE (killed_by_call);
+ BITMAP_FREE (killed_by_call);
}
unsigned int uid = INSN_UID (insn);
unsigned int regno;
struct df_link *link;
+ bitmap_iterator bi;
if (! INSN_P (insn))
continue;
}
/* Increment lifetimes of all live registers. */
- EXECUTE_IF_SET_IN_BITMAP (live, 0, regno,
- {
- reg_info[regno].lifetime++;
- });
+ EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
+ {
+ reg_info[regno].lifetime++;
+ }
}
}
basic_block bb;
bitmap live;
- live = BITMAP_XMALLOC ();
+ live = BITMAP_ALLOC (NULL);
FOR_EACH_BB_IN_BITMAP (blocks, 0, bb,
{
df_bb_reg_info_compute (df, bb, live);
});
- BITMAP_XFREE (live);
+ BITMAP_FREE (live);
}
df_refs_update (struct df *df, bitmap blocks)
{
basic_block bb;
- int count = 0, bbno;
+ unsigned count = 0, bbno;
df->n_regs = max_reg_num ();
if (df->n_regs >= df->reg_size)
}
else
{
- EXECUTE_IF_AND_IN_BITMAP (df->bbs_modified, blocks, 0, bbno,
+ bitmap_iterator bi;
+
+ EXECUTE_IF_AND_IN_BITMAP (df->bbs_modified, blocks, 0, bbno, bi)
{
count += df_bb_refs_update (df, BASIC_BLOCK (bbno));
- });
+ }
}
df_refs_process (df);
}
\f
+/* Perform the set operation OP1 OP OP2, using set representation REPR, and
+ storing the result in OP1. */
+
static void
dataflow_set_a_op_b (enum set_representation repr,
enum df_confluence_op op,
- void *rslt, void *op1, void *op2)
+ void *op1, void *op2)
{
switch (repr)
{
switch (op)
{
case DF_UNION:
- sbitmap_a_or_b (rslt, op1, op2);
+ sbitmap_a_or_b (op1, op1, op2);
break;
case DF_INTERSECTION:
- sbitmap_a_and_b (rslt, op1, op2);
+ sbitmap_a_and_b (op1, op1, op2);
break;
default:
switch (op)
{
case DF_UNION:
- bitmap_a_or_b (rslt, op1, op2);
+ bitmap_ior_into (op1, op2);
break;
case DF_INTERSECTION:
- bitmap_a_and_b (rslt, op1, op2);
+ bitmap_and_into (op1, op2);
break;
default:
int changed;
int i = bb->index;
edge e;
+ edge_iterator ei;
SET_BIT (visited, bb->index);
gcc_assert (TEST_BIT (pending, bb->index));
RESET_BIT (pending, i);
-#define HS(E_ANTI, E_ANTI_NEXT, E_ANTI_BB, E_ANTI_START_BB, IN_SET, \
- E, E_NEXT, E_BB, E_START_BB, OUT_SET) \
+#define HS(E_ANTI, E_ANTI_BB, E_ANTI_START_BB, IN_SET, \
+ E, E_BB, E_START_BB, OUT_SET) \
do \
{ \
/* Calculate <conf_op> of predecessor_outs. */ \
bitmap_zero (IN_SET[i]); \
- for (e = bb->E_ANTI; e; e = e->E_ANTI_NEXT) \
+ FOR_EACH_EDGE (e, ei, bb->E_ANTI) \
{ \
if (e->E_ANTI_BB == E_ANTI_START_BB) \
continue; \
continue; \
\
dataflow_set_a_op_b (dataflow->repr, dataflow->conf_op, \
- IN_SET[i], IN_SET[i], \
+ IN_SET[i], \
OUT_SET[e->E_ANTI_BB->index]); \
} \
\
if (!changed) \
break; \
\
- for (e = bb->E; e; e = e->E_NEXT) \
+ FOR_EACH_EDGE (e, ei, bb->E) \
{ \
if (e->E_BB == E_START_BB || e->E_BB->index == i) \
continue; \
SET_BIT (pending, e->E_BB->index); \
} \
\
- for (e = bb->E; e; e = e->E_NEXT) \
+ FOR_EACH_EDGE (e, ei, bb->E) \
{ \
if (e->E_BB == E_START_BB || e->E_BB->index == i) \
continue; \
} while (0)
if (dataflow->dir == DF_FORWARD)
- HS (pred, pred_next, src, ENTRY_BLOCK_PTR, dataflow->in,
- succ, succ_next, dest, EXIT_BLOCK_PTR, dataflow->out);
+ HS (preds, src, ENTRY_BLOCK_PTR, dataflow->in,
+ succs, dest, EXIT_BLOCK_PTR, dataflow->out);
else
- HS (succ, succ_next, dest, EXIT_BLOCK_PTR, dataflow->out,
- pred, pred_next, src, ENTRY_BLOCK_PTR, dataflow->in);
+ HS (succs, dest, EXIT_BLOCK_PTR, dataflow->out,
+ preds, src, ENTRY_BLOCK_PTR, dataflow->in);
}
/* This function will perform iterative bitvector dataflow described by