tree-cfg.c (tree_make_forwarder_block): Use SET_PHI_RESULT.
2004-06-16 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. From-SVN: r83298
This commit is contained in:
parent
d7621d3c74
commit
d00ad49ba1
|
@ -1,3 +1,74 @@
|
|||
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
|
||||
|
|
|
@ -3747,7 +3747,7 @@ tree_make_forwarder_block (edge fallthru)
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -272,8 +272,22 @@ get_v_must_def_ops (stmt_ann_t ann)
|
|||
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
|
||||
|
@ -283,8 +297,8 @@ get_use_op_ptr (use_optype uses, unsigned int index)
|
|||
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
|
||||
|
@ -295,53 +309,79 @@ get_def_op_ptr (def_optype defs, unsigned int index)
|
|||
}
|
||||
|
||||
|
||||
/* 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)
|
||||
|
@ -448,20 +488,6 @@ phi_arg_from_edge (tree phi, edge e)
|
|||
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. */
|
||||
|
|
|
@ -580,14 +580,14 @@ extern void dump_dominator_optimization_stats (FILE *);
|
|||
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);
|
||||
|
|
|
@ -109,11 +109,12 @@ static void mark_def_sites_initialize_block (struct dom_walk_data *walk_data,
|
|||
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 *);
|
||||
|
@ -231,21 +232,21 @@ mark_def_sites (struct dom_walk_data *walk_data,
|
|||
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
|
||||
|
@ -256,15 +257,15 @@ mark_def_sites (struct dom_walk_data *walk_data,
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
@ -273,11 +274,11 @@ mark_def_sites (struct dom_walk_data *walk_data,
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
@ -287,11 +288,11 @@ mark_def_sites (struct dom_walk_data *walk_data,
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
@ -367,21 +368,16 @@ set_livein_block (tree var, basic_block bb)
|
|||
}
|
||||
|
||||
|
||||
/* 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. */
|
||||
|
@ -394,12 +390,28 @@ prepare_operand_for_rename (tree *op_p, size_t *uid_p, bool is_use)
|
|||
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. */
|
||||
|
@ -774,14 +786,14 @@ rewrite_stmt (struct dom_walk_data *walk_data,
|
|||
/* 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. */
|
||||
|
@ -790,8 +802,9 @@ rewrite_stmt (struct dom_walk_data *walk_data,
|
|||
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. */
|
||||
|
@ -801,27 +814,28 @@ rewrite_stmt (struct dom_walk_data *walk_data,
|
|||
/* 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)));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -116,7 +116,8 @@ static void elim_create (elim_graph, int);
|
|||
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,
|
||||
|
@ -922,25 +923,25 @@ assign_vars (var_map map)
|
|||
}
|
||||
|
||||
|
||||
/* 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;
|
||||
|
@ -950,7 +951,43 @@ replace_variable (var_map map, tree *p, tree *expr)
|
|||
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;
|
||||
}
|
||||
|
@ -1832,7 +1869,7 @@ rewrite_trees (var_map map, tree *values)
|
|||
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;
|
||||
|
||||
|
@ -1850,7 +1887,7 @@ rewrite_trees (var_map map, tree *values)
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -1871,18 +1908,16 @@ rewrite_trees (var_map map, tree *values)
|
|||
{
|
||||
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)
|
||||
|
@ -2074,7 +2109,7 @@ rewrite_vars_out_of_ssa (bitmap vars)
|
|||
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);
|
||||
|
|
|
@ -203,9 +203,9 @@ make_phi_node (tree var, int len)
|
|||
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;
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ resize_phi_node (tree *phi, int len)
|
|||
|
||||
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;
|
||||
}
|
||||
|
@ -365,7 +365,7 @@ add_phi_arg (tree *phi, tree def, edge e)
|
|||
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)++;
|
||||
|
@ -408,13 +408,13 @@ remove_phi_arg_num (tree phi, int i)
|
|||
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)--;
|
||||
|
|
|
@ -389,15 +389,16 @@ substitute_and_fold (void)
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -948,7 +949,7 @@ ccp_fold (tree stmt)
|
|||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
@ -1422,14 +1423,15 @@ replace_uses_in (tree stmt, bool *replaced_addresses_p)
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,31 +54,33 @@ Boston, MA 02111-1307, USA. */
|
|||
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;
|
||||
|
@ -88,26 +90,25 @@ replace_ssa_names (tree *op_p,
|
|||
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)
|
||||
|
@ -117,11 +118,32 @@ replace_exp_1 (tree *op_p, tree val, bool for_propagation)
|
|||
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,
|
||||
|
@ -129,7 +151,7 @@ propagate_value (tree *op_p, tree val)
|
|||
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);
|
||||
}
|
||||
|
@ -138,15 +160,16 @@ replace_exp (tree *op_p, tree val)
|
|||
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;
|
||||
|
@ -156,13 +179,13 @@ cprop_operand (stmt_ann_t ann, tree *op_p, varray_type const_and_copies)
|
|||
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
|
||||
|
@ -180,7 +203,7 @@ cprop_operand (stmt_ann_t ann, tree *op_p, varray_type const_and_copies)
|
|||
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;
|
||||
|
@ -190,14 +213,14 @@ cprop_operand (stmt_ann_t ann, tree *op_p, varray_type const_and_copies)
|
|||
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);
|
||||
|
@ -207,7 +230,7 @@ cprop_operand (stmt_ann_t ann, tree *op_p, varray_type const_and_copies)
|
|||
/* 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;
|
||||
|
||||
|
@ -241,8 +264,8 @@ cprop_into_stmt (tree stmt, varray_type const_and_copies)
|
|||
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);
|
||||
}
|
||||
|
@ -251,8 +274,8 @@ cprop_into_stmt (tree stmt, varray_type 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);
|
||||
}
|
||||
|
@ -261,8 +284,8 @@ cprop_into_stmt (tree stmt, varray_type 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);
|
||||
}
|
||||
|
@ -317,7 +340,8 @@ cprop_into_successor_phis (basic_block bb,
|
|||
{
|
||||
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. */
|
||||
|
@ -343,22 +367,23 @@ cprop_into_successor_phis (basic_block bb,
|
|||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -700,7 +700,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
|
|||
/* 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);
|
||||
|
@ -761,7 +761,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
|
|||
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. */
|
||||
|
@ -773,7 +773,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
|
|||
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. */
|
||||
|
@ -781,10 +781,10 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
|
|||
|
||||
/* 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);
|
||||
|
@ -2386,7 +2386,7 @@ eliminate_redundant_computations (struct dom_walk_data *walk_data,
|
|||
&& 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;
|
||||
|
|
|
@ -132,7 +132,7 @@ fix_phi_uses (tree phi, tree stmt)
|
|||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,8 +164,7 @@ fix_stmt_v_may_defs (tree stmt1, tree stmt2)
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -294,7 +294,7 @@ create_ssa_var_map (int flags)
|
|||
{
|
||||
block_stmt_iterator bsi;
|
||||
basic_block bb;
|
||||
tree *dest, *use;
|
||||
tree dest, use;
|
||||
tree stmt;
|
||||
stmt_ann_t ann;
|
||||
vuse_optype vuses;
|
||||
|
@ -351,22 +351,22 @@ create_ssa_var_map (int flags)
|
|||
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
|
||||
}
|
||||
|
||||
|
@ -1393,22 +1393,22 @@ build_tree_conflict_graph (tree_live_info_p liveinfo, tpa_p tpa,
|
|||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -225,7 +225,7 @@ duplicate_blocks (varray_type bbs_to_duplicate)
|
|||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,65 +88,15 @@ static void add_call_clobber_ops (tree, voperands_t);
|
|||
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;
|
||||
}
|
||||
|
@ -157,9 +107,7 @@ allocate_use_optype (unsigned num)
|
|||
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;
|
||||
}
|
||||
|
@ -170,9 +118,7 @@ allocate_v_may_def_optype (unsigned num)
|
|||
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;
|
||||
}
|
||||
|
@ -183,9 +129,7 @@ allocate_vuse_optype (unsigned num)
|
|||
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;
|
||||
}
|
||||
|
@ -196,9 +140,7 @@ allocate_v_must_def_optype (unsigned num)
|
|||
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;
|
||||
}
|
||||
|
@ -209,7 +151,7 @@ free_uses (use_optype *uses, bool dealloc)
|
|||
if (*uses)
|
||||
{
|
||||
if (dealloc)
|
||||
add_optype_freelist (*uses, (*uses)->num_uses);
|
||||
ggc_free (*uses);
|
||||
*uses = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +162,7 @@ free_defs (def_optype *defs, bool dealloc)
|
|||
if (*defs)
|
||||
{
|
||||
if (dealloc)
|
||||
add_optype_freelist (*defs, (*defs)->num_defs);
|
||||
ggc_free (*defs);
|
||||
*defs = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -231,7 +173,7 @@ free_vuses (vuse_optype *vuses, bool dealloc)
|
|||
if (*vuses)
|
||||
{
|
||||
if (dealloc)
|
||||
add_optype_freelist (*vuses, (*vuses)->num_vuses);
|
||||
ggc_free (*vuses);
|
||||
*vuses = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -242,7 +184,7 @@ free_v_may_defs (v_may_def_optype *v_may_defs, bool dealloc)
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
@ -253,7 +195,7 @@ free_v_must_defs (v_must_def_optype *v_must_defs, bool dealloc)
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
@ -291,24 +233,16 @@ remove_v_must_defs (tree stmt)
|
|||
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
|
||||
|
@ -330,7 +264,7 @@ finalize_ssa_defs (tree stmt)
|
|||
|
||||
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);
|
||||
|
@ -363,7 +297,7 @@ finalize_ssa_uses (tree 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);
|
||||
|
|
|
@ -23,22 +23,39 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
|
||||
/* 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;
|
||||
|
@ -47,6 +64,7 @@ typedef struct v_may_def_optype_d GTY(())
|
|||
|
||||
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;
|
||||
|
@ -55,6 +73,7 @@ typedef struct vuse_optype_d GTY(())
|
|||
|
||||
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;
|
||||
|
@ -63,41 +82,78 @@ typedef struct v_must_def_optype_d GTY(())
|
|||
|
||||
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);
|
||||
|
|
|
@ -1907,7 +1907,7 @@ eliminate (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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -779,7 +779,7 @@ replace_immediate_uses (tree var, tree repl)
|
|||
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;
|
||||
|
|
|
@ -237,7 +237,7 @@ independent_of_stmt_p (tree expr, tree at, block_stmt_iterator bsi)
|
|||
if (!e)
|
||||
abort ();
|
||||
|
||||
expr = phi_element_for_edge (at, e)->def;
|
||||
expr = PHI_ARG_DEF_FROM_EDGE (at, e);
|
||||
}
|
||||
|
||||
/* Unmark the blocks. */
|
||||
|
@ -340,7 +340,7 @@ propagate_through_phis (tree var, edge e)
|
|||
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;
|
||||
|
|
16
gcc/tree.h
16
gcc/tree.h
|
@ -1206,7 +1206,8 @@ struct tree_ssa_name GTY(())
|
|||
};
|
||||
|
||||
/* 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
|
||||
|
@ -1215,13 +1216,12 @@ struct tree_ssa_name GTY(())
|
|||
|
||||
/* 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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue