[PATCH][3/n] Alias housekeeping

Richard Guenther rguenther@suse.de
Wed Apr 27 14:44:00 GMT 2011


As preparation for a fix for PR48764 this removes the need for PTA
to allocate and preserve new decls.  We still need to allocate
UIDs from the decl namespace to have something to point to from
points-to sets, but that can be done with allocating them directly.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2011-04-27  Richard Guenther  <rguenther@suse.de>

	* Makefile.in (tree-ssa-structalias.o): Remove
	gt-tree-ssa-structalias.h dependency.
	(GTFILES): Remove tree-ssa-structalias.c.
	* tree.c (allocate_decl_uid): New function.
	(make_node_stat): Use it.
	(copy_node_stat): Likewise.
	* tree.h (allocate_decl_uid): Declare.
	* tree-ssa-alias.h (delete_alias_heapvars): Remove.
	* tree-ssa.c (delete_tree_ssa): Do not call delete_alias_heapvars.
	* tree-flow.h (struct var_ann_d): Remove is_heapvar flag.
	* tree-ssa-live.c (remove_unused_locals): Do not check is_heapvar
	flag.
	* tree-ssa-structalias.c (heapvar_for_stmt): Remove.
	(struct heapvar_map): Likewise.
	(heapvar_map_eq, heapvar_map_hash, heapvar_lookup,
	heapvar_insert): Likewise.
	(make_heapvar_for): Rename to ...
	(make_heapvar): ... this.  Simplify.
	(fake_var_decl_obstack): New global var.
	(build_fake_var_decl): New function.
	(make_constraint_from_heapvar): Adjust.
	(handle_lhs_call): Likewise.
	(create_function_info_for): Likewise.
	(intra_create_variable_infos): Likewise.
	(init_alias_vars): Allocate fake_var_decl_obstack.
	(init_alias_heapvars, delete_alias_heapvars): Remove.
	(compute_points_to_sets): Do not call init_alias_heapvars.
	(ipa_pta_execute): Likewise.
	(delete_points_to_sets): Free fake_var_decl_obstack.

	* gcc.dg/tree-ssa/pr23382.c: Remove.

Index: gcc/Makefile.in
===================================================================
*** gcc/Makefile.in	(revision 173018)
--- gcc/Makefile.in	(working copy)
*************** tree-ssa-structalias.o: tree-ssa-structa
*** 2381,2387 ****
     $(DIAGNOSTIC_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) \
     $(GIMPLE_H) $(HASHTAB_H) $(FUNCTION_H) $(CGRAPH_H) \
     $(TREE_PASS_H) $(TIMEVAR_H) alloc-pool.h $(SPLAY_TREE_H) $(PARAMS_H) \
!    gt-tree-ssa-structalias.h $(CGRAPH_H) $(ALIAS_H) pointer-set.h
  tree-ssa-uninit.o : tree-ssa-uninit.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
     $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \
     $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
--- 2381,2387 ----
     $(DIAGNOSTIC_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) \
     $(GIMPLE_H) $(HASHTAB_H) $(FUNCTION_H) $(CGRAPH_H) \
     $(TREE_PASS_H) $(TIMEVAR_H) alloc-pool.h $(SPLAY_TREE_H) $(PARAMS_H) \
!    $(CGRAPH_H) $(ALIAS_H) pointer-set.h
  tree-ssa-uninit.o : tree-ssa-uninit.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
     $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \
     $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
*************** GTFILES = $(CPP_ID_DATA_H) $(srcdir)/inp
*** 3776,3782 ****
    $(srcdir)/targhooks.c $(out_file) $(srcdir)/passes.c $(srcdir)/cgraphunit.c \
    $(srcdir)/tree-ssa-propagate.c \
    $(srcdir)/tree-phinodes.c \
-   $(srcdir)/tree-ssa-structalias.c \
    $(srcdir)/lto-symtab.c \
    $(srcdir)/tree-ssa-alias.h \
    $(srcdir)/ipa-prop.h \
--- 3776,3781 ----
Index: gcc/tree.c
===================================================================
*** gcc/tree.c	(revision 173018)
--- gcc/tree.c	(working copy)
*************** record_node_allocation_statistics (enum
*** 814,819 ****
--- 814,827 ----
  #endif
  }
  
+ /* Allocate and return a new UID from the DECL_UID namespace.  */
+ 
+ int
+ allocate_decl_uid (void)
+ {
+   return next_decl_uid++;
+ }
+ 
  /* Return a newly allocated node of code CODE.  For decl and type
     nodes, some other fields are initialized.  The rest of the node is
     initialized to zero.  This function cannot be used for TREE_VEC or
*************** make_node_stat (enum tree_code code MEM_
*** 857,863 ****
  	DECL_UID (t) = --next_debug_decl_uid;
        else
  	{
! 	  DECL_UID (t) = next_decl_uid++;
  	  SET_DECL_PT_UID (t, -1);
  	}
        if (TREE_CODE (t) == LABEL_DECL)
--- 865,871 ----
  	DECL_UID (t) = --next_debug_decl_uid;
        else
  	{
! 	  DECL_UID (t) = allocate_decl_uid ();
  	  SET_DECL_PT_UID (t, -1);
  	}
        if (TREE_CODE (t) == LABEL_DECL)
*************** copy_node_stat (tree node MEM_STAT_DECL)
*** 942,948 ****
  	DECL_UID (t) = --next_debug_decl_uid;
        else
  	{
! 	  DECL_UID (t) = next_decl_uid++;
  	  if (DECL_PT_UID_SET_P (node))
  	    SET_DECL_PT_UID (t, DECL_PT_UID (node));
  	}
--- 950,956 ----
  	DECL_UID (t) = --next_debug_decl_uid;
        else
  	{
! 	  DECL_UID (t) = allocate_decl_uid ();
  	  if (DECL_PT_UID_SET_P (node))
  	    SET_DECL_PT_UID (t, DECL_PT_UID (node));
  	}
Index: gcc/tree.h
===================================================================
*** gcc/tree.h	(revision 173018)
--- gcc/tree.h	(working copy)
*************** extern size_t tree_size (const_tree);
*** 4017,4022 ****
--- 4017,4025 ----
     length.  */
  extern size_t tree_code_size (enum tree_code);
  
+ /* Allocate and return a new UID from the DECL_UID namespace.  */
+ extern int allocate_decl_uid (void);
+ 
  /* Lowest level primitive for allocating a node.
     The TREE_CODE is the only argument.  Contents are initialized
     to zero except for a few of the common fields.  */
Index: gcc/tree-ssa-alias.h
===================================================================
*** gcc/tree-ssa-alias.h	(revision 173018)
--- gcc/tree-ssa-alias.h	(working copy)
*************** extern void dump_alias_stats (FILE *);
*** 125,131 ****
  
  /* In tree-ssa-structalias.c  */
  extern unsigned int compute_may_aliases (void);
- extern void delete_alias_heapvars (void);
  extern bool pt_solution_empty_p (struct pt_solution *);
  extern bool pt_solution_includes_global (struct pt_solution *);
  extern bool pt_solution_includes (struct pt_solution *, const_tree);
--- 125,130 ----
Index: gcc/tree-ssa.c
===================================================================
*** gcc/tree-ssa.c	(revision 173018)
--- gcc/tree-ssa.c	(working copy)
*************** delete_tree_ssa (void)
*** 1187,1194 ****
    if (ssa_operands_active ())
      fini_ssa_operands ();
  
-   delete_alias_heapvars ();
- 
    htab_delete (cfun->gimple_df->default_defs);
    cfun->gimple_df->default_defs = NULL;
    pt_solution_reset (&cfun->gimple_df->escaped);
--- 1187,1192 ----
Index: gcc/tree-flow.h
===================================================================
*** gcc/tree-flow.h	(revision 173018)
--- gcc/tree-flow.h	(working copy)
*************** struct GTY(()) var_ann_d {
*** 172,181 ****
       states.  */
    ENUM_BITFIELD (need_phi_state) need_phi_state : 2;
  
-   /* True for HEAP artificial variables.  These variables represent
-      the memory area allocated by a call to malloc.  */
-   unsigned is_heapvar : 1;
- 
    /* Used by var_map for the base index of ssa base variables.  */
    unsigned base_index;
  
--- 172,177 ----
Index: gcc/tree-ssa-live.c
===================================================================
*** gcc/tree-ssa-live.c	(revision 173018)
--- gcc/tree-ssa-live.c	(working copy)
*************** remove_unused_locals (void)
*** 820,827 ****
      if (!is_global_var (t)
  	&& TREE_CODE (t) != PARM_DECL
  	&& TREE_CODE (t) != RESULT_DECL
! 	&& !is_used_p (t)
! 	&& !var_ann (t)->is_heapvar)
        remove_referenced_var (t);
    remove_unused_scope_block_p (DECL_INITIAL (current_function_decl));
    if (dump_file && (dump_flags & TDF_DETAILS))
--- 821,827 ----
      if (!is_global_var (t)
  	&& TREE_CODE (t) != PARM_DECL
  	&& TREE_CODE (t) != RESULT_DECL
! 	&& !is_used_p (t))
        remove_referenced_var (t);
    remove_unused_scope_block_p (DECL_INITIAL (current_function_decl));
    if (dump_file && (dump_flags & TDF_DETAILS))
Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c	(revision 173018)
--- gcc/tree-ssa-structalias.c	(working copy)
***************
*** 197,204 ****
     keep the set of called functions for indirect calls.
  
     And probably more.  */
- static GTY ((if_marked ("tree_map_marked_p"), param_is (struct heapvar_map)))
- htab_t heapvar_for_stmt;
  
  static bool use_field_sensitive = true;
  static int in_ipa_mode = 0;
--- 197,202 ----
*************** enum { nothing_id = 0, anything_id = 1,
*** 333,393 ****
         escaped_id = 3, nonlocal_id = 4,
         storedanything_id = 5, integer_id = 6 };
  
- struct GTY(()) heapvar_map {
-   struct tree_map map;
-   unsigned HOST_WIDE_INT offset;
- };
- 
- static int
- heapvar_map_eq (const void *p1, const void *p2)
- {
-   const struct heapvar_map *h1 = (const struct heapvar_map *)p1;
-   const struct heapvar_map *h2 = (const struct heapvar_map *)p2;
-   return (h1->map.base.from == h2->map.base.from
- 	  && h1->offset == h2->offset);
- }
- 
- static unsigned int
- heapvar_map_hash (struct heapvar_map *h)
- {
-   return iterative_hash_host_wide_int (h->offset,
- 				       htab_hash_pointer (h->map.base.from));
- }
- 
- /* Lookup a heap var for FROM, and return it if we find one.  */
- 
- static tree
- heapvar_lookup (tree from, unsigned HOST_WIDE_INT offset)
- {
-   struct heapvar_map *h, in;
-   in.map.base.from = from;
-   in.offset = offset;
-   h = (struct heapvar_map *) htab_find_with_hash (heapvar_for_stmt, &in,
- 						  heapvar_map_hash (&in));
-   if (h)
-     return h->map.to;
-   return NULL_TREE;
- }
- 
- /* Insert a mapping FROM->TO in the heap var for statement
-    hashtable.  */
- 
- static void
- heapvar_insert (tree from, unsigned HOST_WIDE_INT offset, tree to)
- {
-   struct heapvar_map *h;
-   void **loc;
- 
-   h = ggc_alloc_heapvar_map ();
-   h->map.base.from = from;
-   h->offset = offset;
-   h->map.hash = heapvar_map_hash (h);
-   h->map.to = to;
-   loc = htab_find_slot_with_hash (heapvar_for_stmt, h, h->map.hash, INSERT);
-   gcc_assert (*loc == NULL);
-   *(struct heapvar_map **) loc = h;
- }
- 
  /* Return a new variable info structure consisting for a variable
     named NAME, and using constraint graph node NODE.  Append it
     to the vector of variable info structures.  */
--- 331,336 ----
*************** make_transitive_closure_constraints (var
*** 3664,3694 ****
    process_constraint (new_constraint (lhs, rhs));
  }
  
  /* Create a new artificial heap variable with NAME.
     Return the created variable.  */
  
  static varinfo_t
! make_heapvar_for (varinfo_t lhs, const char *name)
  {
    varinfo_t vi;
!   tree heapvar = heapvar_lookup (lhs->decl, lhs->offset);
! 
!   if (heapvar == NULL_TREE)
!     {
!       var_ann_t ann;
!       heapvar = create_tmp_var_raw (ptr_type_node, name);
!       DECL_EXTERNAL (heapvar) = 1;
! 
!       heapvar_insert (lhs->decl, lhs->offset, heapvar);
! 
!       ann = get_var_ann (heapvar);
!       ann->is_heapvar = 1;
!     }
! 
!   /* For global vars we need to add a heapvar to the list of referenced
!      vars of a different function than it was created for originally.  */
!   if (cfun && gimple_referenced_vars (cfun))
!     add_referenced_var (heapvar);
  
    vi = new_var_info (heapvar, name);
    vi->is_artificial_var = true;
--- 3607,3641 ----
    process_constraint (new_constraint (lhs, rhs));
  }
  
+ /* Temporary storage for fake var decls.  */
+ struct obstack fake_var_decl_obstack;
+ 
+ /* Build a fake VAR_DECL acting as referrer to a DECL_UID.  */
+ 
+ static tree
+ build_fake_var_decl (tree type)
+ {
+   tree decl = (tree) XOBNEW (&fake_var_decl_obstack, struct tree_var_decl);
+   memset (decl, 0, sizeof (struct tree_var_decl));
+   TREE_SET_CODE (decl, VAR_DECL);
+   TREE_TYPE (decl) = type;
+   DECL_UID (decl) = allocate_decl_uid ();
+   SET_DECL_PT_UID (decl, -1);
+   layout_decl (decl, 0);
+   return decl;
+ }
+ 
  /* Create a new artificial heap variable with NAME.
     Return the created variable.  */
  
  static varinfo_t
! make_heapvar (const char *name)
  {
    varinfo_t vi;
!   tree heapvar;
!   
!   heapvar = build_fake_var_decl (ptr_type_node);
!   DECL_EXTERNAL (heapvar) = 1;
  
    vi = new_var_info (heapvar, name);
    vi->is_artificial_var = true;
*************** make_heapvar_for (varinfo_t lhs, const c
*** 3709,3715 ****
  static varinfo_t
  make_constraint_from_heapvar (varinfo_t lhs, const char *name)
  {
!   varinfo_t vi = make_heapvar_for (lhs, name);
    make_constraint_from (lhs, vi->id);
  
    return vi;
--- 3656,3662 ----
  static varinfo_t
  make_constraint_from_heapvar (varinfo_t lhs, const char *name)
  {
!   varinfo_t vi = make_heapvar (name);
    make_constraint_from (lhs, vi->id);
  
    return vi;
*************** handle_lhs_call (gimple stmt, tree lhs,
*** 3907,3913 ****
        varinfo_t vi;
        struct constraint_expr tmpc;
        rhsc = NULL;
!       vi = make_heapvar_for (get_vi_for_tree (lhs), "HEAP");
        /* We delay marking allocated storage global until we know if
           it escapes.  */
        DECL_EXTERNAL (vi->decl) = 0;
--- 3854,3860 ----
        varinfo_t vi;
        struct constraint_expr tmpc;
        rhsc = NULL;
!       vi = make_heapvar ("HEAP");
        /* We delay marking allocated storage global until we know if
           it escapes.  */
        DECL_EXTERNAL (vi->decl) = 0;
*************** create_function_info_for (tree decl, con
*** 5323,5330 ****
        free (tempname);
  
        /* We need sth that can be pointed to for va_start.  */
!       decl = create_tmp_var_raw (ptr_type_node, name);
!       get_var_ann (decl);
  
        argvi = new_var_info (decl, newname);
        argvi->offset = fi_parm_base + num_args;
--- 5270,5276 ----
        free (tempname);
  
        /* We need sth that can be pointed to for va_start.  */
!       decl = build_fake_var_decl (ptr_type_node);
  
        argvi = new_var_info (decl, newname);
        argvi->offset = fi_parm_base + num_args;
*************** intra_create_variable_infos (void)
*** 5587,5609 ****
  	{
  	  struct constraint_expr lhsc, rhsc;
  	  varinfo_t vi;
! 	  tree heapvar = heapvar_lookup (t, 0);
! 	  if (heapvar == NULL_TREE)
! 	    {
! 	      var_ann_t ann;
! 	      heapvar = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (t)),
! 					    "PARM_NOALIAS");
! 	      DECL_EXTERNAL (heapvar) = 1;
! 	      heapvar_insert (t, 0, heapvar);
! 	      ann = get_var_ann (heapvar);
! 	      ann->is_heapvar = 1;
! 	    }
! 	  if (gimple_referenced_vars (cfun))
! 	    add_referenced_var (heapvar);
  	  lhsc.var = get_vi_for_tree (t)->id;
  	  lhsc.type = SCALAR;
  	  lhsc.offset = 0;
! 	  rhsc.var = (vi = get_vi_for_tree (heapvar))->id;
  	  rhsc.type = ADDRESSOF;
  	  rhsc.offset = 0;
  	  process_constraint (new_constraint (lhsc, rhsc));
--- 5533,5545 ----
  	{
  	  struct constraint_expr lhsc, rhsc;
  	  varinfo_t vi;
! 	  tree heapvar = build_fake_var_decl (TREE_TYPE (TREE_TYPE (t)));
! 	  DECL_EXTERNAL (heapvar) = 1;
! 	  vi = get_varinfo (create_variable_info_for (heapvar, "PARM_NOALIAS"));
  	  lhsc.var = get_vi_for_tree (t)->id;
  	  lhsc.type = SCALAR;
  	  lhsc.offset = 0;
! 	  rhsc.var = vi->id;
  	  rhsc.type = ADDRESSOF;
  	  rhsc.offset = 0;
  	  process_constraint (new_constraint (lhsc, rhsc));
*************** init_alias_vars (void)
*** 6371,6376 ****
--- 6307,6314 ----
    shared_bitmap_table = htab_create (511, shared_bitmap_hash,
  				     shared_bitmap_eq, free);
    init_base_vars ();
+ 
+   gcc_obstack_init (&fake_var_decl_obstack);
  }
  
  /* Remove the REF and ADDRESS edges from GRAPH, as well as all the
*************** remove_preds_and_fake_succs (constraint_
*** 6409,6434 ****
    bitmap_obstack_release (&predbitmap_obstack);
  }
  
- /* Initialize the heapvar for statement mapping.  */
- 
- static void
- init_alias_heapvars (void)
- {
-   if (!heapvar_for_stmt)
-     heapvar_for_stmt = htab_create_ggc (11, tree_map_hash, heapvar_map_eq,
- 					NULL);
- }
- 
- /* Delete the heapvar for statement mapping.  */
- 
- void
- delete_alias_heapvars (void)
- {
-   if (heapvar_for_stmt)
-     htab_delete (heapvar_for_stmt);
-   heapvar_for_stmt = NULL;
- }
- 
  /* Solve the constraint set.  */
  
  static void
--- 6347,6352 ----
*************** compute_points_to_sets (void)
*** 6500,6506 ****
    timevar_push (TV_TREE_PTA);
  
    init_alias_vars ();
-   init_alias_heapvars ();
  
    intra_create_variable_infos ();
  
--- 6418,6423 ----
*************** delete_points_to_sets (void)
*** 6651,6656 ****
--- 6568,6575 ----
    VEC_free (varinfo_t, heap, varmap);
    free_alloc_pool (variable_info_pool);
    free_alloc_pool (constraint_pool);
+ 
+   obstack_free (&fake_var_decl_obstack, NULL);
  }
  
  
*************** ipa_pta_execute (void)
*** 6776,6782 ****
  
    in_ipa_mode = 1;
  
-   init_alias_heapvars ();
    init_alias_vars ();
  
    /* Build the constraints.  */
--- 6695,6700 ----
*************** struct simple_ipa_opt_pass pass_ipa_pta
*** 7119,7124 ****
    TODO_update_ssa                       /* todo_flags_finish */
   }
  };
- 
- 
- #include "gt-tree-ssa-structalias.h"
--- 7037,7039 ----



More information about the Gcc-patches mailing list