* tree-cfg.c (set_bb_for_stmt): Use PHI_BB.
* tree-dfa.c (compute_immediate_uses, add_immediate_use,
redirect_immediate_use): Use PHI_DF.
* tree-flow-inline.h (stmt_ann): Abort on phi nodes.
(bb_for_stmt): Use PHI_BB.
(get_immediate_uses): Use PHI_DF.
* tree-ssa-dse.c (max_stmt_uid): New variable.
(get_stmt_uid): New function.
(dse_optimize_stmt, dse_record_phis, tree_ssa_dse): Do not use phi
node annotations.
* tree-ssa-loop-im.c (LIM_DATA): Do not use phi statement annotations.
(max_uid): Renamed to max_stmt_uid.
(get_stmt_uid): New function.
(maybe_queue_var, single_reachable_address, determine_lsm): Do not use
phi node annotations.
* tree-ssa.c (replace_immediate_uses): Do not use phi node annotations.
* tree.h (PHI_BB, PHI_DF): New accessor functions.
(struct tree_phi_node): Add bb and df fields.
From-SVN: r87369
+2004-09-11 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-cfg.c (set_bb_for_stmt): Use PHI_BB.
+ * tree-dfa.c (compute_immediate_uses, add_immediate_use,
+ redirect_immediate_use): Use PHI_DF.
+ * tree-flow-inline.h (stmt_ann): Abort on phi nodes.
+ (bb_for_stmt): Use PHI_BB.
+ (get_immediate_uses): Use PHI_DF.
+ * tree-ssa-dse.c (max_stmt_uid): New variable.
+ (get_stmt_uid): New function.
+ (dse_optimize_stmt, dse_record_phis, tree_ssa_dse): Do not use phi
+ node annotations.
+ * tree-ssa-loop-im.c (LIM_DATA): Do not use phi statement annotations.
+ (max_uid): Renamed to max_stmt_uid.
+ (get_stmt_uid): New function.
+ (maybe_queue_var, single_reachable_address, determine_lsm): Do not use
+ phi node annotations.
+ * tree-ssa.c (replace_immediate_uses): Do not use phi node annotations.
+ * tree.h (PHI_BB, PHI_DF): New accessor functions.
+ (struct tree_phi_node): Add bb and df fields.
+
2004-09-11 Richard Henderson <rth@redhat.com>
PR middle-end/17416
void
set_bb_for_stmt (tree t, basic_block bb)
{
- if (TREE_CODE (t) == STATEMENT_LIST)
+ if (TREE_CODE (t) == PHI_NODE)
+ PHI_BB (t) = bb;
+ else if (TREE_CODE (t) == STATEMENT_LIST)
{
tree_stmt_iterator i;
for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
static void
free_df_for_stmt (tree stmt)
{
- stmt_ann_t ann = stmt_ann (stmt);
+ dataflow_t *df;
- if (ann && ann->df)
+ if (TREE_CODE (stmt) == PHI_NODE)
+ df = &PHI_DF (stmt);
+ else
{
- /* If we have a varray of immediate uses, then go ahead and release
- it for re-use. */
- if (ann->df->immediate_uses)
- ggc_free (ann->df->immediate_uses);
-
- /* Similarly for the main dataflow structure. */
- ggc_free (ann->df);
- ann->df = NULL;
+ stmt_ann_t ann = stmt_ann (stmt);
+
+ if (!ann)
+ return;
+
+ df = &ann->df;
}
+
+ if (!*df)
+ return;
+
+ /* If we have a varray of immediate uses, then go ahead and release
+ it for re-use. */
+ if ((*df)->immediate_uses)
+ ggc_free ((*df)->immediate_uses);
+
+ /* Similarly for the main dataflow structure. */
+ ggc_free (*df);
+ *df = NULL;
}
static void
add_immediate_use (tree stmt, tree use_stmt)
{
- stmt_ann_t ann = get_stmt_ann (stmt);
- struct dataflow_d *df;
+ struct dataflow_d **df;
+
+ if (TREE_CODE (stmt) == PHI_NODE)
+ df = &PHI_DF (stmt);
+ else
+ {
+ stmt_ann_t ann = get_stmt_ann (stmt);
+ df = &ann->df;
+ }
- df = ann->df;
- if (df == NULL)
+ if (*df == NULL)
{
- df = ann->df = ggc_alloc (sizeof (struct dataflow_d));
- memset ((void *) df, 0, sizeof (struct dataflow_d));
- df->uses[0] = use_stmt;
+ *df = ggc_alloc (sizeof (struct dataflow_d));
+ memset ((void *) *df, 0, sizeof (struct dataflow_d));
+ (*df)->uses[0] = use_stmt;
return;
}
- if (!df->uses[1])
+ if (!(*df)->uses[1])
{
- df->uses[1] = use_stmt;
+ (*df)->uses[1] = use_stmt;
return;
}
- if (ann->df->immediate_uses == NULL)
- VARRAY_TREE_INIT (ann->df->immediate_uses, 4, "immediate_uses");
+ if ((*df)->immediate_uses == NULL)
+ VARRAY_TREE_INIT ((*df)->immediate_uses, 4, "immediate_uses");
- VARRAY_PUSH_TREE (ann->df->immediate_uses, use_stmt);
+ VARRAY_PUSH_TREE ((*df)->immediate_uses, use_stmt);
}
redirect_immediate_use (tree use, tree old, tree new)
{
tree imm_stmt = SSA_NAME_DEF_STMT (use);
- struct dataflow_d *df = get_stmt_ann (imm_stmt)->df;
+ struct dataflow_d *df = get_immediate_uses (imm_stmt);
unsigned int num_uses = num_immediate_uses (df);
unsigned int i;
static inline basic_block
bb_for_stmt (tree t)
{
- stmt_ann_t ann = stmt_ann (t);
+ stmt_ann_t ann;
+
+ if (TREE_CODE (t) == PHI_NODE)
+ return PHI_BB (t);
+
+ ann = stmt_ann (t);
return ann ? ann->bb : NULL;
}
static dataflow_t
get_immediate_uses (tree stmt)
{
- stmt_ann_t ann = stmt_ann (stmt);
+ stmt_ann_t ann;
+
+ if (TREE_CODE (stmt) == PHI_NODE)
+ return PHI_DF (stmt);
+
+ ann = stmt_ann (stmt);
return ann ? ann->df : NULL;
}
static void fix_stmt_v_may_defs (tree, tree);
static void record_voperand_set (bitmap, bitmap *, unsigned int);
+static unsigned max_stmt_uid; /* Maximal uid of a statement. Uids to phi
+ nodes are assigned using the versions of
+ ssa names they define. */
+
+/* Returns uid of statement STMT. */
+
+static unsigned
+get_stmt_uid (tree stmt)
+{
+ if (TREE_CODE (stmt) == PHI_NODE)
+ return SSA_NAME_VERSION (PHI_RESULT (stmt)) + max_stmt_uid;
+
+ return stmt_ann (stmt)->uid;
+}
+
/* Function indicating whether we ought to include information for 'var'
when calculating immediate uses. For this pass we only want use
information for virtual variables. */
same block. */
while (num_uses == 1
&& TREE_CODE (use) == PHI_NODE
- && bitmap_bit_p (dse_gd->stores, stmt_ann (use)->uid))
+ && bitmap_bit_p (dse_gd->stores, get_stmt_uid (use)))
{
/* Record the first PHI we skip so that we can fix its
uses if we find that STMT is a dead store. */
/* If we have precisely one immediate use at this point, then we may
have found redundant store. */
if (num_uses == 1
- && bitmap_bit_p (dse_gd->stores, stmt_ann (use)->uid)
+ && bitmap_bit_p (dse_gd->stores, get_stmt_uid (use))
&& operand_equal_p (TREE_OPERAND (stmt, 0),
TREE_OPERAND (use, 0), 0))
{
if (need_imm_uses_for (PHI_RESULT (phi)))
record_voperand_set (dse_gd->stores,
&bd->stores,
- get_stmt_ann (phi)->uid);
+ get_stmt_uid (phi));
}
static void
{
struct dom_walk_data walk_data;
struct dse_global_data dse_gd;
- unsigned int uid = 0;
basic_block bb;
/* Create a UID for each statement in the function. Ordering of the
UIDs is not important for this pass. */
+ max_stmt_uid = 0;
FOR_EACH_BB (bb)
{
block_stmt_iterator bsi;
- tree phi;
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- stmt_ann (bsi_stmt (bsi))->uid = uid++;
-
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- stmt_ann (phi)->uid = uid++;
+ stmt_ann (bsi_stmt (bsi))->uid = max_stmt_uid++;
}
/* We might consider making this a property of each pass so that it
MAX_LOOP loop. */
};
-#define LIM_DATA(STMT) ((struct lim_aux_data *) (stmt_ann (STMT)->common.aux))
+#define LIM_DATA(STMT) (TREE_CODE (STMT) == PHI_NODE \
+ ? NULL \
+ : (struct lim_aux_data *) (stmt_ann (STMT)->common.aux))
/* Description of a memory reference for store motion. */
block will be executed. */
#define ALWAYS_EXECUTED_IN(BB) ((struct loop *) (BB)->aux)
-/* Maximum uid in the statement in the function. */
+static unsigned max_stmt_uid; /* Maximal uid of a statement. Uids to phi
+ nodes are assigned using the versions of
+ ssa names they define. */
-static unsigned max_uid;
+/* Returns uid of statement STMT. */
+
+static unsigned
+get_stmt_uid (tree stmt)
+{
+ if (TREE_CODE (stmt) == PHI_NODE)
+ return SSA_NAME_VERSION (PHI_RESULT (stmt)) + max_stmt_uid;
+
+ return stmt_ann (stmt)->uid;
+}
/* Calls CBCK for each index in memory reference ADDR_P. There are two
kinds situations handled; in each of these cases, the memory reference
if (!def_bb
|| !flow_bb_inside_loop_p (loop, def_bb)
- || TEST_BIT (seen, stmt_ann (stmt)->uid))
+ || TEST_BIT (seen, get_stmt_uid (stmt)))
return;
- SET_BIT (seen, stmt_ann (stmt)->uid);
+ SET_BIT (seen, get_stmt_uid (stmt));
queue[(*in_queue)++] = stmt;
}
struct mem_ref **mem_refs,
bool *seen_call_stmt)
{
+ unsigned max_uid = max_stmt_uid + num_ssa_names;
tree *queue = xmalloc (sizeof (tree) * max_uid);
sbitmap seen = sbitmap_alloc (max_uid);
unsigned in_queue = 1;
sra_data.common_ref = NULL_TREE;
queue[0] = stmt;
- SET_BIT (seen, stmt_ann (stmt)->uid);
+ SET_BIT (seen, get_stmt_uid (stmt));
*seen_call_stmt = false;
while (in_queue)
if (!flow_bb_inside_loop_p (loop, bb_for_stmt (stmt)))
continue;
- if (TEST_BIT (seen, stmt_ann (stmt)->uid))
+ if (TEST_BIT (seen, get_stmt_uid (stmt)))
continue;
- SET_BIT (seen, stmt_ann (stmt)->uid);
+ SET_BIT (seen, get_stmt_uid (stmt));
queue[in_queue++] = stmt;
}
/* Create a UID for each statement in the function. Ordering of the
UIDs is not important for this pass. */
- max_uid = 0;
+ max_stmt_uid = 0;
FOR_EACH_BB (bb)
{
block_stmt_iterator bsi;
- tree phi;
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- stmt_ann (bsi_stmt (bsi))->uid = max_uid++;
-
- for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
- stmt_ann (phi)->uid = max_uid++;
+ stmt_ann (bsi_stmt (bsi))->uid = max_stmt_uid++;
}
compute_immediate_uses (TDFA_USE_VOPS, NULL);
int i, j, n;
dataflow_t df;
tree stmt;
- stmt_ann_t ann;
bool mark_new_vars;
ssa_op_iter iter;
use_operand_p use_p;
for (i = 0; i < n; i++)
{
stmt = immediate_use (df, i);
- ann = stmt_ann (stmt);
if (TREE_CODE (stmt) == PHI_NODE)
{
#define PHI_ARG_ELT(NODE, I) PHI_NODE_ELT_CHECK (NODE, I)
#define PHI_ARG_EDGE(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).e
#define PHI_ARG_NONZERO(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).nonzero
+#define PHI_BB(NODE) PHI_NODE_CHECK (NODE)->phi.bb
+#define PHI_DF(NODE) PHI_NODE_CHECK (NODE)->phi.df
struct edge_def;
SSA renamer. */
int rewritten;
+ /* Basic block to that the phi node belongs. */
+ struct basic_block_def *bb;
+
+ /* Dataflow information. */
+ struct dataflow_d *df;
+
struct phi_arg_d GTY ((length ("((tree)&%h)->phi.capacity"))) a[1];
};
\f