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]

[PATCH] Simplified alias-export (final)


This is the final version of a simplified alias-export.  Alias-export
in the sense that points-to information is transitioned over to RTL
by means of keeping all base objects in MEM_EXPR, including INDIRECT_REFs
of pointer SSA_NAMEs.  In another sense the patch opens the path to
remove overlapping parts of the RTL and the tree alias-oracles as
it simply queries the tree alias-oracle with the information from the
MEM_EXPRs after the RTL oracle is finished.

The patch consistently improves SPEC 2006 on x86_64 for me
(to my surprise), not by a large margin though.  It is a wash for Itanium
where I expected a much bigger effect.

The patch fixes the regression I introduced while "fixing" restrict.
The fix caused restrict information to no longer be available on RTL.

The worst-case memory and compile-time effects on our regular testers
was on tramp3d with -fprofile-generate, so I re-checked that numbers
after this final cleanup.  Numbers now show a (probably in the noise)
improvement in compile-time and a 0.0004% increase in peak VM memory
usage.  A memory usage increase is expected as we now keep SSA operands
and points-to sets over the whole RTL compilation and because as
the MEM_EXPRs retain all their base information mem-attr sharing should
be less efficient.  But as RTL is function-at-a-time I choose to care
less.

Re-bootstrapped and tested on x86_64-unknown-linux-gnu.  If there are
no comments I'll apply this somewhen tomorrow.

Thanks,
Richard.

2009-07-13  Richard Guenther  <rguenther@suse.de>
	Andrey Belevantsev <abel@ispras.ru>

	* tree-ssa-alias.h (refs_may_alias_p_1): Declare.
	(pt_solution_set): Likewise.
	* tree-ssa-alias.c (refs_may_alias_p_1): Export.
	* tree-ssa-structalias.c (pt_solution_set): New function.
	* final.c (rest_of_clean_state): Free SSA data structures.
	* print-rtl.c (print_decl_name): Remove.
	(print_mem_expr): Implement in terms of print_generic_expr.
	* alias.c (ao_ref_from_mem): New function.
	(rtx_refs_may_alias_p): Likewise.
	(true_dependence): Query alias-export info.
	(canon_true_dependence): Likewise.
	(write_dependence_p): Likewise.
	* tree-dfa.c (get_ref_base_and_extent): For void types leave
	size unknown.
	* emit-rtl.c (component_ref_for_mem_expr): Remove.
	(mem_expr_equal_p): Use operand_equal_p.
	(set_mem_attributes_minus_bitpos): Do not use
	component_ref_for_mem_expr.
	* cfgexpand.c (add_partitioned_vars_to_ptset): New function.
	(update_alias_info_with_stack_vars): Likewise.
	(partition_stack_vars): Call update_alias_info_with_stack_vars.
	* tree-ssa.c (delete_tree_ssa): Do not release SSA names
	explicitly nor clear stmt operands.
	Free the decl-to-pointer map.
	* tree-optimize.c (execute_free_datastructures): Do not free
	SSA data structures here.
	* tree-flow.h (struct gimple_df): Add decls_to_pointers member.
	* Makefile.in (emit-rtl.o): Add pointer-set.h dependency.
	(alias.o): Add tree-ssa-alias.h, pointer-set.h and $(TREE_FLOW_H)
	dependencies.
	(print-rtl.o): Add $(DIAGNOSTIC_H) dependency.

Index: gcc/tree-ssa-alias.h
===================================================================
*** gcc/tree-ssa-alias.h.orig	2009-07-13 10:36:03.000000000 +0200
--- gcc/tree-ssa-alias.h	2009-07-13 12:15:38.000000000 +0200
*************** extern tree ao_ref_base (ao_ref *);
*** 92,97 ****
--- 92,98 ----
  extern alias_set_type ao_ref_alias_set (ao_ref *);
  extern bool ptr_deref_may_alias_global_p (tree);
  extern bool refs_may_alias_p (tree, tree);
+ extern bool refs_may_alias_p_1 (ao_ref *, ao_ref *, bool);
  extern bool refs_anti_dependent_p (tree, tree);
  extern bool refs_output_dependent_p (tree, tree);
  extern bool ref_maybe_used_by_stmt_p (gimple, tree);
*************** extern bool pt_solutions_intersect (stru
*** 121,126 ****
--- 122,128 ----
  extern bool pt_solutions_same_restrict_base (struct pt_solution *,
  					     struct pt_solution *);
  extern void pt_solution_reset (struct pt_solution *);
+ extern void pt_solution_set (struct pt_solution *, bitmap);
  extern void dump_pta_stats (FILE *);
  
  
Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c.orig	2009-07-13 10:36:03.000000000 +0200
--- gcc/tree-ssa-alias.c	2009-07-13 14:32:12.000000000 +0200
*************** indirect_refs_may_alias_p (tree ref1, tr
*** 724,730 ****
  
  /* Return true, if the two memory references REF1 and REF2 may alias.  */
  
! static bool
  refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
  {
    tree base1, base2;
--- 724,730 ----
  
  /* Return true, if the two memory references REF1 and REF2 may alias.  */
  
! bool
  refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
  {
    tree base1, base2;
Index: gcc/final.c
===================================================================
*** gcc/final.c.orig	2009-07-13 10:36:03.000000000 +0200
--- gcc/final.c	2009-07-13 10:50:58.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 72,77 ****
--- 72,78 ----
  #include "expr.h"
  #include "cfglayout.h"
  #include "tree-pass.h"
+ #include "tree-flow.h"
  #include "timevar.h"
  #include "cgraph.h"
  #include "coverage.h"
*************** rest_of_clean_state (void)
*** 4422,4427 ****
--- 4423,4430 ----
  
    free_bb_for_insn ();
  
+   delete_tree_ssa ();
+ 
    if (targetm.binds_local_p (current_function_decl))
      {
        unsigned int pref = crtl->preferred_stack_boundary;
Index: gcc/print-rtl.c
===================================================================
*** gcc/print-rtl.c.orig	2009-07-13 10:36:03.000000000 +0200
--- gcc/print-rtl.c	2009-07-13 10:50:58.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 40,45 ****
--- 40,46 ----
  #include "flags.h"
  #include "hard-reg-set.h"
  #include "basic-block.h"
+ #include "diagnostic.h"
  #endif
  
  static FILE *outfile;
*************** int flag_simple = 0;
*** 72,131 ****
  int dump_for_graph;
  
  #ifndef GENERATOR_FILE
- static void
- print_decl_name (FILE *outfile, const_tree node)
- {
-   if (DECL_NAME (node))
-     fputs (IDENTIFIER_POINTER (DECL_NAME (node)), outfile);
-   else
-     {
-       if (TREE_CODE (node) == LABEL_DECL && LABEL_DECL_UID (node) != -1)
- 	fprintf (outfile, "L.%d", (int) LABEL_DECL_UID (node));
-       else
-         {
-           char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
- 	  fprintf (outfile, "%c.%u", c, DECL_UID (node));
-         }
-     }
- }
- 
  void
  print_mem_expr (FILE *outfile, const_tree expr)
  {
!   if (TREE_CODE (expr) == COMPONENT_REF)
!     {
!       if (TREE_OPERAND (expr, 0))
! 	print_mem_expr (outfile, TREE_OPERAND (expr, 0));
!       else
! 	fputs (" <variable>", outfile);
!       fputc ('.', outfile);
!       print_decl_name (outfile, TREE_OPERAND (expr, 1));
!     }
!   else if (TREE_CODE (expr) == INDIRECT_REF)
!     {
!       fputs (" (*", outfile);
!       print_mem_expr (outfile, TREE_OPERAND (expr, 0));
!       fputs (")", outfile);
!     }
!   else if (TREE_CODE (expr) == ALIGN_INDIRECT_REF)
!     {
!       fputs (" (A*", outfile);
!       print_mem_expr (outfile, TREE_OPERAND (expr, 0));
!       fputs (")", outfile);
!     }
!   else if (TREE_CODE (expr) == MISALIGNED_INDIRECT_REF)
!     {
!       fputs (" (M*", outfile);
!       print_mem_expr (outfile, TREE_OPERAND (expr, 0));
!       fputs (")", outfile);
!     }
!   else if (TREE_CODE (expr) == RESULT_DECL)
!     fputs (" <result>", outfile);
!   else
!     {
!       fputc (' ', outfile);
!       print_decl_name (outfile, expr);
!     }
  }
  #endif
  
--- 73,83 ----
  int dump_for_graph;
  
  #ifndef GENERATOR_FILE
  void
  print_mem_expr (FILE *outfile, const_tree expr)
  {
!   fputc (' ', outfile);
!   print_generic_expr (outfile, CONST_CAST_TREE (expr), 0);
  }
  #endif
  
Index: gcc/alias.c
===================================================================
*** gcc/alias.c.orig	2009-07-13 10:36:03.000000000 +0200
--- gcc/alias.c	2009-07-13 14:32:12.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 46,51 ****
--- 46,54 ----
  #include "tree-pass.h"
  #include "ipa-type-escape.h"
  #include "df.h"
+ #include "tree-ssa-alias.h"
+ #include "pointer-set.h"
+ #include "tree-flow.h"
  
  /* The aliasing API provided here solves related but different problems:
  
*************** DEF_VEC_ALLOC_P(alias_set_entry,gc);
*** 249,254 ****
--- 252,349 ----
  /* The splay-tree used to store the various alias set entries.  */
  static GTY (()) VEC(alias_set_entry,gc) *alias_sets;
  
+ /* Build a decomposed reference object for querying the alias-oracle
+    from the MEM rtx and store it in *REF.
+    Returns false if MEM is not suitable for the alias-oracle.  */
+ 
+ static bool
+ ao_ref_from_mem (ao_ref *ref, const_rtx mem)
+ {
+   tree expr = MEM_EXPR (mem);
+   tree base;
+ 
+   if (!expr)
+     return false;
+ 
+   ao_ref_init (ref, expr);
+ 
+   /* Get the base of the reference and see if we have to reject or
+      adjust it.  */
+   base = ao_ref_base (ref);
+   if (base == NULL_TREE)
+     return false;
+ 
+   /* If this is a pointer dereference of a non-SSA_NAME punt.
+      ???  We could replace it with a pointer to anything.  */
+   if (INDIRECT_REF_P (base)
+       && TREE_CODE (TREE_OPERAND (base, 0)) != SSA_NAME)
+     return false;
+ 
+   /* If this is a reference based on a partitioned decl replace the
+      base with an INDIRECT_REF of the pointer representative we
+      created during stack slot partitioning.  */
+   if (TREE_CODE (base) == VAR_DECL
+       && ! TREE_STATIC (base)
+       && cfun->gimple_df->decls_to_pointers != NULL)
+     {
+       void *namep;
+       namep = pointer_map_contains (cfun->gimple_df->decls_to_pointers, base);
+       if (namep)
+ 	{
+ 	  ref->base_alias_set = get_alias_set (base);
+ 	  ref->base = build1 (INDIRECT_REF, TREE_TYPE (base), *(tree *)namep);
+ 	}
+     }
+ 
+   ref->ref_alias_set = MEM_ALIAS_SET (mem);
+ 
+   /* For NULL MEM_OFFSET the MEM_EXPR may have been stripped arbitrarily
+      without recording offset or extent adjustments properly.  */
+   if (MEM_OFFSET (mem) == NULL_RTX)
+     {
+       ref->offset = 0;
+       ref->max_size = -1;
+     }
+   else
+     {
+       ref->offset += INTVAL (MEM_OFFSET (mem)) * BITS_PER_UNIT;
+     }
+ 
+   /* NULL MEM_SIZE should not really happen with a non-NULL MEM_EXPR,
+      but just play safe here.  The size may have been adjusted together
+      with the offset, so we need to take it if it is set and not rely
+      on MEM_EXPR here (which has the size determining parts potentially
+      stripped anyway).  We lose precision for max_size which is only
+      available from the remaining MEM_EXPR.  */
+   if (MEM_SIZE (mem) == NULL_RTX)
+     {
+       ref->size = -1;
+       ref->max_size = -1;
+     }
+   else
+     {
+       ref->size = INTVAL (MEM_SIZE (mem)) * BITS_PER_UNIT;
+     }
+ 
+   return true;
+ }
+ 
+ /* Query the alias-oracle on whether the two memory rtx X and MEM may
+    alias.  If TBAA_P is set also apply TBAA.  Returns true if the
+    two rtxen may alias, false otherwise.  */
+ 
+ static bool
+ rtx_refs_may_alias_p (const_rtx x, const_rtx mem, bool tbaa_p)
+ {
+   ao_ref ref1, ref2;
+ 
+   if (!ao_ref_from_mem (&ref1, x)
+       || !ao_ref_from_mem (&ref2, mem))
+     return true;
+ 
+   return refs_may_alias_p_1 (&ref1, &ref2, tbaa_p);
+ }
+ 
  /* Returns a pointer to the alias set entry for ALIAS_SET, if there is
     such an entry, or NULL otherwise.  */
  
*************** true_dependence (const_rtx mem, enum mac
*** 2191,2198 ****
    if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
      return 1;
  
!   return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
! 					      varies);
  }
  
  /* Canonical true dependence: X is read after store in MEM takes place.
--- 2286,2295 ----
    if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
      return 1;
  
!   if (fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, varies))
!     return 0;
! 
!   return rtx_refs_may_alias_p (x, mem, true);
  }
  
  /* Canonical true dependence: X is read after store in MEM takes place.
*************** canon_true_dependence (const_rtx mem, en
*** 2255,2262 ****
    if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
      return 1;
  
!   return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
! 					      varies);
  }
  
  /* Returns nonzero if a write to X might alias a previous read from
--- 2352,2361 ----
    if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
      return 1;
  
!   if (fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, varies))
!     return 0;
! 
!   return rtx_refs_may_alias_p (x, mem, true);
  }
  
  /* Returns nonzero if a write to X might alias a previous read from
*************** write_dependence_p (const_rtx mem, const
*** 2316,2323 ****
      = fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
  					 rtx_addr_varies_p);
  
!   return (!(fixed_scalar == mem && !aliases_everything_p (x))
! 	  && !(fixed_scalar == x && !aliases_everything_p (mem)));
  }
  
  /* Anti dependence: X is written after read in MEM takes place.  */
--- 2415,2425 ----
      = fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
  					 rtx_addr_varies_p);
  
!   if ((fixed_scalar == mem && !aliases_everything_p (x))
!       || (fixed_scalar == x && !aliases_everything_p (mem)))
!     return 0;
! 
!   return rtx_refs_may_alias_p (x, mem, false);
  }
  
  /* Anti dependence: X is written after read in MEM takes place.  */
Index: gcc/tree-dfa.c
===================================================================
*** gcc/tree-dfa.c.orig	2009-07-13 10:36:03.000000000 +0200
--- gcc/tree-dfa.c	2009-07-13 12:43:20.000000000 +0200
*************** get_ref_base_and_extent (tree exp, HOST_
*** 729,735 ****
      size_tree = DECL_SIZE (TREE_OPERAND (exp, 1));
    else if (TREE_CODE (exp) == BIT_FIELD_REF)
      size_tree = TREE_OPERAND (exp, 1);
!   else
      {
        enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
        if (mode == BLKmode)
--- 729,735 ----
      size_tree = DECL_SIZE (TREE_OPERAND (exp, 1));
    else if (TREE_CODE (exp) == BIT_FIELD_REF)
      size_tree = TREE_OPERAND (exp, 1);
!   else if (!VOID_TYPE_P (TREE_TYPE (exp)))
      {
        enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
        if (mode == BLKmode)
Index: gcc/emit-rtl.c
===================================================================
*** gcc/emit-rtl.c.orig	2009-07-13 10:36:03.000000000 +0200
--- gcc/emit-rtl.c	2009-07-13 10:50:58.000000000 +0200
*************** static mem_attrs *get_mem_attrs (alias_s
*** 197,203 ****
  static hashval_t reg_attrs_htab_hash (const void *);
  static int reg_attrs_htab_eq (const void *, const void *);
  static reg_attrs *get_reg_attrs (tree, int);
- static tree component_ref_for_mem_expr (tree);
  static rtx gen_const_vector (enum machine_mode, int);
  static void copy_rtx_if_shared_1 (rtx *orig);
  
--- 197,202 ----
*************** operand_subword_force (rtx op, unsigned
*** 1429,1468 ****
    return result;
  }
  
- /* Within a MEM_EXPR, we care about either (1) a component ref of a decl,
-    or (2) a component ref of something variable.  Represent the later with
-    a NULL expression.  */
- 
- static tree
- component_ref_for_mem_expr (tree ref)
- {
-   tree inner = TREE_OPERAND (ref, 0);
- 
-   if (TREE_CODE (inner) == COMPONENT_REF)
-     inner = component_ref_for_mem_expr (inner);
-   else
-     {
-       /* Now remove any conversions: they don't change what the underlying
- 	 object is.  Likewise for SAVE_EXPR.  */
-       while (CONVERT_EXPR_P (inner)
- 	     || TREE_CODE (inner) == VIEW_CONVERT_EXPR
- 	     || TREE_CODE (inner) == SAVE_EXPR)
- 	inner = TREE_OPERAND (inner, 0);
- 
-       if (! DECL_P (inner))
- 	inner = NULL_TREE;
-     }
- 
-   if (inner == TREE_OPERAND (ref, 0)
-       /* Don't leak SSA-names in the third operand.  */
-       && (!TREE_OPERAND (ref, 2)
- 	  || TREE_CODE (TREE_OPERAND (ref, 2)) != SSA_NAME))
-     return ref;
-   else
-     return build3 (COMPONENT_REF, TREE_TYPE (ref), inner,
- 		   TREE_OPERAND (ref, 1), NULL_TREE);
- }
- 
  /* Returns 1 if both MEM_EXPR can be considered equal
     and 0 otherwise.  */
  
--- 1428,1433 ----
*************** mem_expr_equal_p (const_tree expr1, cons
*** 1478,1500 ****
    if (TREE_CODE (expr1) != TREE_CODE (expr2))
      return 0;
  
!   if (TREE_CODE (expr1) == COMPONENT_REF)
!     return 
!       mem_expr_equal_p (TREE_OPERAND (expr1, 0),
! 			TREE_OPERAND (expr2, 0))
!       && mem_expr_equal_p (TREE_OPERAND (expr1, 1), /* field decl */
! 			   TREE_OPERAND (expr2, 1));
!   
!   if (INDIRECT_REF_P (expr1))
!     return mem_expr_equal_p (TREE_OPERAND (expr1, 0),
! 			     TREE_OPERAND (expr2, 0));
! 
!   /* ARRAY_REFs, ARRAY_RANGE_REFs and BIT_FIELD_REFs should already
! 	      have been resolved here.  */
!   gcc_assert (DECL_P (expr1));
!   
!   /* Decls with different pointers can't be equal.  */
!   return 0;
  }
  
  /* Return OFFSET if XEXP (MEM, 0) - OFFSET is known to be ALIGN
--- 1443,1449 ----
    if (TREE_CODE (expr1) != TREE_CODE (expr2))
      return 0;
  
!   return operand_equal_p (expr1, expr2, 0);
  }
  
  /* Return OFFSET if XEXP (MEM, 0) - OFFSET is known to be ALIGN
*************** set_mem_attributes_minus_bitpos (rtx ref
*** 1732,1738 ****
        else if (TREE_CODE (t) == COMPONENT_REF
  	       && ! DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
  	{
! 	  expr = component_ref_for_mem_expr (t);
  	  offset = const0_rtx;
  	  apply_bitpos = bitpos;
  	  /* ??? Any reason the field size would be different than
--- 1681,1687 ----
        else if (TREE_CODE (t) == COMPONENT_REF
  	       && ! DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
  	{
! 	  expr = t;
  	  offset = const0_rtx;
  	  apply_bitpos = bitpos;
  	  /* ??? Any reason the field size would be different than
*************** set_mem_attributes_minus_bitpos (rtx ref
*** 1789,1795 ****
  	    }
  	  else if (TREE_CODE (t2) == COMPONENT_REF)
  	    {
! 	      expr = component_ref_for_mem_expr (t2);
  	      if (host_integerp (off_tree, 1))
  		{
  		  offset = GEN_INT (tree_low_cst (off_tree, 1));
--- 1738,1745 ----
  	    }
  	  else if (TREE_CODE (t2) == COMPONENT_REF)
  	    {
! 	      expr = t2;
! 	      offset = NULL;
  	      if (host_integerp (off_tree, 1))
  		{
  		  offset = GEN_INT (tree_low_cst (off_tree, 1));
Index: gcc/cfgexpand.c
===================================================================
*** gcc/cfgexpand.c.orig	2009-07-13 10:36:03.000000000 +0200
--- gcc/cfgexpand.c	2009-07-13 12:40:45.000000000 +0200
*************** stack_var_size_cmp (const void *a, const
*** 784,789 ****
--- 784,916 ----
    return 0;
  }
  
+ 
+ /* If the points-to solution *PI points to variables that are in a partition
+    together with other variables add all partition members to the pointed-to
+    variables bitmap.  */
+ 
+ static void
+ add_partitioned_vars_to_ptset (struct pt_solution *pt,
+ 			       struct pointer_map_t *decls_to_partitions,
+ 			       struct pointer_set_t *visited, bitmap temp)
+ {
+   bitmap_iterator bi;
+   unsigned i;
+   bitmap *part;
+ 
+   if (pt->anything
+       || pt->vars == NULL
+       /* The pointed-to vars bitmap is shared, it is enough to
+ 	 visit it once.  */
+       || pointer_set_insert(visited, pt->vars))
+     return;
+ 
+   bitmap_clear (temp);
+ 
+   /* By using a temporary bitmap to store all members of the partitions
+      we have to add we make sure to visit each of the partitions only
+      once.  */
+   EXECUTE_IF_SET_IN_BITMAP (pt->vars, 0, i, bi)
+     if ((!temp
+ 	 || !bitmap_bit_p (temp, i))
+ 	&& (part = (bitmap *) pointer_map_contains (decls_to_partitions,
+ 						    (void *)(size_t) i)))
+       bitmap_ior_into (temp, *part);
+   if (!bitmap_empty_p (temp))
+     bitmap_ior_into (pt->vars, temp);
+ }
+ 
+ /* Update points-to sets based on partition info, so we can use them on RTL.
+    The bitmaps representing stack partitions will be saved until expand,
+    where partitioned decls used as bases in memory expressions will be
+    rewritten.  */
+ 
+ static void
+ update_alias_info_with_stack_vars (void)
+ {
+   struct pointer_map_t *decls_to_partitions = NULL;
+   size_t i, j;
+   tree var = NULL_TREE;
+ 
+   for (i = 0; i < stack_vars_num; i++)
+     {
+       bitmap part = NULL;
+       tree name;
+       struct ptr_info_def *pi;
+ 
+       /* Not interested in partitions with single variable.  */
+       if (stack_vars[i].representative != i
+           || stack_vars[i].next == EOC)
+         continue;
+ 
+       if (!decls_to_partitions)
+ 	{
+ 	  decls_to_partitions = pointer_map_create ();
+ 	  cfun->gimple_df->decls_to_pointers = pointer_map_create ();
+ 	}
+ 
+       /* Create an SSA_NAME that points to the partition for use
+          as base during alias-oracle queries on RTL for bases that
+ 	 have been partitioned.  */
+       if (var == NULL_TREE)
+ 	var = create_tmp_var (ptr_type_node, NULL);
+       name = make_ssa_name (var, NULL);
+ 
+       /* Create bitmaps representing partitions.  They will be used for
+          points-to sets later, so use GGC alloc.  */
+       part = BITMAP_GGC_ALLOC ();
+       for (j = i; j != EOC; j = stack_vars[j].next)
+ 	{
+ 	  tree decl = stack_vars[j].decl;
+ 	  unsigned int uid = DECL_UID (decl);
+ 	  /* We should never end up partitioning SSA names (though they
+ 	     may end up on the stack).  Neither should we allocate stack
+ 	     space to something that is unused and thus unreferenced.  */
+ 	  gcc_assert (DECL_P (decl)
+ 		      && referenced_var_lookup (uid));
+ 	  bitmap_set_bit (part, uid);
+ 	  *((bitmap *) pointer_map_insert (decls_to_partitions,
+ 					   (void *)(size_t) uid)) = part;
+ 	  *((tree *) pointer_map_insert (cfun->gimple_df->decls_to_pointers,
+ 					 decl)) = name;
+ 	}
+ 
+       /* Make the SSA name point to all partition members.  */
+       pi = get_ptr_info (name);
+       pt_solution_set (&pi->pt, part);
+     }
+ 
+   /* Make all points-to sets that contain one member of a partition
+      contain all members of the partition.  */
+   if (decls_to_partitions)
+     {
+       unsigned i;
+       struct pointer_set_t *visited = pointer_set_create ();
+       bitmap temp = BITMAP_ALLOC (NULL);
+ 
+       for (i = 1; i < num_ssa_names; i++)
+ 	{
+ 	  tree name = ssa_name (i);
+ 	  struct ptr_info_def *pi;
+ 
+ 	  if (name
+ 	      && POINTER_TYPE_P (TREE_TYPE (name))
+ 	      && ((pi = SSA_NAME_PTR_INFO (name)) != NULL))
+ 	    add_partitioned_vars_to_ptset (&pi->pt, decls_to_partitions,
+ 					   visited, temp);
+ 	}
+ 
+       add_partitioned_vars_to_ptset (&cfun->gimple_df->escaped,
+ 				     decls_to_partitions, visited, temp);
+       add_partitioned_vars_to_ptset (&cfun->gimple_df->callused,
+ 				     decls_to_partitions, visited, temp);
+ 
+       pointer_set_destroy (visited);
+       pointer_map_destroy (decls_to_partitions);
+       BITMAP_FREE (temp);
+     }
+ }
+ 
  /* A subroutine of partition_stack_vars.  The UNION portion of a UNION/FIND
     partitioning algorithm.  Partitions A and B are known to be non-conflicting.
     Merge them into a single partition A.
*************** partition_stack_vars (void)
*** 903,908 ****
--- 1030,1037 ----
  	    break;
  	}
      }
+ 
+   update_alias_info_with_stack_vars ();
  }
  
  /* A debugging aid for expand_used_vars.  Dump the generated partitions.  */
Index: gcc/tree-ssa.c
===================================================================
*** gcc/tree-ssa.c.orig	2009-07-13 10:36:03.000000000 +0200
--- gcc/tree-ssa.c	2009-07-13 10:50:58.000000000 +0200
*************** init_tree_ssa (struct function *fn)
*** 802,853 ****
  void
  delete_tree_ssa (void)
  {
-   size_t i;
-   basic_block bb;
-   gimple_stmt_iterator gsi;
    referenced_var_iterator rvi;
    tree var;
  
-   /* Release any ssa_names still in use.  */
-   for (i = 0; i < num_ssa_names; i++)
-     {
-       tree var = ssa_name (i);
-       if (var && TREE_CODE (var) == SSA_NAME)
-         {
- 	  SSA_NAME_IMM_USE_NODE (var).prev = &(SSA_NAME_IMM_USE_NODE (var));
- 	  SSA_NAME_IMM_USE_NODE (var).next = &(SSA_NAME_IMM_USE_NODE (var));
- 	}
-       release_ssa_name (var);
-     }
- 
-   /* FIXME.  This may not be necessary.  We will release all this
-      memory en masse in free_ssa_operands.  This clearing used to be
-      necessary to avoid problems with the inliner, but it may not be
-      needed anymore.  */
-   FOR_EACH_BB (bb)
-     {
-       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- 	{
- 	  gimple stmt = gsi_stmt (gsi);
- 
- 	  if (gimple_has_ops (stmt))
- 	    {
- 	      gimple_set_def_ops (stmt, NULL);
- 	      gimple_set_use_ops (stmt, NULL);
- 	    }
- 
- 	  if (gimple_has_mem_ops (stmt))
- 	    {
- 	      gimple_set_vdef (stmt, NULL_TREE);
- 	      gimple_set_vuse (stmt, NULL_TREE);
- 	    }
- 
- 	  gimple_set_modified (stmt, true);
- 	}
-       if (!(bb->flags & BB_RTL))
- 	set_phi_nodes (bb, NULL);
-     }
- 
    /* Remove annotations from every referenced local variable.  */
    FOR_EACH_REFERENCED_VAR (var, rvi)
      {
--- 802,810 ----
*************** delete_tree_ssa (void)
*** 873,878 ****
--- 830,838 ----
    cfun->gimple_df->default_defs = NULL;
    pt_solution_reset (&cfun->gimple_df->escaped);
    pt_solution_reset (&cfun->gimple_df->callused);
+   if (cfun->gimple_df->decls_to_pointers != NULL)
+     pointer_map_destroy (cfun->gimple_df->decls_to_pointers);
+   cfun->gimple_df->decls_to_pointers = NULL;
    cfun->gimple_df->modified_noreturn_calls = NULL;
    cfun->gimple_df = NULL;
  
Index: gcc/tree-optimize.c
===================================================================
*** gcc/tree-optimize.c.orig	2009-07-13 10:36:03.000000000 +0200
--- gcc/tree-optimize.c	2009-07-13 10:50:58.000000000 +0200
*************** execute_free_datastructures (void)
*** 226,235 ****
    free_dominance_info (CDI_DOMINATORS);
    free_dominance_info (CDI_POST_DOMINATORS);
  
-   /* Remove the ssa structures.  */
-   if (cfun->gimple_df)
-     delete_tree_ssa ();
- 
    /* And get rid of annotations we no longer need.  */
    delete_tree_cfg_annotations ();
  
--- 226,231 ----
Index: gcc/tree-flow.h
===================================================================
*** gcc/tree-flow.h.orig	2009-07-13 10:36:03.000000000 +0200
--- gcc/tree-flow.h	2009-07-13 12:43:48.000000000 +0200
*************** struct GTY(()) gimple_df {
*** 63,68 ****
--- 63,72 ----
    /* The PTA solution for the CALLUSED artificial variable.  */
    struct pt_solution callused;
  
+   /* A map of decls to artificial ssa-names that point to the partition
+      of the decl.  */
+   struct pointer_map_t * GTY((skip(""))) decls_to_pointers;
+ 
    /* Free list of SSA_NAMEs.  */
    tree free_ssanames;
  
Index: gcc/Makefile.in
===================================================================
*** gcc/Makefile.in.orig	2009-07-13 10:36:03.000000000 +0200
--- gcc/Makefile.in	2009-07-13 10:50:58.000000000 +0200
*************** rtl.o : rtl.c $(CONFIG_H) $(SYSTEM_H) co
*** 2565,2571 ****
  
  print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
      $(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H) $(FLAGS_H) \
!     $(BCONFIG_H) $(REAL_H)
  rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) \
     $(RTL_H) hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) $(REAL_H) \
     $(FLAGS_H) $(REGS_H) output.h $(TARGET_H) $(FUNCTION_H) $(TREE_H) \
--- 2565,2571 ----
  
  print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
      $(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H) $(FLAGS_H) \
!     $(BCONFIG_H) $(REAL_H) $(DIAGNOSTIC_H)
  rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) \
     $(RTL_H) hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) $(REAL_H) \
     $(FLAGS_H) $(REGS_H) output.h $(TARGET_H) $(FUNCTION_H) $(TREE_H) \
*************** emit-rtl.o : emit-rtl.c $(CONFIG_H) $(SY
*** 2653,2659 ****
     $(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) insn-config.h $(RECOG_H) \
     $(GGC_H) $(EXPR_H) hard-reg-set.h $(BITMAP_H) $(TOPLEV_H) $(BASIC_BLOCK_H) \
     $(HASHTAB_H) $(TM_P_H) debug.h langhooks.h $(TREE_PASS_H) gt-emit-rtl.h \
!    $(REAL_H) $(DF_H)
  real.o : real.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
     $(TOPLEV_H) $(TM_P_H) $(REAL_H) dfp.h
  dfp.o : dfp.c dfp.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)	$(TREE_H) \
--- 2653,2659 ----
     $(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) insn-config.h $(RECOG_H) \
     $(GGC_H) $(EXPR_H) hard-reg-set.h $(BITMAP_H) $(TOPLEV_H) $(BASIC_BLOCK_H) \
     $(HASHTAB_H) $(TM_P_H) debug.h langhooks.h $(TREE_PASS_H) gt-emit-rtl.h \
!    $(REAL_H) $(DF_H) pointer-set.h
  real.o : real.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
     $(TOPLEV_H) $(TM_P_H) $(REAL_H) dfp.h
  dfp.o : dfp.c dfp.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)	$(TREE_H) \
*************** alias.o : alias.c $(CONFIG_H) $(SYSTEM_H
*** 2978,2984 ****
     $(FLAGS_H) hard-reg-set.h $(BASIC_BLOCK_H) $(REGS_H) $(TOPLEV_H) output.h \
     $(ALIAS_H) $(EMIT_RTL_H) $(GGC_H) $(FUNCTION_H) cselib.h $(TREE_H) $(TM_P_H) \
     langhooks.h $(TARGET_H) gt-alias.h $(TIMEVAR_H) $(CGRAPH_H) \
!    $(SPLAY_TREE_H) $(VARRAY_H) $(IPA_TYPE_ESCAPE_H) $(DF_H) $(TREE_PASS_H)
  stack-ptr-mod.o : stack-ptr-mod.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TM_H) $(TREE_H) $(RTL_H) $(REGS_H) $(EXPR_H) $(TREE_PASS_H) \
     $(BASIC_BLOCK_H) $(FLAGS_H) output.h $(DF_H)
--- 2978,2985 ----
     $(FLAGS_H) hard-reg-set.h $(BASIC_BLOCK_H) $(REGS_H) $(TOPLEV_H) output.h \
     $(ALIAS_H) $(EMIT_RTL_H) $(GGC_H) $(FUNCTION_H) cselib.h $(TREE_H) $(TM_P_H) \
     langhooks.h $(TARGET_H) gt-alias.h $(TIMEVAR_H) $(CGRAPH_H) \
!    $(SPLAY_TREE_H) $(VARRAY_H) $(IPA_TYPE_ESCAPE_H) $(DF_H) $(TREE_PASS_H) \
!    tree-ssa-alias.h pointer-set.h $(TREE_FLOW_H)
  stack-ptr-mod.o : stack-ptr-mod.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TM_H) $(TREE_H) $(RTL_H) $(REGS_H) $(EXPR_H) $(TREE_PASS_H) \
     $(BASIC_BLOCK_H) $(FLAGS_H) output.h $(DF_H)
Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c.orig	2009-07-02 17:00:53.000000000 +0200
--- gcc/tree-ssa-structalias.c	2009-07-13 14:28:53.000000000 +0200
*************** pt_solution_reset (struct pt_solution *p
*** 4886,4891 ****
--- 4886,4913 ----
    pt->anything = true;
  }
  
+ /* Set the points-to solution *PT to point only to the variables
+    in VARS.  */
+ 
+ void
+ pt_solution_set (struct pt_solution *pt, bitmap vars)
+ {
+   bitmap_iterator bi;
+   unsigned i;
+ 
+   memset (pt, 0, sizeof (struct pt_solution));
+   pt->vars = vars;
+   EXECUTE_IF_SET_IN_BITMAP (vars, 0, i, bi)
+     {
+       tree var = referenced_var_lookup (i);
+       if (is_global_var (var))
+ 	{
+ 	  pt->vars_contains_global = true;
+ 	  break;
+ 	}
+     }
+ }
+ 
  /* Return true if the points-to solution *PT is empty.  */
  
  static bool


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