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:
Andrew MacLeod 2004-06-17 18:13:20 +00:00 committed by Andrew Macleod
parent d7621d3c74
commit d00ad49ba1
19 changed files with 434 additions and 272 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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. */

View File

@ -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);

View File

@ -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)));
}

View File

@ -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);

View File

@ -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)--;

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;