This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Reducing SSA_NAME churning


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











Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]