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]

[RFC] Kill unused vars from dumps (and for real)


Hi!

This simple hack makes us remove unused VAR_DECLs from the
unexpanded_var_list.  At the moment after update_ssa, but
in the end as separate TODO_.  There may be ways to better
implement this (and maybe using var_ann->used as temporary
flag is not a good idea).

It passes the tramp3d check (aka, it builds and the output does
not differ), while reducing overall -fdump-tree-all required
space from 5.9G to 3.3G, f.i. a typical dump file, like .t70.cunroll
is before:

-rw-r--r--  1 rguenther suse 83294492 2005-08-03 12:10 
unpatched/tramp3d-v4.cpp.t70.cunroll

and after:

-rw-r--r--  1 rguenther suse 28202609 2005-08-03 12:31 
patched/tramp3d-v4.cpp.t70.cunroll

and it's definitely more easy to follow the variable declarations
without all the garbage in (like it is reading the .vars dump).
Before, for a randomly picked function, we have 517 VAR_DECLs in
the tree dump, while after, we need to browse only through 75 of
them (i.e. only 15% of the VAR_DECLs are useful).

Any hints for improving the actual implementation?

Oh, and I didn't measure any positive impact on compile-speed
or memory usage, though all testing was with checking enabled,
sofar.

Thanks,
Richard.


Index: gimple-low.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimple-low.c,v
retrieving revision 2.26
diff -u -c -3 -p -r2.26 gimple-low.c
*** gimple-low.c	30 Jun 2005 00:47:49 -0000	2.26
--- gimple-low.c	3 Aug 2005 09:33:06 -0000
*************** Software Foundation, 51 Franklin Street,
*** 40,45 ****
--- 40,46 ----
  #include "expr.h"
  #include "toplev.h"
  #include "tree-pass.h"
+ #include "pointer-set.h"
  
  struct lower_data
  {
*************** expand_var_p (tree var)
*** 552,557 ****
--- 553,644 ----
    return true;
  }
  
+ static tree
+ mark_used_vars (tree *tp, int *walk_subtrees, void *data)
+ {
+   tree var;
+ 
+   if (TREE_CODE (*tp) == VAR_DECL)
+     var = *tp;
+   else if (TREE_CODE (*tp) == SSA_NAME)
+     var = SSA_NAME_VAR (*tp);
+   else
+     return NULL_TREE;
+ 
+   if (TREE_CODE (var) == VAR_DECL
+       && DECL_CONTEXT (var) == cfun->decl)
+     {
+       struct var_ann_d *ann = var_ann (var);
+       ann->used = true;
+     }
+ 
+   return NULL_TREE;
+ }
+ 
+ void
+ remove_useless_vars_ssa (void);
+ void
+ remove_useless_vars_ssa (void)
+ {
+   basic_block bb;
+   tree *cell;
+   struct pointer_set_t *visited_nodes;
+ 
+   visited_nodes = pointer_set_create ();
+   FOR_EACH_BB (bb)
+     {
+       block_stmt_iterator bsi;
+       tree phi, def;
+ 
+       /* Walk the statements.  */
+       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ 	walk_tree (bsi_stmt_ptr (bsi), mark_used_vars,
+ 		   NULL, visited_nodes);
+ 
+       /* It should be enough to walk the phi results.  */
+       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+         {
+ #if 1
+           use_operand_p arg_p;
+           ssa_op_iter i;
+ 
+           def = PHI_RESULT (phi);
+           mark_used_vars (&def, NULL, NULL);
+ #endif
+ 
+ #if 1
+           FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES)
+             {
+               tree arg = USE_FROM_PTR (arg_p);
+ 	      mark_used_vars (&arg, NULL, NULL);
+             }
+ #endif
+         }
+     }
+   pointer_set_destroy (visited_nodes);
+ 
+   /* Remove unmarked vars and clear used flag.  */
+   for (cell = &cfun->unexpanded_var_list; *cell; )
+     {
+       tree var = TREE_VALUE (*cell);
+       struct var_ann_d *ann = var_ann (var);
+ #if 0
+       if (TREE_CODE (var) == VAR_DECL
+ 	  && DECL_CONTEXT (var) == cfun->decl
+ 	  && ann && !ann->used)
+ #endif
+       if (TREE_CODE (var) == VAR_DECL
+ 	  && (!ann || !ann->used))
+ 	{
+ 	  *cell = TREE_CHAIN (*cell);
+           continue;
+ 	}
+       if (ann)
+ 	ann->used = false;
+       cell = &TREE_CHAIN (*cell);
+     }
+ }
+ 
  /* Throw away variables that are unused.  */
  
  static void
Index: passes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/passes.c,v
retrieving revision 2.105
diff -u -c -3 -p -r2.105 passes.c
*** passes.c	19 Jul 2005 18:45:56 -0000	2.105
--- passes.c	3 Aug 2005 09:33:06 -0000
*************** init_optimization_passes (void)
*** 667,673 ****
  }
  
  static unsigned int last_verified;
! 
  static void
  execute_todo (struct tree_opt_pass *pass, unsigned int flags, bool use_required)
  {
--- 667,673 ----
  }
  
  static unsigned int last_verified;
! extern void remove_useless_vars_ssa (void);
  static void
  execute_todo (struct tree_opt_pass *pass, unsigned int flags, bool use_required)
  {
*************** execute_todo (struct tree_opt_pass *pass
*** 692,697 ****
--- 692,699 ----
      {
        unsigned update_flags = flags & TODO_update_ssa_any;
        update_ssa (update_flags);
+       if (in_ssa_p)
+ 	remove_useless_vars_ssa ();
      }
  
    if ((flags & TODO_dump_func)


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