Commit d00ad49b by Andrew MacLeod Committed by Andrew Macleod

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
parent d7621d3c
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> 2004-06-17 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
PR tree-optimization/15991 PR tree-optimization/15991
......
...@@ -3747,7 +3747,7 @@ tree_make_forwarder_block (edge fallthru) ...@@ -3747,7 +3747,7 @@ tree_make_forwarder_block (edge fallthru)
var = PHI_RESULT (phi); var = PHI_RESULT (phi);
new_phi = create_phi_node (var, bb); new_phi = create_phi_node (var, bb);
SSA_NAME_DEF_STMT (var) = new_phi; 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); add_phi_arg (&new_phi, PHI_RESULT (phi), fallthru);
} }
......
...@@ -272,8 +272,22 @@ get_v_must_def_ops (stmt_ann_t ann) ...@@ -272,8 +272,22 @@ get_v_must_def_ops (stmt_ann_t ann)
return ann ? ann->v_must_def_ops : NULL; 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. */ /* 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) get_use_op_ptr (use_optype uses, unsigned int index)
{ {
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
...@@ -283,8 +297,8 @@ get_use_op_ptr (use_optype uses, unsigned int index) ...@@ -283,8 +297,8 @@ get_use_op_ptr (use_optype uses, unsigned int index)
return uses->uses[index]; return uses->uses[index];
} }
/* Return a pointer to the tree that is at INDEX in the DEFS array. */ /* Return a def_operand_p pointer for element INDEX of DEFS. */
static inline tree * static inline def_operand_p
get_def_op_ptr (def_optype defs, unsigned int index) get_def_op_ptr (def_optype defs, unsigned int index)
{ {
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
...@@ -295,53 +309,79 @@ get_def_op_ptr (def_optype defs, unsigned int index) ...@@ -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. */ 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) get_v_may_def_result_ptr(v_may_def_optype v_may_defs, unsigned int index)
{ {
def_operand_p op;
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
if (index >= v_may_defs->num_v_may_defs) if (index >= v_may_defs->num_v_may_defs)
abort(); abort();
#endif #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. */ 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) get_v_may_def_op_ptr(v_may_def_optype v_may_defs, unsigned int index)
{ {
use_operand_p op;
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
if (index >= v_may_defs->num_v_may_defs) if (index >= v_may_defs->num_v_may_defs)
abort(); abort();
#endif #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. */ /* Return a use_operand_p that is at INDEX in the VUSES array. */
static inline tree * static inline use_operand_p
get_vuse_op_ptr(vuse_optype vuses, unsigned int index) get_vuse_op_ptr(vuse_optype vuses, unsigned int index)
{ {
use_operand_p op;
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
if (index >= vuses->num_vuses) if (index >= vuses->num_vuses)
abort(); abort();
#endif #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. */ 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) get_v_must_def_op_ptr (v_must_def_optype v_must_defs, unsigned int index)
{ {
def_operand_p op;
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
if (index >= v_must_defs->num_v_must_defs) if (index >= v_must_defs->num_v_must_defs)
abort(); abort();
#endif #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. */ /* Mark the beginning of changes to the SSA operands for STMT. */
static inline void static inline void
start_ssa_stmt_operands (tree stmt ATTRIBUTE_UNUSED) start_ssa_stmt_operands (tree stmt ATTRIBUTE_UNUSED)
...@@ -448,20 +488,6 @@ phi_arg_from_edge (tree phi, edge e) ...@@ -448,20 +488,6 @@ phi_arg_from_edge (tree phi, edge e)
return -1; 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. */ /* Return true if T is an executable statement. */
......
...@@ -580,14 +580,14 @@ extern void dump_dominator_optimization_stats (FILE *); ...@@ -580,14 +580,14 @@ extern void dump_dominator_optimization_stats (FILE *);
extern void debug_dominator_optimization_stats (void); extern void debug_dominator_optimization_stats (void);
/* In tree-ssa-copy.c */ /* In tree-ssa-copy.c */
extern void propagate_value (tree *, tree); extern void propagate_value (use_operand_p, tree);
extern void replace_exp (tree *, 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 bool cprop_into_stmt (tree, varray_type);
extern void cprop_into_successor_phis (basic_block, varray_type, bitmap); extern void cprop_into_successor_phis (basic_block, varray_type, bitmap);
/* In tree-flow-inline.h */ /* In tree-flow-inline.h */
static inline int phi_arg_from_edge (tree, edge); 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 may_propagate_copy (tree, tree);
static inline bool is_call_clobbered (tree); static inline bool is_call_clobbered (tree);
static inline void mark_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, ...@@ -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 compute_global_livein (bitmap, bitmap);
static void set_def_block (tree, basic_block); static void set_def_block (tree, basic_block);
static void set_livein_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 insert_phi_nodes (bitmap *);
static void rewrite_stmt (struct dom_walk_data *, basic_block, static void rewrite_stmt (struct dom_walk_data *, basic_block,
block_stmt_iterator); 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 void insert_phi_nodes_for (tree, bitmap *, varray_type *);
static tree get_reaching_def (tree); static tree get_reaching_def (tree);
static hashval_t def_blocks_hash (const void *); static hashval_t def_blocks_hash (const void *);
...@@ -231,21 +232,21 @@ mark_def_sites (struct dom_walk_data *walk_data, ...@@ -231,21 +232,21 @@ mark_def_sites (struct dom_walk_data *walk_data,
uses = USE_OPS (ann); uses = USE_OPS (ann);
for (i = 0; i < NUM_USES (uses); i++) 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)) && !TEST_BIT (kills, uid))
set_livein_block (*use_p, bb); set_livein_block (USE_FROM_PTR (use_p), bb);
} }
/* Similarly for virtual uses. */ /* Similarly for virtual uses. */
vuses = VUSE_OPS (ann); vuses = VUSE_OPS (ann);
for (i = 0; i < NUM_VUSES (vuses); i++) 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)) if (prepare_use_operand_for_rename (use_p, &uid))
set_livein_block (*use_p, bb); set_livein_block (USE_FROM_PTR (use_p), bb);
} }
/* Note that virtual definitions are irrelevant for computing KILLS /* Note that virtual definitions are irrelevant for computing KILLS
...@@ -256,15 +257,15 @@ mark_def_sites (struct dom_walk_data *walk_data, ...@@ -256,15 +257,15 @@ mark_def_sites (struct dom_walk_data *walk_data,
v_may_defs = V_MAY_DEF_OPS (ann); v_may_defs = V_MAY_DEF_OPS (ann);
for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) 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), use_operand_p use_p = V_MAY_DEF_OP_PTR (v_may_defs, i);
&uid, true)) if (prepare_use_operand_for_rename (use_p, &uid))
{ {
/* If we do not already have an SSA_NAME for our destination, /* If we do not already have an SSA_NAME for our destination,
then set the destination to the source. */ then set the destination to the source. */
if (TREE_CODE (V_MAY_DEF_RESULT (v_may_defs, i)) != SSA_NAME) 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); 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, ...@@ -273,11 +274,11 @@ mark_def_sites (struct dom_walk_data *walk_data,
v_must_defs = V_MUST_DEF_OPS (ann); v_must_defs = V_MUST_DEF_OPS (ann);
for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) 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); SET_BIT (kills, uid);
} }
} }
...@@ -287,11 +288,11 @@ mark_def_sites (struct dom_walk_data *walk_data, ...@@ -287,11 +288,11 @@ mark_def_sites (struct dom_walk_data *walk_data,
defs = DEF_OPS (ann); defs = DEF_OPS (ann);
for (i = 0; i < NUM_DEFS (defs); i++) 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); SET_BIT (kills, uid);
} }
} }
...@@ -367,21 +368,16 @@ set_livein_block (tree var, basic_block bb) ...@@ -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 /* 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
1. If OP_P is used (rather than set), then strip away any SSA_NAME uid, and return true. Otherwise return false. If the operand was an
wrapping the operand. SSA_NAME, change it to the stipped name. */
2. Set *UID_P to the underlying variable's uid.
3. Return true.
Otherwise return false. */
static bool 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; *uid_p = var_ann (var)->uid;
/* Ignore variables that don't need to be renamed. */ /* 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) ...@@ -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 By not throwing away SSA_NAMEs on assignments, we avoid a lot of
useless churn of SSA_NAMEs without having to overly complicate the useless churn of SSA_NAMEs without having to overly complicate the
renamer. */ renamer. */
if (TREE_CODE (*op_p) == SSA_NAME && is_use) if (TREE_CODE (use) == SSA_NAME)
*op_p = var; SET_USE (op_p, var);
return true; 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 /* Helper for insert_phi_nodes. If VAR needs PHI nodes, insert them
at the dominance frontier (DFS) of blocks defining VAR. */ at the dominance frontier (DFS) of blocks defining VAR. */
...@@ -774,14 +786,14 @@ rewrite_stmt (struct dom_walk_data *walk_data, ...@@ -774,14 +786,14 @@ rewrite_stmt (struct dom_walk_data *walk_data,
/* Step 2. Register the statement's DEF and VDEF operands. */ /* Step 2. Register the statement's DEF and VDEF operands. */
for (i = 0; i < NUM_DEFS (defs); i++) 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) if (TREE_CODE (DEF_FROM_PTR (def_p)) != SSA_NAME)
*def_p = make_ssa_name (*def_p, stmt); SET_DEF (def_p, make_ssa_name (DEF_FROM_PTR (def_p), stmt));
/* FIXME: We shouldn't be registering new defs if the variable /* FIXME: We shouldn't be registering new defs if the variable
doesn't need to be renamed. */ 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. */ /* Register new virtual definitions made by the statement. */
...@@ -790,8 +802,9 @@ rewrite_stmt (struct dom_walk_data *walk_data, ...@@ -790,8 +802,9 @@ rewrite_stmt (struct dom_walk_data *walk_data,
rewrite_operand (V_MAY_DEF_OP_PTR (v_may_defs, i)); rewrite_operand (V_MAY_DEF_OP_PTR (v_may_defs, i));
if (TREE_CODE (V_MAY_DEF_RESULT (v_may_defs, i)) != SSA_NAME) if (TREE_CODE (V_MAY_DEF_RESULT (v_may_defs, i)) != SSA_NAME)
*V_MAY_DEF_RESULT_PTR (v_may_defs, i) SET_V_MAY_DEF_RESULT (v_may_defs, i,
= make_ssa_name (V_MAY_DEF_RESULT (v_may_defs, i), stmt); make_ssa_name (V_MAY_DEF_RESULT (v_may_defs, i),
stmt));
/* FIXME: We shouldn't be registering new defs if the variable /* FIXME: We shouldn't be registering new defs if the variable
doesn't need to be renamed. */ doesn't need to be renamed. */
...@@ -801,27 +814,28 @@ rewrite_stmt (struct dom_walk_data *walk_data, ...@@ -801,27 +814,28 @@ rewrite_stmt (struct dom_walk_data *walk_data,
/* Register new virtual mustdefs made by the statement. */ /* Register new virtual mustdefs made by the statement. */
for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) 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) if (TREE_CODE (DEF_FROM_PTR (v_must_def_p)) != SSA_NAME)
*v_must_def_p = make_ssa_name (*v_must_def_p, stmt); 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 /* FIXME: We shouldn't be registering new mustdefs if the variable
doesn't need to be renamed. */ 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. */ definition. */
static inline void static inline void
rewrite_operand (tree *op_p) rewrite_operand (use_operand_p op_p)
{ {
if (TREE_CODE (*op_p) != SSA_NAME) if (TREE_CODE (USE_FROM_PTR (op_p)) != SSA_NAME)
*op_p = get_reaching_def (*op_p); SET_USE (op_p, get_reaching_def (USE_FROM_PTR (op_p)));
} }
......
...@@ -116,7 +116,8 @@ static void elim_create (elim_graph, int); ...@@ -116,7 +116,8 @@ static void elim_create (elim_graph, int);
static void eliminate_phi (edge, int, elim_graph); static void eliminate_phi (edge, int, elim_graph);
static tree_live_info_p coalesce_ssa_name (var_map, int); static tree_live_info_p coalesce_ssa_name (var_map, int);
static void assign_vars (var_map); 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 eliminate_virtual_phis (void);
static void coalesce_abnormal_edges (var_map, conflict_graph, root_var_p); static void coalesce_abnormal_edges (var_map, conflict_graph, root_var_p);
static void print_exprs (FILE *, const char *, tree, const char *, tree, static void print_exprs (FILE *, const char *, tree, const char *, tree,
...@@ -922,25 +923,25 @@ assign_vars (var_map map) ...@@ -922,25 +923,25 @@ assign_vars (var_map map)
} }
/* Replace *P with whatever variable it has been rewritten to based on the /* Replace use operand P with whatever variable it has been rewritten to based
partitions in MAP. EXPR is an optional expression vector over SSA versions on the partitions in MAP. EXPR is an optional expression vector over SSA
which is used to replace *P with an expression instead of a variable. versions which is used to replace P with an expression instead of a variable.
If the stmt is changed, return true. */ If the stmt is changed, return true. */
static inline bool 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 new_var;
tree var = *p; tree var = USE_FROM_PTR (p);
/* Check if we are replacing this variable with an expression. */ /* Check if we are replacing this variable with an expression. */
if (expr) if (expr)
{ {
int version = SSA_NAME_VERSION (*p); int version = SSA_NAME_VERSION (var);
if (expr[version]) if (expr[version])
{ {
tree new_expr = TREE_OPERAND (expr[version], 1); 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. */ /* Clear the stmt's RHS, or GC might bite us. */
TREE_OPERAND (expr[version], 1) = NULL_TREE; TREE_OPERAND (expr[version], 1) = NULL_TREE;
return true; return true;
...@@ -950,7 +951,43 @@ replace_variable (var_map map, tree *p, tree *expr) ...@@ -950,7 +951,43 @@ replace_variable (var_map map, tree *p, tree *expr)
new_var = var_to_partition_to_var (map, var); new_var = var_to_partition_to_var (map, var);
if (new_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); set_is_used (new_var);
return true; return true;
} }
...@@ -1832,7 +1869,7 @@ rewrite_trees (var_map map, tree *values) ...@@ -1832,7 +1869,7 @@ rewrite_trees (var_map map, tree *values)
use_optype uses; use_optype uses;
def_optype defs; def_optype defs;
tree stmt = bsi_stmt (si); tree stmt = bsi_stmt (si);
tree *use_p = NULL; use_operand_p use_p;
int remove = 0, is_copy = 0; int remove = 0, is_copy = 0;
stmt_ann_t ann; stmt_ann_t ann;
...@@ -1850,7 +1887,7 @@ rewrite_trees (var_map map, tree *values) ...@@ -1850,7 +1887,7 @@ rewrite_trees (var_map map, tree *values)
for (i = 0; i < num_uses; i++) for (i = 0; i < num_uses; i++)
{ {
use_p = USE_OP_PTR (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; changed = true;
} }
...@@ -1871,18 +1908,16 @@ rewrite_trees (var_map map, tree *values) ...@@ -1871,18 +1908,16 @@ rewrite_trees (var_map map, tree *values)
{ {
for (i = 0; i < num_defs; i++) 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; changed = true;
/* If both SSA_NAMEs coalesce to the same variable, /* If both SSA_NAMEs coalesce to the same variable,
mark the now redundant copy for removal. */ mark the now redundant copy for removal. */
if (is_copy if (is_copy
&& num_uses == 1 && num_uses == 1
&& use_p && (DEF_FROM_PTR (def_p) == USE_OP (uses, 0)))
&& def_p
&& (*def_p == *use_p))
remove = 1; remove = 1;
} }
if (changed) if (changed)
...@@ -2074,7 +2109,7 @@ rewrite_vars_out_of_ssa (bitmap vars) ...@@ -2074,7 +2109,7 @@ rewrite_vars_out_of_ssa (bitmap vars)
SSA_NAME_DEF_STMT (new_name) = copy; SSA_NAME_DEF_STMT (new_name) = copy;
/* Now make the argument reference our new SSA_NAME. */ /* 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. */ /* Queue the statement for insertion. */
bsi_insert_on_edge (PHI_ARG_EDGE (phi, i), copy); bsi_insert_on_edge (PHI_ARG_EDGE (phi, i), copy);
......
...@@ -203,9 +203,9 @@ make_phi_node (tree var, int len) ...@@ -203,9 +203,9 @@ make_phi_node (tree var, int len)
TREE_SET_CODE (phi, PHI_NODE); TREE_SET_CODE (phi, PHI_NODE);
PHI_ARG_CAPACITY (phi) = len; PHI_ARG_CAPACITY (phi) = len;
if (TREE_CODE (var) == SSA_NAME) if (TREE_CODE (var) == SSA_NAME)
PHI_RESULT (phi) = var; SET_PHI_RESULT (phi, var);
else else
PHI_RESULT (phi) = make_ssa_name (var, phi); SET_PHI_RESULT (phi, make_ssa_name (var, phi));
return phi; return phi;
} }
...@@ -278,7 +278,7 @@ resize_phi_node (tree *phi, int len) ...@@ -278,7 +278,7 @@ resize_phi_node (tree *phi, int len)
for (i = old_len; i < len; i++) 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_EDGE (new_phi, i) = NULL;
PHI_ARG_NONZERO (new_phi, i) = false; PHI_ARG_NONZERO (new_phi, i) = false;
} }
...@@ -365,7 +365,7 @@ add_phi_arg (tree *phi, tree def, edge e) ...@@ -365,7 +365,7 @@ add_phi_arg (tree *phi, tree def, edge e)
SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (*phi)) = 1; 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_EDGE (*phi, i) = e;
PHI_ARG_NONZERO (*phi, i) = false; PHI_ARG_NONZERO (*phi, i) = false;
PHI_NUM_ARGS (*phi)++; PHI_NUM_ARGS (*phi)++;
...@@ -408,13 +408,13 @@ remove_phi_arg_num (tree phi, int i) ...@@ -408,13 +408,13 @@ remove_phi_arg_num (tree phi, int i)
with the element we want to delete. */ with the element we want to delete. */
if (i != num_elem - 1) 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_EDGE (phi, i) = PHI_ARG_EDGE (phi, num_elem - 1);
PHI_ARG_NONZERO (phi, i) = PHI_ARG_NONZERO (phi, num_elem - 1); PHI_ARG_NONZERO (phi, i) = PHI_ARG_NONZERO (phi, num_elem - 1);
} }
/* Shrink the vector and return. */ /* 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_EDGE (phi, num_elem - 1) = NULL;
PHI_ARG_NONZERO (phi, num_elem - 1) = false; PHI_ARG_NONZERO (phi, num_elem - 1) = false;
PHI_NUM_ARGS (phi)--; PHI_NUM_ARGS (phi)--;
......
...@@ -389,15 +389,16 @@ substitute_and_fold (void) ...@@ -389,15 +389,16 @@ substitute_and_fold (void)
for (i = 0; i < PHI_NUM_ARGS (phi); i++) for (i = 0; i < PHI_NUM_ARGS (phi); i++)
{ {
value *new_val; 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; break;
new_val = get_value (*orig_p); new_val = get_value (orig);
if (new_val->lattice_val == CONSTANT if (new_val->lattice_val == CONSTANT
&& may_propagate_copy (*orig_p, new_val->const_val)) && may_propagate_copy (orig, new_val->const_val))
*orig_p = new_val->const_val; SET_USE (orig_p, new_val->const_val);
} }
} }
...@@ -948,7 +949,7 @@ ccp_fold (tree stmt) ...@@ -948,7 +949,7 @@ ccp_fold (tree stmt)
/* Restore operands to their original form. */ /* Restore operands to their original form. */
for (i = 0; i < NUM_USES (uses); i++) for (i = 0; i < NUM_USES (uses); i++)
*(USE_OP_PTR (uses, i)) = orig[i]; SET_USE_OP (uses, i, orig[i]);
free (orig); free (orig);
} }
} }
...@@ -1422,14 +1423,15 @@ replace_uses_in (tree stmt, bool *replaced_addresses_p) ...@@ -1422,14 +1423,15 @@ replace_uses_in (tree stmt, bool *replaced_addresses_p)
uses = STMT_USE_OPS (stmt); uses = STMT_USE_OPS (stmt);
for (i = 0; i < NUM_USES (uses); i++) for (i = 0; i < NUM_USES (uses); i++)
{ {
tree *use = USE_OP_PTR (uses, i); use_operand_p use = USE_OP_PTR (uses, i);
value *val = get_value (*use); value *val = get_value (USE_FROM_PTR (use));
if (val->lattice_val == CONSTANT) if (val->lattice_val == CONSTANT)
{ {
*use = val->const_val; SET_USE (use, val->const_val);
replaced = true; 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; *replaced_addresses_p = true;
} }
} }
......
...@@ -54,31 +54,33 @@ Boston, MA 02111-1307, USA. */ ...@@ -54,31 +54,33 @@ Boston, MA 02111-1307, USA. */
replacements of one SSA_NAME with a different SSA_NAME to use the replacements of one SSA_NAME with a different SSA_NAME to use the
APIs defined in this file. */ 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 VAR. This is needed in cases where VAR had never been dereferenced in the
program. program.
If FOR_PROPAGATION is true, then perform additional checks to ensure 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 static void
replace_ssa_names (tree *op_p, replace_ssa_names_ann (tree op,
tree var, tree var,
bool for_propagation ATTRIBUTE_UNUSED) bool for_propagation ATTRIBUTE_UNUSED)
{ {
#if defined ENABLE_CHECKING #if defined ENABLE_CHECKING
if (for_propagation && !may_propagate_copy (*op_p, var)) if (for_propagation && !may_propagate_copy (op, var))
abort (); abort ();
#endif #endif
/* If VAR doesn't have a memory tag, copy the one from the original /* If VAR doesn't have a memory tag, copy the one from the original
operand. Also copy the dereferenced flags. */ 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 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) if (new_ann->type_mem_tag == NULL_TREE)
new_ann->type_mem_tag = orig_ann->type_mem_tag; new_ann->type_mem_tag = orig_ann->type_mem_tag;
...@@ -88,26 +90,25 @@ replace_ssa_names (tree *op_p, ...@@ -88,26 +90,25 @@ replace_ssa_names (tree *op_p,
abort (); abort ();
} }
*op_p = var; }
}
/* Common code for propagate_value and replace_exp. /* Common code for propagate_value and replace_exp.
Replace *OP_P with VAL. FOR_PROPAGATION indicates if the replacement Replace use operand OP_P with VAL. FOR_PROPAGATION indicates if the
is done to propagate a value or not. */ replacement is done to propagate a value or not. */
static void 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 (val) == SSA_NAME)
{ {
if (TREE_CODE (*op_p) == SSA_NAME) if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
replace_ssa_names (op_p, val, for_propagation); replace_ssa_names_ann (USE_FROM_PTR (op_p), val, for_propagation);
else SET_USE (op_p, val);
*op_p = val;
} }
else 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) /* 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) ...@@ -117,11 +118,32 @@ replace_exp_1 (tree *op_p, tree val, bool for_propagation)
checks to ensure validity of the const/copy propagation. */ checks to ensure validity of the const/copy propagation. */
void void
propagate_value (tree *op_p, tree val) propagate_value (use_operand_p op_p, tree val)
{ {
replace_exp_1 (op_p, val, true); 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). /* 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, Use this version when not const/copy propagating values. For example,
...@@ -129,7 +151,7 @@ propagate_value (tree *op_p, tree val) ...@@ -129,7 +151,7 @@ propagate_value (tree *op_p, tree val)
in specific blocks taking into account actions of PHI nodes. */ in specific blocks taking into account actions of PHI nodes. */
void void
replace_exp (tree *op_p, tree val) replace_exp (use_operand_p op_p, tree val)
{ {
replace_exp_1 (op_p, val, false); replace_exp_1 (op_p, val, false);
} }
...@@ -138,15 +160,16 @@ replace_exp (tree *op_p, tree val) ...@@ -138,15 +160,16 @@ replace_exp (tree *op_p, tree val)
CONST_AND_COPIES. */ CONST_AND_COPIES. */
static bool 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; bool may_have_exposed_new_symbols = false;
tree val; tree val;
tree op = USE_FROM_PTR (op_p);
/* If the operand has a known constant value or it is known to be a /* 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 copy of some other variable, use the value or copy stored in
CONST_AND_COPIES. */ 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) if (val)
{ {
tree op_type, val_type; tree op_type, val_type;
...@@ -156,13 +179,13 @@ cprop_operand (stmt_ann_t ann, tree *op_p, varray_type const_and_copies) ...@@ -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 the renamed virtual operand if we later modify this
statement. Also only allow the new value to be an SSA_NAME statement. Also only allow the new value to be an SSA_NAME
for propagation into virtual operands. */ for propagation into virtual operands. */
if (!is_gimple_reg (*op_p) if (!is_gimple_reg (op)
&& (get_virtual_var (val) != get_virtual_var (*op_p) && (get_virtual_var (val) != get_virtual_var (op)
|| TREE_CODE (val) != SSA_NAME)) || TREE_CODE (val) != SSA_NAME))
return false; return false;
/* Get the toplevel type of each operand. */ /* Get the toplevel type of each operand. */
op_type = TREE_TYPE (*op_p); op_type = TREE_TYPE (op);
val_type = TREE_TYPE (val); val_type = TREE_TYPE (val);
/* While both types are pointers, get the type of the object /* 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) ...@@ -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) if (!lang_hooks.types_compatible_p (op_type, val_type)
&& TREE_CODE (val) != SSA_NAME) && 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) if (!is_gimple_min_invariant (val)
&& TREE_CODE (val) != SSA_NAME) && TREE_CODE (val) != SSA_NAME)
return false; return false;
...@@ -190,14 +213,14 @@ cprop_operand (stmt_ann_t ann, tree *op_p, varray_type const_and_copies) ...@@ -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 to their interaction with exception handling and some GCC
extensions. */ extensions. */
if (TREE_CODE (val) == SSA_NAME if (TREE_CODE (val) == SSA_NAME
&& !may_propagate_copy (*op_p, val)) && !may_propagate_copy (op, val))
return false; return false;
/* Dump details. */ /* Dump details. */
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
{ {
fprintf (dump_file, " Replaced '"); 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 '", fprintf (dump_file, "' with %s '",
(TREE_CODE (val) != SSA_NAME ? "constant" : "variable")); (TREE_CODE (val) != SSA_NAME ? "constant" : "variable"));
print_generic_expr (dump_file, val, dump_flags); 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) ...@@ -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 /* If VAL is an ADDR_EXPR or a constant of pointer type, note
that we may have exposed a new symbol for SSA renaming. */ that we may have exposed a new symbol for SSA renaming. */
if (TREE_CODE (val) == ADDR_EXPR if (TREE_CODE (val) == ADDR_EXPR
|| (POINTER_TYPE_P (TREE_TYPE (*op_p)) || (POINTER_TYPE_P (TREE_TYPE (op))
&& is_gimple_min_invariant (val))) && is_gimple_min_invariant (val)))
may_have_exposed_new_symbols = true; may_have_exposed_new_symbols = true;
...@@ -241,8 +264,8 @@ cprop_into_stmt (tree stmt, varray_type const_and_copies) ...@@ -241,8 +264,8 @@ cprop_into_stmt (tree stmt, varray_type const_and_copies)
num_uses = NUM_USES (uses); num_uses = NUM_USES (uses);
for (i = 0; i < num_uses; i++) for (i = 0; i < num_uses; i++)
{ {
tree *op_p = USE_OP_PTR (uses, i); use_operand_p op_p = USE_OP_PTR (uses, i);
if (TREE_CODE (*op_p) == SSA_NAME) if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
may_have_exposed_new_symbols may_have_exposed_new_symbols
|= cprop_operand (ann, op_p, const_and_copies); |= cprop_operand (ann, op_p, const_and_copies);
} }
...@@ -251,8 +274,8 @@ cprop_into_stmt (tree stmt, varray_type const_and_copies) ...@@ -251,8 +274,8 @@ cprop_into_stmt (tree stmt, varray_type const_and_copies)
num_vuses = NUM_VUSES (vuses); num_vuses = NUM_VUSES (vuses);
for (i = 0; i < num_vuses; i++) for (i = 0; i < num_vuses; i++)
{ {
tree *op_p = VUSE_OP_PTR (vuses, i); use_operand_p op_p = VUSE_OP_PTR (vuses, i);
if (TREE_CODE (*op_p) == SSA_NAME) if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
may_have_exposed_new_symbols may_have_exposed_new_symbols
|= cprop_operand (ann, op_p, const_and_copies); |= cprop_operand (ann, op_p, const_and_copies);
} }
...@@ -261,8 +284,8 @@ cprop_into_stmt (tree stmt, varray_type 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); num_v_may_defs = NUM_V_MAY_DEFS (v_may_defs);
for (i = 0; i < num_v_may_defs; i++) for (i = 0; i < num_v_may_defs; i++)
{ {
tree *op_p = V_MAY_DEF_OP_PTR (v_may_defs, i); use_operand_p op_p = V_MAY_DEF_OP_PTR (v_may_defs, i);
if (TREE_CODE (*op_p) == SSA_NAME) if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
may_have_exposed_new_symbols may_have_exposed_new_symbols
|= cprop_operand (ann, op_p, const_and_copies); |= cprop_operand (ann, op_p, const_and_copies);
} }
...@@ -317,7 +340,8 @@ cprop_into_successor_phis (basic_block bb, ...@@ -317,7 +340,8 @@ cprop_into_successor_phis (basic_block bb,
{ {
int i; int i;
tree new; tree new;
tree *orig_p; use_operand_p orig_p;
tree orig;
/* If the hint is valid (!= phi_num_args), see if it points /* If the hint is valid (!= phi_num_args), see if it points
us to the desired phi alternative. */ us to the desired phi alternative. */
...@@ -343,22 +367,23 @@ cprop_into_successor_phis (basic_block bb, ...@@ -343,22 +367,23 @@ cprop_into_successor_phis (basic_block bb,
/* The alternative may be associated with a constant, so verify /* The alternative may be associated with a constant, so verify
it is an SSA_NAME before doing anything with it. */ it is an SSA_NAME before doing anything with it. */
orig_p = &PHI_ARG_DEF (phi, hint); orig_p = PHI_ARG_DEF_PTR (phi, hint);
if (TREE_CODE (*orig_p) != SSA_NAME) orig = USE_FROM_PTR (orig_p);
if (TREE_CODE (orig) != SSA_NAME)
continue; continue;
/* If the alternative is known to have a nonzero value, record /* If the alternative is known to have a nonzero value, record
that fact in the PHI node itself for future use. */ 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; PHI_ARG_NONZERO (phi, hint) = true;
/* If we have *ORIG_P in our constant/copy table, then replace /* If we have *ORIG_P in our constant/copy table, then replace
ORIG_P with its value in our constant/copy table. */ 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 if (new
&& (TREE_CODE (new) == SSA_NAME && (TREE_CODE (new) == SSA_NAME
|| is_gimple_min_invariant (new)) || is_gimple_min_invariant (new))
&& may_propagate_copy (*orig_p, new)) && may_propagate_copy (orig, new))
propagate_value (orig_p, new); propagate_value (orig_p, new);
} }
} }
......
...@@ -700,7 +700,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e) ...@@ -700,7 +700,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
/* Each PHI creates a temporary equivalence, record them. */ /* Each PHI creates a temporary equivalence, record them. */
for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi)) 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); tree dst = PHI_RESULT (phi);
record_const_or_copy (dst, src, &bd->const_and_copies); record_const_or_copy (dst, src, &bd->const_and_copies);
register_new_def (dst, &bd->block_defs); register_new_def (dst, &bd->block_defs);
...@@ -761,7 +761,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e) ...@@ -761,7 +761,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
if (TREE_CODE (USE_OP (uses, i)) == SSA_NAME) if (TREE_CODE (USE_OP (uses, i)) == SSA_NAME)
tmp = get_value_for (USE_OP (uses, i), const_and_copies); tmp = get_value_for (USE_OP (uses, i), const_and_copies);
if (tmp) if (tmp)
*USE_OP_PTR (uses, i) = tmp; SET_USE_OP (uses, i, tmp);
} }
/* Similarly for virtual uses. */ /* Similarly for virtual uses. */
...@@ -773,7 +773,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e) ...@@ -773,7 +773,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
if (TREE_CODE (VUSE_OP (vuses, i)) == SSA_NAME) if (TREE_CODE (VUSE_OP (vuses, i)) == SSA_NAME)
tmp = get_value_for (VUSE_OP (vuses, i), const_and_copies); tmp = get_value_for (VUSE_OP (vuses, i), const_and_copies);
if (tmp) if (tmp)
VUSE_OP (vuses, i) = tmp; SET_VUSE_OP (vuses, i, tmp);
} }
/* Try to lookup the new expression. */ /* Try to lookup the new expression. */
...@@ -781,10 +781,10 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e) ...@@ -781,10 +781,10 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
/* Restore the statement's original uses/defs. */ /* Restore the statement's original uses/defs. */
for (i = 0; i < NUM_USES (uses); i++) 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++) 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 (uses_copy);
free (vuses_copy); free (vuses_copy);
...@@ -2386,7 +2386,7 @@ eliminate_redundant_computations (struct dom_walk_data *walk_data, ...@@ -2386,7 +2386,7 @@ eliminate_redundant_computations (struct dom_walk_data *walk_data,
&& is_gimple_min_invariant (cached_lhs))) && is_gimple_min_invariant (cached_lhs)))
retval = true; retval = true;
propagate_value (expr_p, cached_lhs); propagate_tree_value (expr_p, cached_lhs);
ann->modified = 1; ann->modified = 1;
} }
return retval; return retval;
......
...@@ -132,7 +132,7 @@ fix_phi_uses (tree phi, tree stmt) ...@@ -132,7 +132,7 @@ fix_phi_uses (tree phi, tree stmt)
them with the appropriate V_MAY_DEF_OP. */ them with the appropriate V_MAY_DEF_OP. */
for (j = 0; j < PHI_NUM_ARGS (phi); j++) for (j = 0; j < PHI_NUM_ARGS (phi); j++)
if (v_may_def == PHI_ARG_DEF (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) ...@@ -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)) if (v_may_def1 == V_MAY_DEF_RESULT (v_may_defs2, j))
{ {
/* Update. */ /* Update. */
*V_MAY_DEF_OP_PTR (v_may_defs1, i) = SET_V_MAY_DEF_OP (v_may_defs1, i, V_MAY_DEF_OP (v_may_defs2, j));
V_MAY_DEF_OP (v_may_defs2, j);
break; break;
} }
} }
......
...@@ -294,7 +294,7 @@ create_ssa_var_map (int flags) ...@@ -294,7 +294,7 @@ create_ssa_var_map (int flags)
{ {
block_stmt_iterator bsi; block_stmt_iterator bsi;
basic_block bb; basic_block bb;
tree *dest, *use; tree dest, use;
tree stmt; tree stmt;
stmt_ann_t ann; stmt_ann_t ann;
vuse_optype vuses; vuse_optype vuses;
...@@ -351,22 +351,22 @@ create_ssa_var_map (int flags) ...@@ -351,22 +351,22 @@ create_ssa_var_map (int flags)
uses = USE_OPS (ann); uses = USE_OPS (ann);
for (x = 0; x < NUM_USES (uses); x++) for (x = 0; x < NUM_USES (uses); x++)
{ {
use = USE_OP_PTR (uses, x); use = USE_OP (uses, x);
register_ssa_partition (map, *use, true); register_ssa_partition (map, use, true);
#if defined ENABLE_CHECKING #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 #endif
} }
defs = DEF_OPS (ann); defs = DEF_OPS (ann);
for (x = 0; x < NUM_DEFS (defs); x++) for (x = 0; x < NUM_DEFS (defs); x++)
{ {
dest = DEF_OP_PTR (defs, x); dest = DEF_OP (defs, x);
register_ssa_partition (map, *dest, false); register_ssa_partition (map, dest, false);
#if defined ENABLE_CHECKING #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 #endif
} }
...@@ -1393,22 +1393,22 @@ build_tree_conflict_graph (tree_live_info_p liveinfo, tpa_p tpa, ...@@ -1393,22 +1393,22 @@ build_tree_conflict_graph (tree_live_info_p liveinfo, tpa_p tpa,
if (!is_a_copy) if (!is_a_copy)
{ {
tree *var_p; tree var;
defs = DEF_OPS (ann); defs = DEF_OPS (ann);
num = NUM_DEFS (defs); num = NUM_DEFS (defs);
for (x = 0; x < num; x++) for (x = 0; x < num; x++)
{ {
var_p = DEF_OP_PTR (defs, x); var = DEF_OP (defs, x);
add_conflicts_if_valid (tpa, graph, map, live, *var_p); add_conflicts_if_valid (tpa, graph, map, live, var);
} }
uses = USE_OPS (ann); uses = USE_OPS (ann);
num = NUM_USES (uses); num = NUM_USES (uses);
for (x = 0; x < num; x++) for (x = 0; x < num; x++)
{ {
var_p = USE_OP_PTR (uses, x); var = USE_OP (uses, x);
set_if_valid (map, live, *var_p); set_if_valid (map, live, var);
} }
} }
} }
......
...@@ -225,7 +225,7 @@ duplicate_blocks (varray_type bbs_to_duplicate) ...@@ -225,7 +225,7 @@ duplicate_blocks (varray_type bbs_to_duplicate)
for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi)) 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); add_phi_arg (&phi, def, e1);
} }
} }
......
...@@ -88,65 +88,15 @@ static void add_call_clobber_ops (tree, voperands_t); ...@@ -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_call_read_ops (tree, voperands_t);
static void add_stmt_operand (tree *, tree, int, 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. */ /* 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 static inline def_optype
allocate_def_optype (unsigned num) allocate_def_optype (unsigned num)
{ {
def_optype def_ops; def_optype def_ops;
unsigned size; unsigned size;
size = sizeof (struct def_optype_d) + sizeof (tree *) * (num - 1); size = sizeof (struct def_optype_d) + sizeof (tree *) * (num - 1);
def_ops = check_optype_freelist (num); def_ops = ggc_alloc (size);
if (!def_ops)
def_ops = ggc_alloc (size);
def_ops->num_defs = num; def_ops->num_defs = num;
return def_ops; return def_ops;
} }
...@@ -157,9 +107,7 @@ allocate_use_optype (unsigned num) ...@@ -157,9 +107,7 @@ allocate_use_optype (unsigned num)
use_optype use_ops; use_optype use_ops;
unsigned size; unsigned size;
size = sizeof (struct use_optype_d) + sizeof (tree *) * (num - 1); size = sizeof (struct use_optype_d) + sizeof (tree *) * (num - 1);
use_ops = check_optype_freelist (num); use_ops = ggc_alloc (size);
if (!use_ops)
use_ops = ggc_alloc (size);
use_ops->num_uses = num; use_ops->num_uses = num;
return use_ops; return use_ops;
} }
...@@ -170,9 +118,7 @@ allocate_v_may_def_optype (unsigned num) ...@@ -170,9 +118,7 @@ allocate_v_may_def_optype (unsigned num)
v_may_def_optype v_may_def_ops; v_may_def_optype v_may_def_ops;
unsigned size; unsigned size;
size = sizeof (struct v_may_def_optype_d) + sizeof (tree) * ((num * 2) - 1); size = sizeof (struct v_may_def_optype_d) + sizeof (tree) * ((num * 2) - 1);
v_may_def_ops = check_optype_freelist (num * 2); v_may_def_ops = ggc_alloc (size);
if (!v_may_def_ops)
v_may_def_ops = ggc_alloc (size);
v_may_def_ops->num_v_may_defs = num; v_may_def_ops->num_v_may_defs = num;
return v_may_def_ops; return v_may_def_ops;
} }
...@@ -183,9 +129,7 @@ allocate_vuse_optype (unsigned num) ...@@ -183,9 +129,7 @@ allocate_vuse_optype (unsigned num)
vuse_optype vuse_ops; vuse_optype vuse_ops;
unsigned size; unsigned size;
size = sizeof (struct vuse_optype_d) + sizeof (tree) * (num - 1); size = sizeof (struct vuse_optype_d) + sizeof (tree) * (num - 1);
vuse_ops = check_optype_freelist (num); vuse_ops = ggc_alloc (size);
if (!vuse_ops)
vuse_ops = ggc_alloc (size);
vuse_ops->num_vuses = num; vuse_ops->num_vuses = num;
return vuse_ops; return vuse_ops;
} }
...@@ -196,9 +140,7 @@ allocate_v_must_def_optype (unsigned num) ...@@ -196,9 +140,7 @@ allocate_v_must_def_optype (unsigned num)
v_must_def_optype v_must_def_ops; v_must_def_optype v_must_def_ops;
unsigned size; unsigned size;
size = sizeof (struct v_must_def_optype_d) + sizeof (tree *) * (num - 1); size = sizeof (struct v_must_def_optype_d) + sizeof (tree *) * (num - 1);
v_must_def_ops = check_optype_freelist (num); v_must_def_ops = ggc_alloc (size);
if (!v_must_def_ops)
v_must_def_ops = ggc_alloc (size);
v_must_def_ops->num_v_must_defs = num; v_must_def_ops->num_v_must_defs = num;
return v_must_def_ops; return v_must_def_ops;
} }
...@@ -209,7 +151,7 @@ free_uses (use_optype *uses, bool dealloc) ...@@ -209,7 +151,7 @@ free_uses (use_optype *uses, bool dealloc)
if (*uses) if (*uses)
{ {
if (dealloc) if (dealloc)
add_optype_freelist (*uses, (*uses)->num_uses); ggc_free (*uses);
*uses = NULL; *uses = NULL;
} }
} }
...@@ -220,7 +162,7 @@ free_defs (def_optype *defs, bool dealloc) ...@@ -220,7 +162,7 @@ free_defs (def_optype *defs, bool dealloc)
if (*defs) if (*defs)
{ {
if (dealloc) if (dealloc)
add_optype_freelist (*defs, (*defs)->num_defs); ggc_free (*defs);
*defs = NULL; *defs = NULL;
} }
} }
...@@ -231,7 +173,7 @@ free_vuses (vuse_optype *vuses, bool dealloc) ...@@ -231,7 +173,7 @@ free_vuses (vuse_optype *vuses, bool dealloc)
if (*vuses) if (*vuses)
{ {
if (dealloc) if (dealloc)
add_optype_freelist (*vuses, (*vuses)->num_vuses); ggc_free (*vuses);
*vuses = NULL; *vuses = NULL;
} }
} }
...@@ -242,7 +184,7 @@ free_v_may_defs (v_may_def_optype *v_may_defs, bool dealloc) ...@@ -242,7 +184,7 @@ free_v_may_defs (v_may_def_optype *v_may_defs, bool dealloc)
if (*v_may_defs) if (*v_may_defs)
{ {
if (dealloc) if (dealloc)
add_optype_freelist (*v_may_defs, (*v_may_defs)->num_v_may_defs); ggc_free (*v_may_defs);
*v_may_defs = NULL; *v_may_defs = NULL;
} }
} }
...@@ -253,7 +195,7 @@ free_v_must_defs (v_must_def_optype *v_must_defs, bool dealloc) ...@@ -253,7 +195,7 @@ free_v_must_defs (v_must_def_optype *v_must_defs, bool dealloc)
if (*v_must_defs) if (*v_must_defs)
{ {
if (dealloc) if (dealloc)
add_optype_freelist (*v_must_defs, (*v_must_defs)->num_v_must_defs); ggc_free (*v_must_defs);
*v_must_defs = NULL; *v_must_defs = NULL;
} }
} }
...@@ -291,24 +233,16 @@ remove_v_must_defs (tree stmt) ...@@ -291,24 +233,16 @@ remove_v_must_defs (tree stmt)
void void
init_ssa_operands (void) init_ssa_operands (void)
{ {
int x;
VARRAY_TREE_PTR_INIT (build_defs, 5, "build defs"); VARRAY_TREE_PTR_INIT (build_defs, 5, "build defs");
VARRAY_TREE_PTR_INIT (build_uses, 10, "build uses"); 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_v_may_defs, 10, "build v_may_defs");
VARRAY_TREE_INIT (build_vuses, 10, "build vuses"); VARRAY_TREE_INIT (build_vuses, 10, "build vuses");
VARRAY_TREE_INIT (build_v_must_defs, 10, "build v_must_defs"); 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 void
fini_ssa_operands (void) fini_ssa_operands (void)
{ {
int x;
for (x = 0; x < NUM_FREE; x++)
optype_freelist[x].next = NULL;
} }
static void static void
...@@ -330,7 +264,7 @@ finalize_ssa_defs (tree stmt) ...@@ -330,7 +264,7 @@ finalize_ssa_defs (tree stmt)
def_ops = allocate_def_optype (num); def_ops = allocate_def_optype (num);
for (x = 0; x < num ; x++) 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); VARRAY_POP_ALL (build_defs);
ann = stmt_ann (stmt); ann = stmt_ann (stmt);
...@@ -363,7 +297,7 @@ finalize_ssa_uses (tree stmt) ...@@ -363,7 +297,7 @@ finalize_ssa_uses (tree stmt)
use_ops = allocate_use_optype (num); use_ops = allocate_use_optype (num);
for (x = 0; x < num ; x++) 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); VARRAY_POP_ALL (build_uses);
ann = stmt_ann (stmt); ann = stmt_ann (stmt);
......
...@@ -23,22 +23,39 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -23,22 +23,39 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Interface to SSA operands. */ /* 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(()) typedef struct def_optype_d GTY(())
{ {
unsigned num_defs; 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; } def_optype_t;
typedef def_optype_t *def_optype; typedef def_optype_t *def_optype;
/* This represents the USE operands of a stmt. */
typedef struct use_optype_d GTY(()) typedef struct use_optype_d GTY(())
{ {
unsigned num_uses; 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; } use_optype_t;
typedef use_optype_t *use_optype; typedef use_optype_t *use_optype;
/* This represents the MAY_DEFS for a stmt. */
typedef struct v_may_def_optype_d GTY(()) typedef struct v_may_def_optype_d GTY(())
{ {
unsigned num_v_may_defs; unsigned num_v_may_defs;
...@@ -47,6 +64,7 @@ typedef struct v_may_def_optype_d GTY(()) ...@@ -47,6 +64,7 @@ typedef struct v_may_def_optype_d GTY(())
typedef v_may_def_optype_t *v_may_def_optype; typedef v_may_def_optype_t *v_may_def_optype;
/* This represents the VUSEs for a stmt. */
typedef struct vuse_optype_d GTY(()) typedef struct vuse_optype_d GTY(())
{ {
unsigned num_vuses; unsigned num_vuses;
...@@ -55,6 +73,7 @@ typedef struct vuse_optype_d GTY(()) ...@@ -55,6 +73,7 @@ typedef struct vuse_optype_d GTY(())
typedef vuse_optype_t *vuse_optype; typedef vuse_optype_t *vuse_optype;
/* This represents the V_MUST_DEFS for a stmt. */
typedef struct v_must_def_optype_d GTY(()) typedef struct v_must_def_optype_d GTY(())
{ {
unsigned num_v_must_defs; unsigned num_v_must_defs;
...@@ -63,41 +82,78 @@ typedef struct v_must_def_optype_d GTY(()) ...@@ -63,41 +82,78 @@ typedef struct v_must_def_optype_d GTY(())
typedef v_must_def_optype_t *v_must_def_optype; 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 USE_OPS(ANN) get_use_ops (ANN)
#define STMT_USE_OPS(STMT) get_use_ops (stmt_ann (STMT)) #define STMT_USE_OPS(STMT) get_use_ops (stmt_ann (STMT))
#define NUM_USES(OPS) ((OPS) ? (OPS)->num_uses : 0) #define NUM_USES(OPS) ((OPS) ? (OPS)->num_uses : 0)
#define USE_OP_PTR(OPS, I) get_use_op_ptr ((OPS), (I)) #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 DEF_OPS(ANN) get_def_ops (ANN)
#define STMT_DEF_OPS(STMT) get_def_ops (stmt_ann (STMT)) #define STMT_DEF_OPS(STMT) get_def_ops (stmt_ann (STMT))
#define NUM_DEFS(OPS) ((OPS) ? (OPS)->num_defs : 0) #define NUM_DEFS(OPS) ((OPS) ? (OPS)->num_defs : 0)
#define DEF_OP_PTR(OPS, I) get_def_op_ptr ((OPS), (I)) #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 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 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 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_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_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 VUSE_OPS(ANN) get_vuse_ops (ANN)
#define STMT_VUSE_OPS(STMT) get_vuse_ops (stmt_ann(STMT)) #define STMT_VUSE_OPS(STMT) get_vuse_ops (stmt_ann(STMT))
#define NUM_VUSES(OPS) ((OPS) ? (OPS)->num_vuses : 0) #define NUM_VUSES(OPS) ((OPS) ? (OPS)->num_vuses : 0)
#define VUSE_OP_PTR(OPS, I) get_vuse_op_ptr ((OPS), (I)) #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 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 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 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_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 init_ssa_operands (void);
extern void fini_ssa_operands (void); extern void fini_ssa_operands (void);
......
...@@ -1907,7 +1907,7 @@ eliminate (void) ...@@ -1907,7 +1907,7 @@ eliminate (void)
print_generic_stmt (dump_file, stmt, 0); print_generic_stmt (dump_file, stmt, 0);
} }
pre_stats.eliminations++; pre_stats.eliminations++;
propagate_value (&TREE_OPERAND (stmt, 1), sprime); propagate_tree_value (&TREE_OPERAND (stmt, 1), sprime);
modify_stmt (stmt); modify_stmt (stmt);
} }
} }
......
...@@ -779,7 +779,7 @@ replace_immediate_uses (tree var, tree repl) ...@@ -779,7 +779,7 @@ replace_immediate_uses (tree var, tree repl)
for (j = 0; j < PHI_NUM_ARGS (stmt); j++) for (j = 0; j < PHI_NUM_ARGS (stmt); j++)
if (PHI_ARG_DEF (stmt, j) == var) 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 if (TREE_CODE (repl) == SSA_NAME
&& PHI_ARG_EDGE (stmt, j)->flags & EDGE_ABNORMAL) && PHI_ARG_EDGE (stmt, j)->flags & EDGE_ABNORMAL)
SSA_NAME_OCCURS_IN_ABNORMAL_PHI (repl) = 1; SSA_NAME_OCCURS_IN_ABNORMAL_PHI (repl) = 1;
......
...@@ -237,7 +237,7 @@ independent_of_stmt_p (tree expr, tree at, block_stmt_iterator bsi) ...@@ -237,7 +237,7 @@ independent_of_stmt_p (tree expr, tree at, block_stmt_iterator bsi)
if (!e) if (!e)
abort (); abort ();
expr = phi_element_for_edge (at, e)->def; expr = PHI_ARG_DEF_FROM_EDGE (at, e);
} }
/* Unmark the blocks. */ /* Unmark the blocks. */
...@@ -340,7 +340,7 @@ propagate_through_phis (tree var, edge e) ...@@ -340,7 +340,7 @@ propagate_through_phis (tree var, edge e)
tree phi; tree phi;
for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (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 PHI_RESULT (phi);
return var; return var;
......
...@@ -1206,7 +1206,8 @@ struct tree_ssa_name GTY(()) ...@@ -1206,7 +1206,8 @@ struct tree_ssa_name GTY(())
}; };
/* In a PHI_NODE node. */ /* 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 /* 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 list. The head of the list is linked from the block annotation, and
...@@ -1215,13 +1216,12 @@ struct tree_ssa_name GTY(()) ...@@ -1215,13 +1216,12 @@ struct tree_ssa_name GTY(())
/* Nonzero if the PHI node was rewritten by a previous pass through the /* Nonzero if the PHI node was rewritten by a previous pass through the
SSA renamer. */ SSA renamer. */
#define PHI_REWRITTEN(NODE) PHI_NODE_CHECK (NODE)->phi.rewritten #define PHI_REWRITTEN(NODE) PHI_NODE_CHECK (NODE)->phi.rewritten
#define PHI_NUM_ARGS(NODE) PHI_NODE_CHECK (NODE)->phi.num_args #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_CAPACITY(NODE) PHI_NODE_CHECK (NODE)->phi.capacity
#define PHI_ARG_ELT(NODE, I) PHI_NODE_ELT_CHECK (NODE, I) #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_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_ARG_NONZERO(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).nonzero
struct edge_def; struct edge_def;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment