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] TREE_ADDRESSABLE versus ARRAY_TYPE


Richard (and Diego, please check me :),

this is somewhat revisited version of the patch based on discussion in
between Diego and me.  All the aliasing issues are little bit messy for
my little mind, so I will try to describe ours (ot at least mine's
understanding of) conclusion here and hope to hear your opinion.

We do have function needs_to_live_in_memory.  It is bit dificult to understand
exact definition of it for me, but from the usage it is basically used to
detect objects that can be addressed even tought the direct address operator is
missing.  So I can accempt definition of "memory" in gimple way to be place
where all object pointers can point to go.

In this sense code declaring all arrays to live in memory does not fit very
well (nor does Diego's original proposal to limit check to arrays with
nonconstant accesses only).  It seems to me that sole purpose of this code is
to make RTL expanders happy as they can't do nonconstant offsets in registers
and they don't work out themselves that it must go to memory (as they do for
large struct for instance).

Thus this patch uses my pass to detect those nonconstant memories and put
ADDRESSABLE flag at very end of ssa compilation pass.
For Gimple, the arrays are objects not living in memory (unless their address is taken).
This wins better aliasing, more sibcalls and hopefully also more SRA later.

Does this seem to make sense?
Bootstrapped/regtested i686-pc-gnu
Hope I didn't messed up something obvious

Honza

2004-01-13  Jan Hubicka  <jh@suse.cz>
	* Makefile.in: Remvoe tree-simple from GTYized files.
	* tree-dfa.c (find_addressable_vars): Parse nontrivial ADDR_EXPRs.
	(discover_nonconstant_array_refs_r): New static function.
	(discover_nonconstant_array_refs): New global function.
	* tree-flow.h (discover_nonconstant_array_refs): Declare.
	* tree-optimize.c (optimize_function_tree): Call the new function.
	* tree-simple.c (types_checked, types_in_memory): Kill.
	(struct_needs_to_live_in_memory): Kill.
	(needs_to_live_in_memory): aggregates are safe.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.903.2.165
diff -c -3 -p -r1.903.2.165 Makefile.in
*** Makefile.in	7 Jan 2004 23:44:14 -0000	1.903.2.165
--- Makefile.in	12 Jan 2004 18:36:58 -0000
*************** GTFILES = $(srcdir)/input.h $(srcdir)/co
*** 2202,2208 ****
    $(srcdir)/tree-alias-type.h $(srcdir)/tree-alias-common.h \
    $(srcdir)/tree-alias-type.c $(srcdir)/tree-alias-common.c \
    $(srcdir)/tree-ssa-operands.h $(srcdir)/tree-ssa-operands.c \
-   $(srcdir)/tree-simple.c \
    $(out_file) \
    @all_gtfiles@
  
--- 2202,2207 ----
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.209
diff -c -3 -p -r1.1.4.209 tree-dfa.c
*** tree-dfa.c	9 Jan 2004 08:50:42 -0000	1.1.4.209
--- tree-dfa.c	12 Jan 2004 18:36:59 -0000
*************** find_addressable_vars (bitmap addresses_
*** 1469,1477 ****
  	      if (TREE_CODE (t) != ADDR_EXPR)
  		continue;
  
! 	      t = TREE_OPERAND (t, 0);
! 	      if (TREE_CODE (t) == VAR_DECL
! 		  || TREE_CODE (t) == PARM_DECL)
  		bitmap_set_bit (addresses_needed, var_ann (t)->uid);
  	    }
  	}
--- 1469,1477 ----
  	      if (TREE_CODE (t) != ADDR_EXPR)
  		continue;
  
! 	      t = get_base_symbol (TREE_OPERAND (t, 0));
! 	      if (t && (TREE_CODE (t) == VAR_DECL
! 		        || TREE_CODE (t) == PARM_DECL))
  		bitmap_set_bit (addresses_needed, var_ann (t)->uid);
  	    }
  	}
*************** mark_new_vars_to_rename (tree stmt, bitm
*** 2228,2231 ****
--- 2228,2277 ----
    BITMAP_XFREE (vars_in_vops_to_rename);
  }
  
+ /* Helper function for discover_nonconstant_array_refs. 
+    Look for variables inside ARRAY_REF with non-constant operand
+    and mark them as addressable.  */
+ static tree
+ discover_nonconstant_array_refs_r (tree * tp, int *walk_subtrees,
+ 				   void *data ATTRIBUTE_UNUSED)
+ {
+   tree t = *tp;
+   if (TYPE_P (t) || DECL_P (t))
+     *walk_subtrees = 0;
+   else if (TREE_CODE (t) == ARRAY_REF)
+     {
+       while ((TREE_CODE (t) == ARRAY_REF
+ 	      && is_gimple_min_invariant (TREE_OPERAND (t, 1)))
+ 	     || (TREE_CODE (t) == COMPONENT_REF
+ 		 || TREE_CODE (t) == REALPART_EXPR
+ 		 || TREE_CODE (t) == IMAGPART_EXPR))
+ 	t = TREE_OPERAND (t, 0);
+       if (TREE_CODE (t) == ARRAY_REF)
+ 	{
+ 	  t = get_base_symbol (t);
+ 	  if (t && DECL_P (t))
+ 	    TREE_ADDRESSABLE (t) = 1;
+ 	}
+       *walk_subtrees = 0;
+     }
+   return NULL_TREE;
+ }
+ 
+ /* RTL expansion code is not able to compile array references with variable
+    offsets for arrays stored in single register.
+    Discover such expressions and mark variables as addressable to avoid
+    this scenario.  */
+ void
+ discover_nonconstant_array_refs (void)
+ {
+   basic_block bb;
+   block_stmt_iterator bsi;
+ 
+   FOR_EACH_BB (bb)
+     {
+       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ 	walk_tree (bsi_stmt_ptr (bsi), discover_nonconstant_array_refs_r,
+ 		   NULL , NULL);
+     }
+ }
  #include "gt-tree-dfa.h"
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.179
diff -c -3 -p -r1.1.4.179 tree-flow.h
*** tree-flow.h	7 Jan 2004 23:44:15 -0000	1.1.4.179
--- tree-flow.h	12 Jan 2004 18:36:59 -0000
*************** extern tree get_virtual_var (tree);
*** 471,476 ****
--- 471,477 ----
  extern void create_global_var (void);
  extern void add_referenced_tmp_var (tree var);
  extern void mark_new_vars_to_rename (tree, bitmap);
+ extern void discover_nonconstant_array_refs (void);
  
  /* Flags used when computing reaching definitions and reached uses.  */
  #define TDFA_USE_OPS		1 << 0
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v
retrieving revision 1.1.4.105
diff -c -3 -p -r1.1.4.105 tree-optimize.c
*** tree-optimize.c	9 Jan 2004 21:19:27 -0000	1.1.4.105
--- tree-optimize.c	12 Jan 2004 18:36:59 -0000
*************** optimize_function_tree (tree fndecl, tre
*** 287,292 ****
--- 287,294 ----
        /* Rewrite the function out of SSA form.  */
        rewrite_out_of_ssa (fndecl, TDI_optimized);
        ggc_collect ();
+       
+       discover_nonconstant_array_refs ();
  
        /* Flush out flow graph and SSA data.  */
        BITMAP_XFREE (vars_to_rename);
Index: tree-simple.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-simple.c,v
retrieving revision 1.1.4.68
diff -c -3 -p -r1.1.4.68 tree-simple.c
*** tree-simple.c	10 Jan 2004 03:29:33 -0000	1.1.4.68
--- tree-simple.c	12 Jan 2004 18:36:59 -0000
*************** is_gimple_reg_type (tree type)
*** 416,453 ****
  }
  
  
- /* Used to avoid calling struct_needs_to_live_in_memory repeatedly for the
-    same type.  */
  
- static GTY(()) bitmap types_checked = NULL;
- static GTY(()) bitmap types_in_memory = NULL;
- 
- 
- /* Return true if at least one of the fields in T is (or contains) an
-    ARRAY_TYPE.  */
- 
- static bool
- struct_needs_to_live_in_memory (tree t)
- {
-   tree f;
- 
-   for (f = TYPE_FIELDS (t); f; f = TREE_CHAIN (f))
-     {
-       if (TREE_CODE (f) != FIELD_DECL)
- 	continue;
- 
-       /* If a field is an array, the structure must go in memory.  */
-       if (TREE_CODE (TREE_TYPE (f)) == ARRAY_TYPE)
- 	return true;
- 
-       /* Check nested structures.  */
-       if (AGGREGATE_TYPE_P (TREE_TYPE (f))
- 	  && struct_needs_to_live_in_memory (TREE_TYPE (f)))
- 	return true;
-     }
- 
-   return false;
- }
  
  /* Return true if T (assumed to be a DECL) must be assigned a memory
     location.  */
--- 414,420 ----
*************** needs_to_live_in_memory (tree t)
*** 459,495 ****
    if (TREE_STATIC (t)
        || DECL_EXTERNAL (t)
        || DECL_NONLOCAL (t)
-       || TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
        || (TREE_CODE (t) == RESULT_DECL
  	  && aggregate_value_p (t, current_function_decl))
        || decl_function_context (t) != current_function_decl)
      return true;
  
-   /* Now, check for structures.  A structure will need to live in memory if
-      if at least one of its fields is of array type.  */
-   if (AGGREGATE_TYPE_P (TREE_TYPE (t)))
-     {
-       tree type = TREE_TYPE (t);
-       unsigned int uid = TYPE_UID (type);
- 
-       if (types_checked == NULL)
- 	{
- 	  types_checked = BITMAP_GGC_ALLOC ();
- 	  types_in_memory = BITMAP_GGC_ALLOC ();
- 	}
- 
-       /* If we have not examined this type already, do so and
- 	 cache the result.  */
-       if (!bitmap_bit_p (types_checked, uid))
- 	{
- 	  bitmap_set_bit (types_checked, uid);
- 	  if (struct_needs_to_live_in_memory (type))
- 	    bitmap_set_bit (types_in_memory, uid);
- 	}
- 
-       return bitmap_bit_p (types_in_memory, uid);
-     }
- 
    return false;
  }
  
--- 426,436 ----
*************** recalculate_side_effects (tree t)
*** 732,736 ****
        break;
     }
  }
- 
- #include "gt-tree-simple.h"
--- 673,675 ----


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