This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Reducing SSA_NAME churning
- From: law at redhat dot com
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 19 May 2004 14:43:45 -0600
- Subject: Reducing SSA_NAME churning
- Reply-to: law at redhat dot com
One of the more annoying aspects of tree-ssa dumps is that the SSA version
numbers on variables can be scrambled badly after jump threading -- which
can make diffing dumps difficult.
This patch significantly reduces the useless churning of SSA version
numbers. Basically if we're re-rewriting a particular variable, we
re-use the existing version number for any of its real or virtual
assignments.
By re-using the existing number, any uses which are still dominated by
that particular assignment will continue to use the same number. Thus
changes in version #s are due to changes in which assignment reaches
a particular use.
This also has a nice effect of drastically reducing the load on the
SSA_NAME manager -- without this patch we free a ton of SSA_NAMEs en-masse
only to reallocate them shortly later. That's rather pointless and just
wastes time/memory.
Additionally, this patch _may_ make it possible to maintain some points-to
information after jump threading and re-rewriting. I haven't investigated
that.
Bootstrapped and regression tested on i686-pc-linux-gnu.
* tree-into-ssa.c (prepare_operand_for_rename): New argument is_use.
If the operand is for a use, then strip away the SSA_NAME, do not
strip away the SSA_NAME for a set. Never call release_ssa_name.
(mark_def_sites): Appropriately pass additional argument to
prepare_operand_for_rename. If a VDEF_RESULT is not an SSA_NAME,
then set the VDEF_RESULT to the VDEF_OP.
(set_def_block): Strip away any SSA_NAME to get to the real
underlying variable.
Index: tree-into-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-into-ssa.c,v
retrieving revision 2.6
diff -c -p -r2.6 tree-into-ssa.c
*** tree-into-ssa.c 15 May 2004 23:07:52 -0000 2.6
--- tree-into-ssa.c 19 May 2004 18:57:23 -0000
*************** static void mark_def_sites_initialize_bl
*** 109,115 ****
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);
static void insert_phi_nodes (bitmap *);
static void rewrite_stmt (struct dom_walk_data *, basic_block,
block_stmt_iterator);
--- 109,115 ----
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 void insert_phi_nodes (bitmap *);
static void rewrite_stmt (struct dom_walk_data *, basic_block,
block_stmt_iterator);
*************** mark_def_sites (struct dom_walk_data *wa
*** 232,238 ****
{
tree *use_p = USE_OP_PTR (uses, i);
! if (prepare_operand_for_rename (use_p, &uid)
&& !TEST_BIT (kills, uid))
set_livein_block (*use_p, bb);
}
--- 232,238 ----
{
tree *use_p = USE_OP_PTR (uses, i);
! if (prepare_operand_for_rename (use_p, &uid, true)
&& !TEST_BIT (kills, uid))
set_livein_block (*use_p, bb);
}
*************** mark_def_sites (struct dom_walk_data *wa
*** 243,249 ****
{
tree *use_p = VUSE_OP_PTR (vuses, i);
! if (prepare_operand_for_rename (use_p, &uid))
set_livein_block (*use_p, bb);
}
--- 243,249 ----
{
tree *use_p = VUSE_OP_PTR (vuses, i);
! if (prepare_operand_for_rename (use_p, &uid, true))
set_livein_block (*use_p, bb);
}
*************** mark_def_sites (struct dom_walk_data *wa
*** 255,266 ****
vdefs = VDEF_OPS (ann);
for (i = 0; i < NUM_VDEFS (vdefs); i++)
{
! size_t dummy;
!
! if (prepare_operand_for_rename (VDEF_OP_PTR (vdefs, i), &uid)
! && prepare_operand_for_rename (VDEF_RESULT_PTR (vdefs, i), &dummy))
{
! VDEF_RESULT (vdefs, i) = VDEF_OP (vdefs, i);
set_livein_block (VDEF_OP (vdefs, i), bb);
set_def_block (VDEF_RESULT (vdefs, i), bb);
--- 255,266 ----
vdefs = VDEF_OPS (ann);
for (i = 0; i < NUM_VDEFS (vdefs); i++)
{
! if (prepare_operand_for_rename (VDEF_OP_PTR (vdefs, i), &uid, true))
{
! /* If we do not already have an SSA_NAME for our destination,
! then set the destination to the source. */
! if (TREE_CODE (VDEF_RESULT (vdefs, i)) != SSA_NAME)
! VDEF_RESULT (vdefs, i) = VDEF_OP (vdefs, i);
set_livein_block (VDEF_OP (vdefs, i), bb);
set_def_block (VDEF_RESULT (vdefs, i), bb);
*************** mark_def_sites (struct dom_walk_data *wa
*** 274,280 ****
{
tree *def_p = DEF_OP_PTR (defs, i);
! if (prepare_operand_for_rename (def_p, &uid))
{
set_def_block (*def_p, bb);
SET_BIT (kills, uid);
--- 274,280 ----
{
tree *def_p = DEF_OP_PTR (defs, i);
! if (prepare_operand_for_rename (def_p, &uid, false))
{
set_def_block (*def_p, bb);
SET_BIT (kills, uid);
*************** static void
*** 289,296 ****
set_def_block (tree var, basic_block bb)
{
struct def_blocks_d *db_p;
! enum need_phi_state state = var_ann (var)->need_phi_state;
db_p = get_def_blocks_for (var);
/* Set the bit corresponding to the block where VAR is defined. */
--- 289,300 ----
set_def_block (tree var, basic_block bb)
{
struct def_blocks_d *db_p;
! enum need_phi_state state;
!
! if (TREE_CODE (var) == SSA_NAME)
! var = SSA_NAME_VAR (var);
+ state = var_ann (var)->need_phi_state;
db_p = get_def_blocks_for (var);
/* Set the bit corresponding to the block where VAR is defined. */
*************** set_livein_block (tree var, basic_block
*** 348,359 ****
}
! /* If the operand pointed by OP_P needs to be renamed, strip away SSA_NAME
! wrappers (if needed) and return true. The unique ID for the operand's
! variable will be stored in *UID_P. */
static bool
! prepare_operand_for_rename (tree *op_p, size_t *uid_p)
{
tree var = (TREE_CODE (*op_p) != SSA_NAME) ? *op_p : SSA_NAME_VAR (*op_p);
*uid_p = var_ann (var)->uid;
--- 352,370 ----
}
! /* 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. */
static bool
! prepare_operand_for_rename (tree *op_p, size_t *uid_p, bool is_use)
{
tree var = (TREE_CODE (*op_p) != SSA_NAME) ? *op_p : SSA_NAME_VAR (*op_p);
*uid_p = var_ann (var)->uid;
*************** prepare_operand_for_rename (tree *op_p,
*** 362,376 ****
if (vars_to_rename && !bitmap_bit_p (vars_to_rename, *uid_p))
return false;
! /* The variable needs to be renamed. If it already had an
! SSA_NAME, strip it off. This way, the SSA rename pass
! doesn't need to deal with existing SSA names. */
! if (TREE_CODE (*op_p) == SSA_NAME)
! {
! if (default_def (SSA_NAME_VAR (*op_p)) != *op_p)
! release_ssa_name (*op_p);
! *op_p = var;
! }
return true;
}
--- 373,386 ----
if (vars_to_rename && !bitmap_bit_p (vars_to_rename, *uid_p))
return false;
! /* The variable needs to be renamed. If this is a use which already
! has an SSA_NAME, then strip it off.
!
! 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;
return true;
}