+2004-06-17 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-cfg.c (tree_make_forwarder_block): Use SET_PHI_RESULT.
+ * tree-flow-inline.h (get_use_op_ptr): Return a use_operand_p.
+ (get_use_from_ptr, get_def_from_ptr): New. Return operand pointers.
+ (get_def_op_ptr): Return a def_operand_p instead of a 'tree *'.
+ (get_v_may_def_result_ptr): Return a def_operand_p.
+ (get_v_may_def_op_ptr, get_vuse_op_ptr): Return a use_operand_p.
+ (get_v_must_def_op_ptr): Return a def_operand_p.
+ (get_phi_result_ptr): New. Return a pointer to the result of a PHI.
+ (get_phi_arg_def_ptr): New. Return a pointer to an argument of a PHI.
+ (phi_element_for_edge): Remove.
+ * tree-flow.h (propagate_value, replace_exp): Change prototype.
+ (propagate_tree_value): Add new prototype.
+ (phi_element_for_edge): Remove prototype.
+ * tree-into-ssa.c (mark_def_sites): Use new operand types.
+ (prepare_operand_for_rename): Split into two functions.
+ (prepare_use_operand_for_rename): Prepare use operands.
+ (prepare_def_operand_for_rename): Prepare def operands.
+ (rewrite_stmt): Use new operand types.
+ (rewrite_operand): Use new operand types, change parameter type.
+ * tree-outof-ssa.c (replace_variable): Split into two functions.
+ (replace_use_variable): Rewrite uses.
+ (replace_def_variable): Rewrite defs.
+ (rewrite_trees, rewrite_vars_out_of_ssa): Use new operand types.
+ * tree-phinodes.c (make_phi_node, resize_phi_node): Use new types.
+ (add_phi_arg, remove_phi_arg_num): Use new operand types.
+ * tree-ssa-ccp.c (substitute_and_fold): Use new operand types.
+ (ccp_fold, replace_uses_in): Use new operand types.
+ * tree-ssa-copy.c (replace_ssa_names): Rename to replace_ssa_names_ann
+ and no longer set the value, change parameter type.
+ (replace_exp_1): Use new operand types.
+ (propagate_value): Change parameter type, use new operand types.
+ (propagate_tree_value): Propagate_value without SSA operands.
+ (replace_exp, cprop_operand, cprop_into_stmt): Use new operand types.
+ (cprop_into_successor_phis): Use new operand types.
+ * tree-ssa-dom.c (thread_across_edge): Use new operand types.
+ (eliminate_redundant_computations): Use new operand types.
+ * tree-ssa-dse.c (fix_phi_uses): Use new operand_types.
+ (fix_stmt_v_may_defs): Use new operand_types.
+ * tree-ssa-live.c (create_ssa_var_map): Use new operand_types.
+ (build_tree_conflict_graph): Use new operand_types.
+ * tree-ssa-loop.c (duplicate_blocks): Use PHI_ARG_DEF_FROM_EDGE.
+ * tree-ssa-operands.c (struct freelist_d): Remove.
+ (check_optype_freelist, add_optype_freelist): Remove.
+ (allocate_def_optype, allocate_use_optype, allocate_v_may_def_optype,
+ allocate_vuse_optype, allocate_v_must_def_optype): Call ggc_alloc.
+ (free_uses, free_defs, free_vuses, free_v_may_defs, free_v_must_defs):
+ Call ggc_free instead of add_optype_freelist.
+ (init_ssa_operands, fini_ssa_operands): Remove free list code.
+ (finalize_ssa_defs, finalize_ssa_uses): Set new use/def operands.
+ * tree-ssa-operands.h (struct def_optype_d): Change underlying type.
+ (struct use_optype_d): Change underlying type.
+ (def_operand_p, use_operand_p): New types for pointers to operands.
+ (USE_OP, DEF_OP, V_MAY_DEF_RESULT, V_MAY_DEF_OP, VUSE_OP,
+ V_MUST_DEF_OP): Use new pointer type instead of dereferencing directly.
+ (USE_FROM_PTR, DEF_FROM_PTR): New macros to "dereference" operand
+ pointer types.
+ (SET_USE, SET_DEF): New macros to set operands from their pointer.
+ (SET_USE_OP, SET_DEF_OP, SET_V_MAY_DEF_RESULT, SET_V_MAY_DEF_OP,
+ SET_VUSE_OP, SET_V_MUST_DEF_OP): New SET routines for operands.
+ (PHI_RESULT_PTR, PHI_RESULT, SET_PHI_RESULT): Macros to manage the
+ PHI result as an operand.
+ (PHI_ARG_DEF_PTR, PHI_ARG_DEF, SET_PHI_ARG_DEF, PHI_ARG_DEF_FROM_EDGE,
+ PHI_ARG_DEF_PTR_FROM_EDGE): Macros to manage the PHI arguments.
+ * tree-ssa-pre.c (eliminate): Call propagate_tree_value.
+ * tree-tailcall.c (independent_of_stmt_p, propagate_through_phis): Use
+ PHI_ARG_DEF_FROM_EDGE.
+ * tree.h (PHI_RESULT): Renamed to PHI_RESULT_TREE.
+ (PHI_ARG_DEF): Renamed to PHI_ARG_DEF_TREE.
+
2004-06-17 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
PR tree-optimization/15991
var = PHI_RESULT (phi);
new_phi = create_phi_node (var, bb);
SSA_NAME_DEF_STMT (var) = new_phi;
- PHI_RESULT (phi) = make_ssa_name (SSA_NAME_VAR (var), phi);
+ SET_PHI_RESULT (phi, make_ssa_name (SSA_NAME_VAR (var), phi));
add_phi_arg (&new_phi, PHI_RESULT (phi), fallthru);
}
return ann ? ann->v_must_def_ops : NULL;
}
+/* Return the tree pointer to by USE. */
+static inline tree
+get_use_from_ptr (use_operand_p use)
+{
+ return *(use.use);
+}
+
+/* Return the tree pointer to by DEF. */
+static inline tree
+get_def_from_ptr (def_operand_p def)
+{
+ return *(def.def);
+}
+
/* Return a pointer to the tree that is at INDEX in the USES array. */
-static inline tree *
+static inline use_operand_p
get_use_op_ptr (use_optype uses, unsigned int index)
{
#ifdef ENABLE_CHECKING
return uses->uses[index];
}
-/* Return a pointer to the tree that is at INDEX in the DEFS array. */
-static inline tree *
+/* Return a def_operand_p pointer for element INDEX of DEFS. */
+static inline def_operand_p
get_def_op_ptr (def_optype defs, unsigned int index)
{
#ifdef ENABLE_CHECKING
}
-/* Return a pointer to the tree that is the V_MAY_DEF_RESULT for the V_MAY_DEF
+/* Return the def_operand_p that is the V_MAY_DEF_RESULT for the V_MAY_DEF
at INDEX in the V_MAY_DEFS array. */
-static inline tree *
+static inline def_operand_p
get_v_may_def_result_ptr(v_may_def_optype v_may_defs, unsigned int index)
{
+ def_operand_p op;
#ifdef ENABLE_CHECKING
if (index >= v_may_defs->num_v_may_defs)
abort();
#endif
- return &(v_may_defs->v_may_defs[index * 2]);
+ op.def = &(v_may_defs->v_may_defs[index * 2]);
+ return op;
}
-/* Return a pointer to the tree that is the V_MAY_DEF_OP for the V_MAY_DEF at
+/* Return a use_operand_p that is the V_MAY_DEF_OP for the V_MAY_DEF at
INDEX in the V_MAY_DEFS array. */
-static inline tree *
+static inline use_operand_p
get_v_may_def_op_ptr(v_may_def_optype v_may_defs, unsigned int index)
{
+ use_operand_p op;
#ifdef ENABLE_CHECKING
if (index >= v_may_defs->num_v_may_defs)
abort();
#endif
- return &(v_may_defs->v_may_defs[index * 2 + 1]);
+ op.use = &(v_may_defs->v_may_defs[index * 2 + 1]);
+ return op;
}
-/* Return a pointer to the tree that is at INDEX in the VUSES array. */
-static inline tree *
+/* Return a use_operand_p that is at INDEX in the VUSES array. */
+static inline use_operand_p
get_vuse_op_ptr(vuse_optype vuses, unsigned int index)
{
+ use_operand_p op;
#ifdef ENABLE_CHECKING
if (index >= vuses->num_vuses)
abort();
#endif
- return &(vuses->vuses[index]);
+ op.use = &(vuses->vuses[index]);
+ return op;
}
-/* Return a pointer to the tree that is the V_MUST_DEF_OP for the
+/* Return a def_operand_p that is the V_MUST_DEF_OP for the
V_MUST_DEF at INDEX in the V_MUST_DEFS array. */
-static inline tree *
+static inline def_operand_p
get_v_must_def_op_ptr (v_must_def_optype v_must_defs, unsigned int index)
{
+ def_operand_p op;
#ifdef ENABLE_CHECKING
if (index >= v_must_defs->num_v_must_defs)
abort();
#endif
- return &(v_must_defs->v_must_defs[index]);
+ op.def = &(v_must_defs->v_must_defs[index]);
+ return op;
}
+/* Return a def_operand_p pointer for the result of PHI. */
+static inline def_operand_p
+get_phi_result_ptr (tree phi)
+{
+ def_operand_p op;
+ op.def = &(PHI_RESULT_TREE (phi));
+ return op;
+}
+
+/* Return a use_operand_p pointer for argument I of phinode PHI. */
+static inline use_operand_p
+get_phi_arg_def_ptr (tree phi, int i)
+{
+ use_operand_p op;
+ op.use = &(PHI_ARG_DEF_TREE (phi, i));
+ return op;
+}
+
/* Mark the beginning of changes to the SSA operands for STMT. */
static inline void
start_ssa_stmt_operands (tree stmt ATTRIBUTE_UNUSED)
return -1;
}
-
-/* Return the phi argument number for an edge. */
-static inline struct phi_arg_d *
-phi_element_for_edge (tree phi, edge e)
-{
- int i;
-
- i = phi_arg_from_edge (phi, e);
- if (i != -1)
- return &(PHI_ARG_ELT (phi, i));
- else
- return (struct phi_arg_d *)NULL;
-}
-
/* ----------------------------------------------------------------------- */
/* Return true if T is an executable statement. */
extern void debug_dominator_optimization_stats (void);
/* In tree-ssa-copy.c */
-extern void propagate_value (tree *, tree);
-extern void replace_exp (tree *, tree);
+extern void propagate_value (use_operand_p, tree);
+extern void propagate_tree_value (tree *, tree);
+extern void replace_exp (use_operand_p, tree);
extern bool cprop_into_stmt (tree, varray_type);
extern void cprop_into_successor_phis (basic_block, varray_type, bitmap);
/* In tree-flow-inline.h */
static inline int phi_arg_from_edge (tree, edge);
-static inline struct phi_arg_d *phi_element_for_edge (tree, edge);
static inline bool may_propagate_copy (tree, tree);
static inline bool is_call_clobbered (tree);
static inline void mark_call_clobbered (tree);
static void compute_global_livein (bitmap, bitmap);
static void set_def_block (tree, basic_block);
static void set_livein_block (tree, basic_block);
-static bool prepare_operand_for_rename (tree *op_p, size_t *uid_p, bool);
+static bool prepare_use_operand_for_rename (use_operand_p op_p, size_t *uid_p);
+static bool prepare_def_operand_for_rename (tree def, size_t *uid_p);
static void insert_phi_nodes (bitmap *);
static void rewrite_stmt (struct dom_walk_data *, basic_block,
block_stmt_iterator);
-static inline void rewrite_operand (tree *);
+static inline void rewrite_operand (use_operand_p);
static void insert_phi_nodes_for (tree, bitmap *, varray_type *);
static tree get_reaching_def (tree);
static hashval_t def_blocks_hash (const void *);
uses = USE_OPS (ann);
for (i = 0; i < NUM_USES (uses); i++)
{
- tree *use_p = USE_OP_PTR (uses, i);
+ use_operand_p use_p = USE_OP_PTR (uses, i);
- if (prepare_operand_for_rename (use_p, &uid, true)
+ if (prepare_use_operand_for_rename (use_p, &uid)
&& !TEST_BIT (kills, uid))
- set_livein_block (*use_p, bb);
+ set_livein_block (USE_FROM_PTR (use_p), bb);
}
/* Similarly for virtual uses. */
vuses = VUSE_OPS (ann);
for (i = 0; i < NUM_VUSES (vuses); i++)
{
- tree *use_p = VUSE_OP_PTR (vuses, i);
+ use_operand_p use_p = VUSE_OP_PTR (vuses, i);
- if (prepare_operand_for_rename (use_p, &uid, true))
- set_livein_block (*use_p, bb);
+ if (prepare_use_operand_for_rename (use_p, &uid))
+ set_livein_block (USE_FROM_PTR (use_p), bb);
}
/* Note that virtual definitions are irrelevant for computing KILLS
v_may_defs = V_MAY_DEF_OPS (ann);
for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
{
- if (prepare_operand_for_rename (V_MAY_DEF_OP_PTR (v_may_defs, i),
- &uid, true))
+ use_operand_p use_p = V_MAY_DEF_OP_PTR (v_may_defs, i);
+ if (prepare_use_operand_for_rename (use_p, &uid))
{
/* If we do not already have an SSA_NAME for our destination,
then set the destination to the source. */
if (TREE_CODE (V_MAY_DEF_RESULT (v_may_defs, i)) != SSA_NAME)
- V_MAY_DEF_RESULT (v_may_defs, i) = V_MAY_DEF_OP (v_may_defs, i);
+ SET_V_MAY_DEF_RESULT (v_may_defs, i, USE_FROM_PTR (use_p));
- set_livein_block (V_MAY_DEF_OP (v_may_defs, i), bb);
+ set_livein_block (USE_FROM_PTR (use_p), bb);
set_def_block (V_MAY_DEF_RESULT (v_may_defs, i), bb);
}
}
v_must_defs = V_MUST_DEF_OPS (ann);
for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
{
- tree *def_p = V_MUST_DEF_OP_PTR (v_must_defs, i);
+ tree def = V_MUST_DEF_OP (v_must_defs, i);
- if (prepare_operand_for_rename (def_p, &uid, false))
+ if (prepare_def_operand_for_rename (def, &uid))
{
- set_def_block (*def_p, bb);
+ set_def_block (def, bb);
SET_BIT (kills, uid);
}
}
defs = DEF_OPS (ann);
for (i = 0; i < NUM_DEFS (defs); i++)
{
- tree *def_p = DEF_OP_PTR (defs, i);
+ tree def = DEF_OP (defs, i);
- if (prepare_operand_for_rename (def_p, &uid, false))
+ if (prepare_def_operand_for_rename (def, &uid))
{
- set_def_block (*def_p, bb);
+ set_def_block (def, bb);
SET_BIT (kills, uid);
}
}
}
-/* If the operand pointed to by OP_P needs to be renamed, then
-
- 1. If OP_P is used (rather than set), then strip away any SSA_NAME
- wrapping the operand.
-
- 2. Set *UID_P to the underlying variable's uid.
-
- 3. Return true.
-
- Otherwise return false. */
+/* If the use operand pointed to by OP_P needs to be renamed, then strip away
+ any SSA_NAME wrapping the operand, set *UID_P to the underlying variable's
+ uid, and return true. Otherwise return false. If the operand was an
+ SSA_NAME, change it to the stipped name. */
static bool
-prepare_operand_for_rename (tree *op_p, size_t *uid_p, bool is_use)
+prepare_use_operand_for_rename (use_operand_p op_p, size_t *uid_p)
{
- tree var = (TREE_CODE (*op_p) != SSA_NAME) ? *op_p : SSA_NAME_VAR (*op_p);
+ tree use = USE_FROM_PTR (op_p);
+ tree var = (TREE_CODE (use) != SSA_NAME) ? use : SSA_NAME_VAR (use);
*uid_p = var_ann (var)->uid;
/* Ignore variables that don't need to be renamed. */
By not throwing away SSA_NAMEs on assignments, we avoid a lot of
useless churn of SSA_NAMEs without having to overly complicate the
renamer. */
- if (TREE_CODE (*op_p) == SSA_NAME && is_use)
- *op_p = var;
+ if (TREE_CODE (use) == SSA_NAME)
+ SET_USE (op_p, var);
return true;
}
+/* If the def variable DEF needs to be renamed, then strip away any SSA_NAME
+ wrapping the operand, set *UID_P to the underlying variable's uid and return
+ true. Otherwise return false. */
+
+static bool
+prepare_def_operand_for_rename (tree def, size_t *uid_p)
+{
+ tree var = (TREE_CODE (def) != SSA_NAME) ? def : SSA_NAME_VAR (def);
+ *uid_p = var_ann (var)->uid;
+
+ /* Ignore variables that don't need to be renamed. */
+ if (vars_to_rename && !bitmap_bit_p (vars_to_rename, *uid_p))
+ return false;
+
+ return true;
+}
/* Helper for insert_phi_nodes. If VAR needs PHI nodes, insert them
at the dominance frontier (DFS) of blocks defining VAR. */
/* Step 2. Register the statement's DEF and VDEF operands. */
for (i = 0; i < NUM_DEFS (defs); i++)
{
- tree *def_p = DEF_OP_PTR (defs, i);
+ def_operand_p def_p = DEF_OP_PTR (defs, i);
- if (TREE_CODE (*def_p) != SSA_NAME)
- *def_p = make_ssa_name (*def_p, stmt);
+ if (TREE_CODE (DEF_FROM_PTR (def_p)) != SSA_NAME)
+ SET_DEF (def_p, make_ssa_name (DEF_FROM_PTR (def_p), stmt));
/* FIXME: We shouldn't be registering new defs if the variable
doesn't need to be renamed. */
- register_new_def (*def_p, &bd->block_defs);
+ register_new_def (DEF_FROM_PTR (def_p), &bd->block_defs);
}
/* Register new virtual definitions made by the statement. */
rewrite_operand (V_MAY_DEF_OP_PTR (v_may_defs, i));
if (TREE_CODE (V_MAY_DEF_RESULT (v_may_defs, i)) != SSA_NAME)
- *V_MAY_DEF_RESULT_PTR (v_may_defs, i)
- = make_ssa_name (V_MAY_DEF_RESULT (v_may_defs, i), stmt);
+ SET_V_MAY_DEF_RESULT (v_may_defs, i,
+ make_ssa_name (V_MAY_DEF_RESULT (v_may_defs, i),
+ stmt));
/* FIXME: We shouldn't be registering new defs if the variable
doesn't need to be renamed. */
/* Register new virtual mustdefs made by the statement. */
for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
{
- tree *v_must_def_p = V_MUST_DEF_OP_PTR (v_must_defs, i);
+ def_operand_p v_must_def_p = V_MUST_DEF_OP_PTR (v_must_defs, i);
- if (TREE_CODE (*v_must_def_p) != SSA_NAME)
- *v_must_def_p = make_ssa_name (*v_must_def_p, stmt);
+ if (TREE_CODE (DEF_FROM_PTR (v_must_def_p)) != SSA_NAME)
+ SET_DEF (v_must_def_p,
+ make_ssa_name (DEF_FROM_PTR (v_must_def_p), stmt));
/* FIXME: We shouldn't be registering new mustdefs if the variable
doesn't need to be renamed. */
- register_new_def (*v_must_def_p, &bd->block_defs);
+ register_new_def (DEF_FROM_PTR (v_must_def_p), &bd->block_defs);
}
}
-/* Replace the operand pointed by OP_P with its immediate reaching
+/* Replace the use operand pointed by OP_P with its immediate reaching
definition. */
static inline void
-rewrite_operand (tree *op_p)
+rewrite_operand (use_operand_p op_p)
{
- if (TREE_CODE (*op_p) != SSA_NAME)
- *op_p = get_reaching_def (*op_p);
+ if (TREE_CODE (USE_FROM_PTR (op_p)) != SSA_NAME)
+ SET_USE (op_p, get_reaching_def (USE_FROM_PTR (op_p)));
}
static void eliminate_phi (edge, int, elim_graph);
static tree_live_info_p coalesce_ssa_name (var_map, int);
static void assign_vars (var_map);
-static bool replace_variable (var_map, tree *, tree *);
+static bool replace_use_variable (var_map, use_operand_p, tree *);
+static bool replace_def_variable (var_map, def_operand_p, tree *);
static void eliminate_virtual_phis (void);
static void coalesce_abnormal_edges (var_map, conflict_graph, root_var_p);
static void print_exprs (FILE *, const char *, tree, const char *, tree,
}
-/* Replace *P with whatever variable it has been rewritten to based on the
- partitions in MAP. EXPR is an optional expression vector over SSA versions
- which is used to replace *P with an expression instead of a variable.
+/* Replace use operand P with whatever variable it has been rewritten to based
+ on the partitions in MAP. EXPR is an optional expression vector over SSA
+ versions which is used to replace P with an expression instead of a variable.
If the stmt is changed, return true. */
static inline bool
-replace_variable (var_map map, tree *p, tree *expr)
+replace_use_variable (var_map map, use_operand_p p, tree *expr)
{
tree new_var;
- tree var = *p;
+ tree var = USE_FROM_PTR (p);
/* Check if we are replacing this variable with an expression. */
if (expr)
{
- int version = SSA_NAME_VERSION (*p);
+ int version = SSA_NAME_VERSION (var);
if (expr[version])
{
tree new_expr = TREE_OPERAND (expr[version], 1);
- *p = new_expr;
+ SET_USE (p, new_expr);
/* Clear the stmt's RHS, or GC might bite us. */
TREE_OPERAND (expr[version], 1) = NULL_TREE;
return true;
new_var = var_to_partition_to_var (map, var);
if (new_var)
{
- *p = new_var;
+ SET_USE (p, new_var);
+ set_is_used (new_var);
+ return true;
+ }
+ return false;
+}
+
+
+/* Replace def operand DEF_P with whatever variable it has been rewritten to
+ based on the partitions in MAP. EXPR is an optional expression vector over
+ SSA versions which is used to replace DEF_P with an expression instead of a
+ variable. If the stmt is changed, return true. */
+
+static inline bool
+replace_def_variable (var_map map, def_operand_p def_p, tree *expr)
+{
+ tree new_var;
+ tree var = DEF_FROM_PTR (def_p);
+
+ /* Check if we are replacing this variable with an expression. */
+ if (expr)
+ {
+ int version = SSA_NAME_VERSION (var);
+ if (expr[version])
+ {
+ tree new_expr = TREE_OPERAND (expr[version], 1);
+ SET_DEF (def_p, new_expr);
+ /* Clear the stmt's RHS, or GC might bite us. */
+ TREE_OPERAND (expr[version], 1) = NULL_TREE;
+ return true;
+ }
+ }
+
+ new_var = var_to_partition_to_var (map, var);
+ if (new_var)
+ {
+ SET_DEF (def_p, new_var);
set_is_used (new_var);
return true;
}
use_optype uses;
def_optype defs;
tree stmt = bsi_stmt (si);
- tree *use_p = NULL;
+ use_operand_p use_p;
int remove = 0, is_copy = 0;
stmt_ann_t ann;
for (i = 0; i < num_uses; i++)
{
use_p = USE_OP_PTR (uses, i);
- if (replace_variable (map, use_p, values))
+ if (replace_use_variable (map, use_p, values))
changed = true;
}
{
for (i = 0; i < num_defs; i++)
{
- tree *def_p = DEF_OP_PTR (defs, i);
+ def_operand_p def_p = DEF_OP_PTR (defs, i);
- if (replace_variable (map, def_p, NULL))
+ if (replace_def_variable (map, def_p, NULL))
changed = true;
/* If both SSA_NAMEs coalesce to the same variable,
mark the now redundant copy for removal. */
if (is_copy
&& num_uses == 1
- && use_p
- && def_p
- && (*def_p == *use_p))
+ && (DEF_FROM_PTR (def_p) == USE_OP (uses, 0)))
remove = 1;
}
if (changed)
SSA_NAME_DEF_STMT (new_name) = copy;
/* Now make the argument reference our new SSA_NAME. */
- PHI_ARG_DEF (phi, i) = new_name;
+ SET_PHI_ARG_DEF (phi, i, new_name);
/* Queue the statement for insertion. */
bsi_insert_on_edge (PHI_ARG_EDGE (phi, i), copy);
TREE_SET_CODE (phi, PHI_NODE);
PHI_ARG_CAPACITY (phi) = len;
if (TREE_CODE (var) == SSA_NAME)
- PHI_RESULT (phi) = var;
+ SET_PHI_RESULT (phi, var);
else
- PHI_RESULT (phi) = make_ssa_name (var, phi);
+ SET_PHI_RESULT (phi, make_ssa_name (var, phi));
return phi;
}
for (i = old_len; i < len; i++)
{
- PHI_ARG_DEF (new_phi, i) = NULL_TREE;
+ SET_PHI_ARG_DEF (new_phi, i, NULL_TREE);
PHI_ARG_EDGE (new_phi, i) = NULL;
PHI_ARG_NONZERO (new_phi, i) = false;
}
SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (*phi)) = 1;
}
- PHI_ARG_DEF (*phi, i) = def;
+ SET_PHI_ARG_DEF (*phi, i, def);
PHI_ARG_EDGE (*phi, i) = e;
PHI_ARG_NONZERO (*phi, i) = false;
PHI_NUM_ARGS (*phi)++;
with the element we want to delete. */
if (i != num_elem - 1)
{
- PHI_ARG_DEF (phi, i) = PHI_ARG_DEF (phi, num_elem - 1);
+ SET_PHI_ARG_DEF (phi, i, PHI_ARG_DEF (phi, num_elem - 1));
PHI_ARG_EDGE (phi, i) = PHI_ARG_EDGE (phi, num_elem - 1);
PHI_ARG_NONZERO (phi, i) = PHI_ARG_NONZERO (phi, num_elem - 1);
}
/* Shrink the vector and return. */
- PHI_ARG_DEF (phi, num_elem - 1) = NULL_TREE;
+ SET_PHI_ARG_DEF (phi, num_elem - 1, NULL_TREE);
PHI_ARG_EDGE (phi, num_elem - 1) = NULL;
PHI_ARG_NONZERO (phi, num_elem - 1) = false;
PHI_NUM_ARGS (phi)--;
for (i = 0; i < PHI_NUM_ARGS (phi); i++)
{
value *new_val;
- tree *orig_p = &PHI_ARG_DEF (phi, i);
+ use_operand_p orig_p = PHI_ARG_DEF_PTR (phi, i);
+ tree orig = USE_FROM_PTR (orig_p);
- if (! SSA_VAR_P (*orig_p))
+ if (! SSA_VAR_P (orig))
break;
- new_val = get_value (*orig_p);
+ new_val = get_value (orig);
if (new_val->lattice_val == CONSTANT
- && may_propagate_copy (*orig_p, new_val->const_val))
- *orig_p = new_val->const_val;
+ && may_propagate_copy (orig, new_val->const_val))
+ SET_USE (orig_p, new_val->const_val);
}
}
/* Restore operands to their original form. */
for (i = 0; i < NUM_USES (uses); i++)
- *(USE_OP_PTR (uses, i)) = orig[i];
+ SET_USE_OP (uses, i, orig[i]);
free (orig);
}
}
uses = STMT_USE_OPS (stmt);
for (i = 0; i < NUM_USES (uses); i++)
{
- tree *use = USE_OP_PTR (uses, i);
- value *val = get_value (*use);
+ use_operand_p use = USE_OP_PTR (uses, i);
+ value *val = get_value (USE_FROM_PTR (use));
if (val->lattice_val == CONSTANT)
{
- *use = val->const_val;
+ SET_USE (use, val->const_val);
replaced = true;
- if (POINTER_TYPE_P (TREE_TYPE (*use)) && replaced_addresses_p)
+ if (POINTER_TYPE_P (TREE_TYPE (USE_FROM_PTR (use)))
+ && replaced_addresses_p)
*replaced_addresses_p = true;
}
}
replacements of one SSA_NAME with a different SSA_NAME to use the
APIs defined in this file. */
-/* Given two SSA_NAMEs, replace the one pointed to by OP_P with VAR.
- If *OP_P is a pointer, copy the memory tag used originally by *OP_P into
+/* Given two SSA_NAMEs, replace the annotations for the one referred to by OP
+ with VAR's annmoptations.
+
+ If OP is a pointer, copy the memory tag used originally by OP into
VAR. This is needed in cases where VAR had never been dereferenced in the
program.
If FOR_PROPAGATION is true, then perform additional checks to ensure
- that const/copy propagation of var for *OP_P is valid. */
+ that const/copy propagation of var for OP is valid. */
static void
-replace_ssa_names (tree *op_p,
+replace_ssa_names_ann (tree op,
tree var,
bool for_propagation ATTRIBUTE_UNUSED)
{
#if defined ENABLE_CHECKING
- if (for_propagation && !may_propagate_copy (*op_p, var))
+ if (for_propagation && !may_propagate_copy (op, var))
abort ();
#endif
/* If VAR doesn't have a memory tag, copy the one from the original
operand. Also copy the dereferenced flags. */
- if (POINTER_TYPE_P (TREE_TYPE (*op_p)))
+ if (POINTER_TYPE_P (TREE_TYPE (op)))
{
var_ann_t new_ann = var_ann (SSA_NAME_VAR (var));
- var_ann_t orig_ann = var_ann (SSA_NAME_VAR (*op_p));
+ var_ann_t orig_ann = var_ann (SSA_NAME_VAR (op));
if (new_ann->type_mem_tag == NULL_TREE)
new_ann->type_mem_tag = orig_ann->type_mem_tag;
abort ();
}
- *op_p = var;
-}
+}
+
/* Common code for propagate_value and replace_exp.
- Replace *OP_P with VAL. FOR_PROPAGATION indicates if the replacement
- is done to propagate a value or not. */
+ Replace use operand OP_P with VAL. FOR_PROPAGATION indicates if the
+ replacement is done to propagate a value or not. */
static void
-replace_exp_1 (tree *op_p, tree val, bool for_propagation)
+replace_exp_1 (use_operand_p op_p, tree val, bool for_propagation)
{
if (TREE_CODE (val) == SSA_NAME)
{
- if (TREE_CODE (*op_p) == SSA_NAME)
- replace_ssa_names (op_p, val, for_propagation);
- else
- *op_p = val;
+ if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
+ replace_ssa_names_ann (USE_FROM_PTR (op_p), val, for_propagation);
+ SET_USE (op_p, val);
}
else
- *op_p = lhd_unsave_expr_now (val);
+ SET_USE (op_p, lhd_unsave_expr_now (val));
}
/* Propagate the value VAL (assumed to be a constant or another SSA_NAME)
checks to ensure validity of the const/copy propagation. */
void
-propagate_value (tree *op_p, tree val)
+propagate_value (use_operand_p op_p, tree val)
{
replace_exp_1 (op_p, val, true);
}
+/* Propagate the value VAL (assumed to be a constant or another SSA_NAME)
+ into the tree pointed by OP_P.
+
+ Use this version for const/copy propagation when SSA operands are not
+ available. It will perform the additional checks to ensure validity of
+ the const/copy propagation, but will not update any operand information.
+ Be sure to mark the stmt as modified. */
+
+void
+propagate_tree_value (tree *op_p, tree val)
+{
+ if (TREE_CODE (val) == SSA_NAME)
+ {
+ if (TREE_CODE (*op_p) == SSA_NAME)
+ replace_ssa_names_ann (*op_p, val, true);
+ *op_p = val;
+ }
+ else
+ *op_p = lhd_unsave_expr_now (val);
+}
+
/* Replace *OP_P with value VAL (assumed to be a constant or another SSA_NAME).
Use this version when not const/copy propagating values. For example,
in specific blocks taking into account actions of PHI nodes. */
void
-replace_exp (tree *op_p, tree val)
+replace_exp (use_operand_p op_p, tree val)
{
replace_exp_1 (op_p, val, false);
}
CONST_AND_COPIES. */
static bool
-cprop_operand (stmt_ann_t ann, tree *op_p, varray_type const_and_copies)
+cprop_operand (stmt_ann_t ann, use_operand_p op_p, varray_type const_and_copies)
{
bool may_have_exposed_new_symbols = false;
tree val;
+ tree op = USE_FROM_PTR (op_p);
/* If the operand has a known constant value or it is known to be a
copy of some other variable, use the value or copy stored in
CONST_AND_COPIES. */
- val = VARRAY_TREE (const_and_copies, SSA_NAME_VERSION (*op_p));
+ val = VARRAY_TREE (const_and_copies, SSA_NAME_VERSION (op));
if (val)
{
tree op_type, val_type;
the renamed virtual operand if we later modify this
statement. Also only allow the new value to be an SSA_NAME
for propagation into virtual operands. */
- if (!is_gimple_reg (*op_p)
- && (get_virtual_var (val) != get_virtual_var (*op_p)
+ if (!is_gimple_reg (op)
+ && (get_virtual_var (val) != get_virtual_var (op)
|| TREE_CODE (val) != SSA_NAME))
return false;
/* Get the toplevel type of each operand. */
- op_type = TREE_TYPE (*op_p);
+ op_type = TREE_TYPE (op);
val_type = TREE_TYPE (val);
/* While both types are pointers, get the type of the object
if (!lang_hooks.types_compatible_p (op_type, val_type)
&& TREE_CODE (val) != SSA_NAME)
{
- val = fold_convert (TREE_TYPE (*op_p), val);
+ val = fold_convert (TREE_TYPE (op), val);
if (!is_gimple_min_invariant (val)
&& TREE_CODE (val) != SSA_NAME)
return false;
to their interaction with exception handling and some GCC
extensions. */
if (TREE_CODE (val) == SSA_NAME
- && !may_propagate_copy (*op_p, val))
+ && !may_propagate_copy (op, val))
return false;
/* Dump details. */
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " Replaced '");
- print_generic_expr (dump_file, *op_p, dump_flags);
+ print_generic_expr (dump_file, op, dump_flags);
fprintf (dump_file, "' with %s '",
(TREE_CODE (val) != SSA_NAME ? "constant" : "variable"));
print_generic_expr (dump_file, val, dump_flags);
/* If VAL is an ADDR_EXPR or a constant of pointer type, note
that we may have exposed a new symbol for SSA renaming. */
if (TREE_CODE (val) == ADDR_EXPR
- || (POINTER_TYPE_P (TREE_TYPE (*op_p))
+ || (POINTER_TYPE_P (TREE_TYPE (op))
&& is_gimple_min_invariant (val)))
may_have_exposed_new_symbols = true;
num_uses = NUM_USES (uses);
for (i = 0; i < num_uses; i++)
{
- tree *op_p = USE_OP_PTR (uses, i);
- if (TREE_CODE (*op_p) == SSA_NAME)
+ use_operand_p op_p = USE_OP_PTR (uses, i);
+ if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
may_have_exposed_new_symbols
|= cprop_operand (ann, op_p, const_and_copies);
}
num_vuses = NUM_VUSES (vuses);
for (i = 0; i < num_vuses; i++)
{
- tree *op_p = VUSE_OP_PTR (vuses, i);
- if (TREE_CODE (*op_p) == SSA_NAME)
+ use_operand_p op_p = VUSE_OP_PTR (vuses, i);
+ if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
may_have_exposed_new_symbols
|= cprop_operand (ann, op_p, const_and_copies);
}
num_v_may_defs = NUM_V_MAY_DEFS (v_may_defs);
for (i = 0; i < num_v_may_defs; i++)
{
- tree *op_p = V_MAY_DEF_OP_PTR (v_may_defs, i);
- if (TREE_CODE (*op_p) == SSA_NAME)
+ use_operand_p op_p = V_MAY_DEF_OP_PTR (v_may_defs, i);
+ if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
may_have_exposed_new_symbols
|= cprop_operand (ann, op_p, const_and_copies);
}
{
int i;
tree new;
- tree *orig_p;
+ use_operand_p orig_p;
+ tree orig;
/* If the hint is valid (!= phi_num_args), see if it points
us to the desired phi alternative. */
/* The alternative may be associated with a constant, so verify
it is an SSA_NAME before doing anything with it. */
- orig_p = &PHI_ARG_DEF (phi, hint);
- if (TREE_CODE (*orig_p) != SSA_NAME)
+ orig_p = PHI_ARG_DEF_PTR (phi, hint);
+ orig = USE_FROM_PTR (orig_p);
+ if (TREE_CODE (orig) != SSA_NAME)
continue;
/* If the alternative is known to have a nonzero value, record
that fact in the PHI node itself for future use. */
- if (bitmap_bit_p (nonzero_vars, SSA_NAME_VERSION (*orig_p)))
+ if (bitmap_bit_p (nonzero_vars, SSA_NAME_VERSION (orig)))
PHI_ARG_NONZERO (phi, hint) = true;
/* If we have *ORIG_P in our constant/copy table, then replace
ORIG_P with its value in our constant/copy table. */
- new = VARRAY_TREE (const_and_copies, SSA_NAME_VERSION (*orig_p));
+ new = VARRAY_TREE (const_and_copies, SSA_NAME_VERSION (orig));
if (new
&& (TREE_CODE (new) == SSA_NAME
|| is_gimple_min_invariant (new))
- && may_propagate_copy (*orig_p, new))
+ && may_propagate_copy (orig, new))
propagate_value (orig_p, new);
}
}
/* Each PHI creates a temporary equivalence, record them. */
for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
{
- tree src = PHI_ARG_DEF (phi, phi_arg_from_edge (phi, e));
+ tree src = PHI_ARG_DEF_FROM_EDGE (phi, e);
tree dst = PHI_RESULT (phi);
record_const_or_copy (dst, src, &bd->const_and_copies);
register_new_def (dst, &bd->block_defs);
if (TREE_CODE (USE_OP (uses, i)) == SSA_NAME)
tmp = get_value_for (USE_OP (uses, i), const_and_copies);
if (tmp)
- *USE_OP_PTR (uses, i) = tmp;
+ SET_USE_OP (uses, i, tmp);
}
/* Similarly for virtual uses. */
if (TREE_CODE (VUSE_OP (vuses, i)) == SSA_NAME)
tmp = get_value_for (VUSE_OP (vuses, i), const_and_copies);
if (tmp)
- VUSE_OP (vuses, i) = tmp;
+ SET_VUSE_OP (vuses, i, tmp);
}
/* Try to lookup the new expression. */
/* Restore the statement's original uses/defs. */
for (i = 0; i < NUM_USES (uses); i++)
- *USE_OP_PTR (uses, i) = uses_copy[i];
+ SET_USE_OP (uses, i, uses_copy[i]);
for (i = 0; i < NUM_VUSES (vuses); i++)
- VUSE_OP (vuses, i) = vuses_copy[i];
+ SET_VUSE_OP (vuses, i, vuses_copy[i]);
free (uses_copy);
free (vuses_copy);
&& is_gimple_min_invariant (cached_lhs)))
retval = true;
- propagate_value (expr_p, cached_lhs);
+ propagate_tree_value (expr_p, cached_lhs);
ann->modified = 1;
}
return retval;
them with the appropriate V_MAY_DEF_OP. */
for (j = 0; j < PHI_NUM_ARGS (phi); j++)
if (v_may_def == PHI_ARG_DEF (phi, j))
- PHI_ARG_DEF (phi, j) = V_MAY_DEF_OP (v_may_defs, i);
+ SET_PHI_ARG_DEF (phi, j, V_MAY_DEF_OP (v_may_defs, i));
}
}
if (v_may_def1 == V_MAY_DEF_RESULT (v_may_defs2, j))
{
/* Update. */
- *V_MAY_DEF_OP_PTR (v_may_defs1, i) =
- V_MAY_DEF_OP (v_may_defs2, j);
+ SET_V_MAY_DEF_OP (v_may_defs1, i, V_MAY_DEF_OP (v_may_defs2, j));
break;
}
}
{
block_stmt_iterator bsi;
basic_block bb;
- tree *dest, *use;
+ tree dest, use;
tree stmt;
stmt_ann_t ann;
vuse_optype vuses;
uses = USE_OPS (ann);
for (x = 0; x < NUM_USES (uses); x++)
{
- use = USE_OP_PTR (uses, x);
- register_ssa_partition (map, *use, true);
+ use = USE_OP (uses, x);
+ register_ssa_partition (map, use, true);
#if defined ENABLE_CHECKING
- SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (*use))->uid);
+ SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (use))->uid);
#endif
}
defs = DEF_OPS (ann);
for (x = 0; x < NUM_DEFS (defs); x++)
{
- dest = DEF_OP_PTR (defs, x);
- register_ssa_partition (map, *dest, false);
+ dest = DEF_OP (defs, x);
+ register_ssa_partition (map, dest, false);
#if defined ENABLE_CHECKING
- SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (*dest))->uid);
+ SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (dest))->uid);
#endif
}
if (!is_a_copy)
{
- tree *var_p;
+ tree var;
defs = DEF_OPS (ann);
num = NUM_DEFS (defs);
for (x = 0; x < num; x++)
{
- var_p = DEF_OP_PTR (defs, x);
- add_conflicts_if_valid (tpa, graph, map, live, *var_p);
+ var = DEF_OP (defs, x);
+ add_conflicts_if_valid (tpa, graph, map, live, var);
}
uses = USE_OPS (ann);
num = NUM_USES (uses);
for (x = 0; x < num; x++)
{
- var_p = USE_OP_PTR (uses, x);
- set_if_valid (map, live, *var_p);
+ var = USE_OP (uses, x);
+ set_if_valid (map, live, var);
}
}
}
for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
{
- tree def = phi_element_for_edge (phi, e)->def;
+ tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
add_phi_arg (&phi, def, e1);
}
}
static void add_call_read_ops (tree, voperands_t);
static void add_stmt_operand (tree *, tree, int, voperands_t);
-
-struct freelist_d GTY((chain_next ("%h.next")))
-{
- struct freelist_d *next;
-};
-
-#define NUM_FREE 5
-static GTY ((length ("NUM_FREE"))) struct freelist_d optype_freelist[NUM_FREE] = { {0}, {0}, {0}, {0}, {0} };
-
-
-static inline void *
-check_optype_freelist (size_t num ATTRIBUTE_UNUSED)
-{
- return NULL;
-#if 0
- void *vec = NULL;
-
- if (num <= NUM_FREE && optype_freelist[num - 1].next)
- {
- vec = (void *)optype_freelist[num - 1].next;
- optype_freelist[num - 1].next = optype_freelist[num - 1].next->next;
- }
- return vec;
-#endif
-}
/* Return a vector of contiguous memory of a specified size. */
-
-static inline void
-add_optype_freelist (void *vec ATTRIBUTE_UNUSED, size_t size ATTRIBUTE_UNUSED)
-{
-#if 0
- struct freelist_d *ptr;
-#ifdef ENABLE_CHECKING
- if (size == 0)
- abort ();
-#endif
-
- /* if its bigger than one of our lists, simply let it go and let GC
- collect it. */
- if (size > NUM_FREE)
- return;
-
- ptr = vec;
- ptr->next = optype_freelist[size - 1].next;;
- optype_freelist[size - 1].next = ptr;
-#endif
-}
-
-
static inline def_optype
allocate_def_optype (unsigned num)
{
def_optype def_ops;
unsigned size;
size = sizeof (struct def_optype_d) + sizeof (tree *) * (num - 1);
- def_ops = check_optype_freelist (num);
- if (!def_ops)
- def_ops = ggc_alloc (size);
+ def_ops = ggc_alloc (size);
def_ops->num_defs = num;
return def_ops;
}
use_optype use_ops;
unsigned size;
size = sizeof (struct use_optype_d) + sizeof (tree *) * (num - 1);
- use_ops = check_optype_freelist (num);
- if (!use_ops)
- use_ops = ggc_alloc (size);
+ use_ops = ggc_alloc (size);
use_ops->num_uses = num;
return use_ops;
}
v_may_def_optype v_may_def_ops;
unsigned size;
size = sizeof (struct v_may_def_optype_d) + sizeof (tree) * ((num * 2) - 1);
- v_may_def_ops = check_optype_freelist (num * 2);
- if (!v_may_def_ops)
- v_may_def_ops = ggc_alloc (size);
+ v_may_def_ops = ggc_alloc (size);
v_may_def_ops->num_v_may_defs = num;
return v_may_def_ops;
}
vuse_optype vuse_ops;
unsigned size;
size = sizeof (struct vuse_optype_d) + sizeof (tree) * (num - 1);
- vuse_ops = check_optype_freelist (num);
- if (!vuse_ops)
- vuse_ops = ggc_alloc (size);
+ vuse_ops = ggc_alloc (size);
vuse_ops->num_vuses = num;
return vuse_ops;
}
v_must_def_optype v_must_def_ops;
unsigned size;
size = sizeof (struct v_must_def_optype_d) + sizeof (tree *) * (num - 1);
- v_must_def_ops = check_optype_freelist (num);
- if (!v_must_def_ops)
- v_must_def_ops = ggc_alloc (size);
+ v_must_def_ops = ggc_alloc (size);
v_must_def_ops->num_v_must_defs = num;
return v_must_def_ops;
}
if (*uses)
{
if (dealloc)
- add_optype_freelist (*uses, (*uses)->num_uses);
+ ggc_free (*uses);
*uses = NULL;
}
}
if (*defs)
{
if (dealloc)
- add_optype_freelist (*defs, (*defs)->num_defs);
+ ggc_free (*defs);
*defs = NULL;
}
}
if (*vuses)
{
if (dealloc)
- add_optype_freelist (*vuses, (*vuses)->num_vuses);
+ ggc_free (*vuses);
*vuses = NULL;
}
}
if (*v_may_defs)
{
if (dealloc)
- add_optype_freelist (*v_may_defs, (*v_may_defs)->num_v_may_defs);
+ ggc_free (*v_may_defs);
*v_may_defs = NULL;
}
}
if (*v_must_defs)
{
if (dealloc)
- add_optype_freelist (*v_must_defs, (*v_must_defs)->num_v_must_defs);
+ ggc_free (*v_must_defs);
*v_must_defs = NULL;
}
}
void
init_ssa_operands (void)
{
- int x;
-
VARRAY_TREE_PTR_INIT (build_defs, 5, "build defs");
VARRAY_TREE_PTR_INIT (build_uses, 10, "build uses");
VARRAY_TREE_INIT (build_v_may_defs, 10, "build v_may_defs");
VARRAY_TREE_INIT (build_vuses, 10, "build vuses");
VARRAY_TREE_INIT (build_v_must_defs, 10, "build v_must_defs");
-
- for (x = 0; x < NUM_FREE; x++)
- optype_freelist[x].next = NULL;
}
void
fini_ssa_operands (void)
{
- int x;
- for (x = 0; x < NUM_FREE; x++)
- optype_freelist[x].next = NULL;
}
static void
def_ops = allocate_def_optype (num);
for (x = 0; x < num ; x++)
- def_ops->defs[x] = VARRAY_TREE_PTR (build_defs, x);
+ def_ops->defs[x].def = VARRAY_TREE_PTR (build_defs, x);
VARRAY_POP_ALL (build_defs);
ann = stmt_ann (stmt);
use_ops = allocate_use_optype (num);
for (x = 0; x < num ; x++)
- use_ops->uses[x] = VARRAY_TREE_PTR (build_uses, x);
+ use_ops->uses[x].use = VARRAY_TREE_PTR (build_uses, x);
VARRAY_POP_ALL (build_uses);
ann = stmt_ann (stmt);
/* Interface to SSA operands. */
+
+/* This represents a pointer to a DEF operand. */
+typedef struct def_operand_ptr GTY(())
+{
+ tree * GTY((skip(""))) def;
+} def_operand_p;
+
+/* This represents a pointer to a USE operand. */
+typedef struct use_operand_ptr GTY(())
+{
+ tree * GTY((skip(""))) use;
+} use_operand_p;
+
+
+/* This represents the DEF operands of a stmt. */
typedef struct def_optype_d GTY(())
{
unsigned num_defs;
- tree * GTY((length("%h.num_defs"), skip(""))) defs[1];
+ struct def_operand_ptr GTY((length("%h.num_defs"))) defs[1];
} def_optype_t;
typedef def_optype_t *def_optype;
+/* This represents the USE operands of a stmt. */
typedef struct use_optype_d GTY(())
{
unsigned num_uses;
- tree * GTY((length("%h.num_uses"), skip(""))) uses[1];
+ struct use_operand_ptr GTY((length("%h.num_uses"))) uses[1];
} use_optype_t;
typedef use_optype_t *use_optype;
+/* This represents the MAY_DEFS for a stmt. */
typedef struct v_may_def_optype_d GTY(())
{
unsigned num_v_may_defs;
typedef v_may_def_optype_t *v_may_def_optype;
+/* This represents the VUSEs for a stmt. */
typedef struct vuse_optype_d GTY(())
{
unsigned num_vuses;
typedef vuse_optype_t *vuse_optype;
+/* This represents the V_MUST_DEFS for a stmt. */
typedef struct v_must_def_optype_d GTY(())
{
unsigned num_v_must_defs;
typedef v_must_def_optype_t *v_must_def_optype;
+#define USE_FROM_PTR(OP) get_use_from_ptr (OP)
+#define DEF_FROM_PTR(OP) get_def_from_ptr (OP)
+#define SET_USE(OP, V) ((*((OP).use)) = (V))
+#define SET_DEF(OP, V) ((*((OP).def)) = (V))
+
+
#define USE_OPS(ANN) get_use_ops (ANN)
#define STMT_USE_OPS(STMT) get_use_ops (stmt_ann (STMT))
#define NUM_USES(OPS) ((OPS) ? (OPS)->num_uses : 0)
#define USE_OP_PTR(OPS, I) get_use_op_ptr ((OPS), (I))
-#define USE_OP(OPS, I) (*(USE_OP_PTR ((OPS), (I))))
+#define USE_OP(OPS, I) (USE_FROM_PTR (USE_OP_PTR ((OPS), (I))))
+#define SET_USE_OP(OPS, I, V) (SET_USE (USE_OP_PTR ((OPS), (I)), (V)))
+
#define DEF_OPS(ANN) get_def_ops (ANN)
#define STMT_DEF_OPS(STMT) get_def_ops (stmt_ann (STMT))
#define NUM_DEFS(OPS) ((OPS) ? (OPS)->num_defs : 0)
#define DEF_OP_PTR(OPS, I) get_def_op_ptr ((OPS), (I))
-#define DEF_OP(OPS, I) (*(DEF_OP_PTR ((OPS), (I))))
+#define DEF_OP(OPS, I) (DEF_FROM_PTR (DEF_OP_PTR ((OPS), (I))))
+#define SET_DEF_OP(OPS, I, V) (SET_DEF (DEF_OP_PTR ((OPS), (I)), (V)))
+
#define V_MAY_DEF_OPS(ANN) get_v_may_def_ops (ANN)
#define STMT_V_MAY_DEF_OPS(STMT) get_v_may_def_ops (stmt_ann(STMT))
#define NUM_V_MAY_DEFS(OPS) ((OPS) ? (OPS)->num_v_may_defs : 0)
#define V_MAY_DEF_RESULT_PTR(OPS, I) get_v_may_def_result_ptr ((OPS), (I))
-#define V_MAY_DEF_RESULT(OPS, I) (*(V_MAY_DEF_RESULT_PTR ((OPS), (I))))
+#define V_MAY_DEF_RESULT(OPS, I) \
+ (DEF_FROM_PTR (V_MAY_DEF_RESULT_PTR ((OPS), (I))))
+#define SET_V_MAY_DEF_RESULT(OPS, I, V) \
+ (SET_DEF (V_MAY_DEF_RESULT_PTR ((OPS), (I)), (V)))
#define V_MAY_DEF_OP_PTR(OPS, I) get_v_may_def_op_ptr ((OPS), (I))
-#define V_MAY_DEF_OP(OPS, I) (*(V_MAY_DEF_OP_PTR ((OPS), (I))))
+#define V_MAY_DEF_OP(OPS, I) \
+ (USE_FROM_PTR (V_MAY_DEF_OP_PTR ((OPS), (I))))
+#define SET_V_MAY_DEF_OP(OPS, I, V) \
+ (SET_USE (V_MAY_DEF_OP_PTR ((OPS), (I)), (V)))
#define VUSE_OPS(ANN) get_vuse_ops (ANN)
#define STMT_VUSE_OPS(STMT) get_vuse_ops (stmt_ann(STMT))
#define NUM_VUSES(OPS) ((OPS) ? (OPS)->num_vuses : 0)
#define VUSE_OP_PTR(OPS, I) get_vuse_op_ptr ((OPS), (I))
-#define VUSE_OP(OPS, I) (*(VUSE_OP_PTR ((OPS), (I))))
+#define VUSE_OP(OPS, I) (USE_FROM_PTR (VUSE_OP_PTR ((OPS), (I))))
+#define SET_VUSE_OP(OPS, I, V) (SET_USE (VUSE_OP_PTR ((OPS), (I)), (V)))
#define V_MUST_DEF_OPS(ANN) get_v_must_def_ops (ANN)
#define STMT_V_MUST_DEF_OPS(STMT) get_v_must_def_ops (stmt_ann (STMT))
#define NUM_V_MUST_DEFS(OPS) ((OPS) ? (OPS)->num_v_must_defs : 0)
#define V_MUST_DEF_OP_PTR(OPS, I) get_v_must_def_op_ptr ((OPS), (I))
-#define V_MUST_DEF_OP(OPS, I) (*(V_MUST_DEF_OP_PTR ((OPS), (I))))
+#define V_MUST_DEF_OP(OPS, I) \
+ (DEF_FROM_PTR (V_MUST_DEF_OP_PTR ((OPS), (I))))
+#define SET_V_MUST_DEF_OP(OPS, I, V) \
+ (SET_DEF (V_MUST_DEF_OP_PTR ((OPS), (I)), (V)))
+
+
+#define PHI_RESULT_PTR(PHI) get_phi_result_ptr (PHI)
+#define PHI_RESULT(PHI) DEF_FROM_PTR (PHI_RESULT_PTR (PHI))
+#define SET_PHI_RESULT(PHI, V) SET_DEF (PHI_RESULT_PTR (PHI), (V))
+
+#define PHI_ARG_DEF_PTR(PHI, I) get_phi_arg_def_ptr ((PHI), (I))
+#define PHI_ARG_DEF(PHI, I) USE_FROM_PTR (PHI_ARG_DEF_PTR ((PHI), (I)))
+#define SET_PHI_ARG_DEF(PHI, I, V) \
+ SET_USE (PHI_ARG_DEF_PTR ((PHI), (I)), (V))
+#define PHI_ARG_DEF_FROM_EDGE(PHI, E) \
+ PHI_ARG_DEF ((PHI), \
+ phi_arg_from_edge ((PHI),(E)))
+#define PHI_ARG_DEF_PTR_FROM_EDGE(PHI, E) \
+ PHI_ARG_DEF_PTR ((PHI), \
+ phi_arg_from_edge ((PHI),(E)))
+
extern void init_ssa_operands (void);
extern void fini_ssa_operands (void);
print_generic_stmt (dump_file, stmt, 0);
}
pre_stats.eliminations++;
- propagate_value (&TREE_OPERAND (stmt, 1), sprime);
+ propagate_tree_value (&TREE_OPERAND (stmt, 1), sprime);
modify_stmt (stmt);
}
}
for (j = 0; j < PHI_NUM_ARGS (stmt); j++)
if (PHI_ARG_DEF (stmt, j) == var)
{
- PHI_ARG_DEF (stmt, j) = repl;
+ SET_PHI_ARG_DEF (stmt, j, repl);
if (TREE_CODE (repl) == SSA_NAME
&& PHI_ARG_EDGE (stmt, j)->flags & EDGE_ABNORMAL)
SSA_NAME_OCCURS_IN_ABNORMAL_PHI (repl) = 1;
if (!e)
abort ();
- expr = phi_element_for_edge (at, e)->def;
+ expr = PHI_ARG_DEF_FROM_EDGE (at, e);
}
/* Unmark the blocks. */
tree phi;
for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
- if (phi_element_for_edge (phi, e)->def == var)
+ if (PHI_ARG_DEF_FROM_EDGE (phi, e) == var)
return PHI_RESULT (phi);
return var;
};
\f
/* In a PHI_NODE node. */
-#define PHI_RESULT(NODE) PHI_NODE_CHECK (NODE)->phi.result
+#define PHI_RESULT_TREE(NODE) PHI_NODE_CHECK (NODE)->phi.result
+#define PHI_ARG_DEF_TREE(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).def
/* PHI_NODEs for each basic block are chained together in a single linked
list. The head of the list is linked from the block annotation, and
/* Nonzero if the PHI node was rewritten by a previous pass through the
SSA renamer. */
-#define PHI_REWRITTEN(NODE) PHI_NODE_CHECK (NODE)->phi.rewritten
-#define PHI_NUM_ARGS(NODE) PHI_NODE_CHECK (NODE)->phi.num_args
-#define PHI_ARG_CAPACITY(NODE) PHI_NODE_CHECK (NODE)->phi.capacity
-#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_DEF(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).def
-#define PHI_ARG_NONZERO(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).nonzero
+#define PHI_REWRITTEN(NODE) PHI_NODE_CHECK (NODE)->phi.rewritten
+#define PHI_NUM_ARGS(NODE) PHI_NODE_CHECK (NODE)->phi.num_args
+#define PHI_ARG_CAPACITY(NODE) PHI_NODE_CHECK (NODE)->phi.capacity
+#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
struct edge_def;