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]

Re: [tree-ssa] Re-compute TREE_ADDRESSABLE early


> > On Tue, 2003-12-16 at 19:11, Jan Hubicka wrote:
> > > > On Tue, 2003-12-16 at 18:50, Jan Hubicka wrote:
> > > > 
> > > > > I wrote this code orignally as an attempt to avoid need to compute
> > > > > TREE_ADDRESSABLE in the frontend.  This is not possible right now as
> > > > > gimplification and several other bits depends on different definitions
> > > > > of TREE_ADDRESABLE value.
> > > > > 
> > > > If you compute addressability in tree_rest_of_compilation() prior to
> > > > gimplification, you wouldn't need this.
> > > > 
> > > > I'm not sure this is needed.
> > > 
> > > The idea is that inlining and early dead/unreachable code removal
> > > elliminate some address operations and this is very cheap.  But I will
> > > update and test the generic part too later this week.
> > > 
> > I think I'm missing something here.  What I propose is to walk the
> > function tree right after we've inlined all the calls and before we're
> > about to gimplify the function:
> > 
> > tree_rest_of_compilation ()
> > {
> >   [ ... ]
> >   if (flag_inline_trees)
> >     {
> >       timevar_push (TV_INTEGRATION);
> >       optimize_inline_calls (fndecl);
> >       timevar_pop (TV_INTEGRATION);
> >     }
> >   
> >   <-- Walk function body to set/clear TREE_ADDRESSABLE on all DECLs -->
> 
> I see now what you are shooting for.  OK, for C++ we are already in
> GIMPLE, while for fortran we are in GENERIC, so writing ADDR_EXPR lookup
> code for this spot is trivial.  I will get into it tonight (I already
> have function somewhere doing this, so all I need is to dig it out)
> >                                                                        
> >   /* If the function has not already been gimplified, do so now.  */
> >   if (!lang_hooks.gimple_before_inlining)
> >     gimplify_function_tree (fndecl);
> >   [...]
> > }
> > 
> > Won't this guarantee that the gimplifier will only see TREE_ADDRESSABLE
> > on the variables that are *really* addressable?
> 
> The problematic bit is that C and C++ frontend see gimplifier run much
> earlier (before tree_rest_of_compilation is executed) and I would love
> to see gimplification to happen before inlining on *all* frontends in
> longer run at least on higher optimization levels.  I don't see
> practical way to do things like tail recursion discovery, function body
> estimate or profile estimate done on GENERIC trees and all these are
> needed to make sanier inlining decisions than we are dong now.
> 
> But in general I would agree that having GENERIC version of
> TREE_ADDRESSABLE bit recognizer makes sense.  I will write it and then
> we can see how to solve the ordering problem.  It is easy enought so we
> can afford some experiments.

I am attaching the implementation of GENERIC implementation of
ADDRESSABLE bit computing code.  It passed enable/disable checking on
i686-pc-gnu-linux, but the aliasing fixes in recent two days
dramatically changes effectivity of this bit.  While I sitll do get some
memory savings and no slowdowns (at least not something that can not be
attributed to the noise), I no longer get such a large benefits
on number of instructions in Gerald's testcase I reported first time.
Now the compiler gets it even without early computing.  The original
version of this patch save 1 instruction now, while the current version
saves 0.  I ges 86 instructions savings from both patches on GCC modules
test.  In a way this is positive result.  The effectivity of patch
strikes me wrong as I saw no reason why dom2 should not catch the cases
too, so tree-mustalias seems to be doing it's job now.

So you may consider whether it worths the extra few lines at all.
Perhaps it still makes sense in the wider plan of dropping addresability
code for local functions from the frontends (generic capable frontends
no longer needs this to be done, when ENABLE_CHECKING verifying
consistency is dropped from the patch)

I have similar code to discover TREE_ADDRSSABLE bits on static and
global variables during cgraph analysis pass but and plan to push that
patch out soonish.

Finally I have patch that adds TREE_CONSTANT flag to parameters whose
address is not taken and whose are not set by program that needs this
analysis too.  This is usefull for intraprocedural constant propagation
prototype I do have and for better inlining decisions for callback
functions.   THis code however requires functions to be gimplified
instead of genericized early as it is dificult to manage clobbering
statements in generic form.

Honza

2003-12-19  Jan Hubicka  <jh@suse.cz>
	* tree-flow.h (generic_compute_addressable_flags): Declare.
	* tree-must-alias.c (generic_compute_addressable_flags_r): New static
	function.
	(generic_compute_addressable_flags): New global function.
	(tree_rest_of_compilation): Recompute addressable flags before
	gimplification.
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.172
diff -c -3 -p -r1.1.4.172 tree-flow.h
*** tree-flow.h	16 Dec 2003 21:42:31 -0000	1.1.4.172
--- tree-flow.h	18 Dec 2003 23:02:29 -0000
*************** static inline bool may_propagate_copy (t
*** 529,534 ****
--- 529,535 ----
  
  /* In tree-must-alias.c  */
  void tree_compute_must_alias (tree, bitmap, enum tree_dump_index);
+ void generic_compute_addressable_flags (tree);
  
  /* In tree-eh.c  */
  extern void lower_eh_constructs (tree *);
Index: tree-must-alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-must-alias.c,v
retrieving revision 1.1.2.16
diff -c -3 -p -r1.1.2.16 tree-must-alias.c
*** tree-must-alias.c	17 Dec 2003 03:36:14 -0000	1.1.2.16
--- tree-must-alias.c	18 Dec 2003 23:02:29 -0000
*************** remove_element_from (varray_type array, 
*** 302,304 ****
--- 302,391 ----
      VARRAY_TREE (array, i) = VARRAY_TREE (array, len - 1);
    VARRAY_POP (array);
  }
+ 
+ /* Helper function of generic_compute_addressable_flags.
+    Look for ADDR_EXPR nodes and mark their arguments as addressable.
+    The addressable bit is cleared first time variable is seen inside BIND_EXPR.
+    */
+ 
+ static tree
+ generic_compute_addressable_flags_r (tree * tp,
+ 				     int *walk_subtrees,
+ 				     void *data ATTRIBUTE_UNUSED)
+ {
+   tree t = *tp;
+ 
+   if (TYPE_P (t) || DECL_P (t))
+     {
+       *walk_subtrees = 0;
+       return NULL_TREE;
+     }
+   switch (TREE_CODE (t))
+     {
+     case ADDR_EXPR:
+       {
+ 	tree var = get_base_symbol (TREE_OPERAND (t, 0));
+ 
+ 	if (var
+ 	    && (TREE_CODE (var) == VAR_DECL || TREE_CODE (var) == PARM_DECL))
+ 	  {
+ #ifdef ENABLE_CHECKING
+ 	    /* Expect conservative settings on the input.  */
+ 	    if (needs_to_live_in_memory (var) && !TREE_ADDRESSABLE (var))
+ 	      abort ();
+ #endif
+ 	    TREE_ADDRESSABLE (var) = 1;
+ 	  }
+       }
+       break;
+     case ASM_EXPR:
+       {
+ 	int noutputs = list_length (ASM_OUTPUTS (t));
+ 	const char **oconstraints
+ 	  = (const char **) alloca ((noutputs) * sizeof (const char *));
+ 	int i;
+ 	tree link;
+ 	tree op;
+ 	const char *constraint;
+ 	bool allows_mem, allows_reg, is_inout;
+ 
+ 	for (i = 0, link = ASM_OUTPUTS (t); link;
+ 	     ++i, link = TREE_CHAIN (link))
+ 	  {
+ 	    oconstraints[i] = constraint
+ 	      = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+ 	    parse_output_constraint (&constraint, i, 0, 0,
+ 				     &allows_mem, &allows_reg, &is_inout);
+ 	    if (allows_reg && is_inout)
+ 	      /* This should have been split in gimplify_asm_expr.  */
+ 	      abort ();
+ 	    if (!allows_reg && allows_mem
+ 		&& (op = get_base_symbol (TREE_VALUE (link)))
+ 		&& (TREE_CODE (op) == VAR_DECL
+ 		    || TREE_CODE (op) == PARM_DECL))
+ 	      TREE_ADDRESSABLE (op) = 1;
+ 	  }
+       }
+       break;
+     case BIND_EXPR:
+       {
+ 	tree var;
+ 
+ 	for (var = BIND_EXPR_VARS (t); var; var = TREE_CHAIN (var))
+ 	  if (TREE_ADDRESSABLE (var) && !needs_to_live_in_memory (var))
+ 	    TREE_ADDRESSABLE (var) = 0;
+       }
+       break;
+     default:
+       break;
+     }
+   return NULL_TREE;
+ }
+ 
+ /* Simple early pass computing addressable flags on GENERIC trees.  */
+ void
+ generic_compute_addressable_flags (tree fndecl)
+ {
+   walk_tree (&DECL_SAVED_TREE (fndecl), generic_compute_addressable_flags_r,
+ 	     NULL, NULL);
+ }
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v
retrieving revision 1.1.4.95
diff -c -3 -p -r1.1.4.95 tree-optimize.c
*** tree-optimize.c	15 Dec 2003 15:55:34 -0000	1.1.4.95
--- tree-optimize.c	18 Dec 2003 23:02:29 -0000
*************** tree_rest_of_compilation (tree fndecl, b
*** 364,369 ****
--- 364,373 ----
        timevar_pop (TV_INTEGRATION);
      }
  
+   /* Re-compute TREE_ADDRESSABLE flags more aggressivly to improve alias
+      analysis.  */
+   generic_compute_addressable_flags (fndecl);
+ 
    /* If the function has not already been gimplified, do so now.  */
    if (!lang_hooks.gimple_before_inlining)
      gimplify_function_tree (fndecl);


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