[sa]: Revert partial def stuff, use fake variables instead

Zdenek Dvorak rakdver@atrey.karlin.mff.cuni.cz
Thu Dec 23 02:41:00 GMT 2004


Hello,

> It may be easiest to just have an external interface for creating tags 
> with a known points-to set, and taking care of all the magic 
> involved inside tree-ssa-alias, which knows how to do this stuff right.

here is some attempt (see the set_single_alias function).  It does not
quite work yet, but already there a few things that quite surprised me
(some of the observations below obviously may be wrong, so feel free
to correct me if I misunderstood something):

1) both pt_vars in ptr_info_def and aliases in name_mem_tag seem to
   contain exactly the same information.  The former seems to only be
   used internally by alias analysis, while the later is much more
   bloated (varray) version used mainly by tree-ssa-operands.

2) To make things even more funny, we require that the ssa names with
   the same pt_vars also have the same tag.  This forces the function
   to look through all other pointers, and automatically causes a
   quadratic behavior in any code that would be foolish enough to try
   to use it.  I had a look at the similar function at tcb advertised
   by Diego (add_type_alias) that tries to work with type tags of the
   pointers instead of the name ones, and seems to have exactly the
   same problem.

So far I did not notice any reason for having NMT's at all -- it seems
to me that everything would work just fine (and much more efficiently)
if tree-ssa-operands just looked at pt_vars instead.  What do I miss?

Zdenek

Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-flow.h,v
retrieving revision 2.75
diff -c -3 -p -r2.75 tree-flow.h
*** tree-flow.h	10 Dec 2004 21:54:41 -0000	2.75
--- tree-flow.h	23 Dec 2004 02:23:42 -0000
*************** extern void dump_points_to_info_for (FIL
*** 562,567 ****
--- 562,569 ----
  extern void debug_points_to_info_for (tree);
  extern bool may_be_aliased (tree);
  extern struct ptr_info_def *get_ptr_info (tree);
+ extern void copy_alias_info (tree, tree);
+ extern void set_single_alias (tree, tree);
  
  /* Call-back function for walk_use_def_chains().  At each reaching
     definition, a function with this prototype is called.  */
Index: tree-ssa-alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-alias.c,v
retrieving revision 2.64
diff -c -3 -p -r2.64 tree-ssa-alias.c
*** tree-ssa-alias.c	20 Dec 2004 18:18:28 -0000	2.64
--- tree-ssa-alias.c	23 Dec 2004 02:23:42 -0000
*************** may_be_aliased (tree var)
*** 2519,2521 ****
--- 2519,2605 ----
    return true;
  }
  
+ /* Copy the may alias information from pointer FROM to pointer TO.  */
+ 
+ void
+ copy_alias_info (tree to, tree from)
+ {
+   struct ptr_info_def *pi, *npi;
+   tree tvar, fvar;
+  
+   pi = get_ptr_info (from);
+   npi = get_ptr_info (to);
+   memcpy (npi, pi, sizeof (struct ptr_info_def));
+   if (pi->pt_vars)
+     {
+       npi->pt_vars = BITMAP_GGC_ALLOC ();
+       bitmap_copy (npi->pt_vars, pi->pt_vars);
+     }
+ 
+   tvar = SSA_NAME_VAR (to);
+   fvar = SSA_NAME_VAR (from);
+   var_ann (tvar)->type_mem_tag = var_ann (fvar)->type_mem_tag;
+ }
+ 
+ /* Record that TO may only point to VAR.  */
+ 
+ void
+ set_single_alias (tree to, tree var)
+ {
+   struct ptr_info_def *pi = get_ptr_info (to), *api;
+   varray_type aliases = var_ann (var)->may_aliases;
+   tree nmt, al, name;
+   unsigned i;
+ 
+   if (is_global_var (var))
+     pi->pt_global_mem = 1;
+ 
+   pi->pt_vars = BITMAP_GGC_ALLOC ();
+ 
+   if (!aliases)
+     bitmap_set_bit (pi->pt_vars, var_ann (var)->uid);
+   else
+     {
+       for (i = 0; i < VARRAY_ACTIVE_SIZE (aliases); i++)
+ 	{
+ 	  al = VARRAY_TREE (aliases, i);
+ 	  bitmap_set_bit (pi->pt_vars, var_ann (al)->uid);
+ 	}
+     }
+ 
+   /* Find a pointer with the same points-to set if available.  */
+   nmt = NULL_TREE;
+   for (i = 0; i < num_ssa_names; i++)
+     {
+       name = ssa_name (i);
+       if (!name)
+ 	continue;
+       api = SSA_NAME_PTR_INFO (name);
+       if (!api || !api->name_mem_tag || !api->pt_vars)
+ 	continue;
+ 
+       if (bitmap_equal_p (pi->pt_vars, api->pt_vars))
+ 	{
+ 	  nmt = api->name_mem_tag;
+ 	  break;
+ 	};
+     }
+ 
+   if (!nmt)
+     {
+       /* Create a new nmt if not found.  */
+       nmt = get_nmt_for (to);
+       pi->name_mem_tag = nmt;
+ 
+       if (!aliases)
+ 	add_may_alias (nmt, var);
+       else
+ 	{
+ 	  for (i = 0; i < VARRAY_ACTIVE_SIZE (aliases); i++)
+ 	    {
+ 	      al = VARRAY_TREE (aliases, i);
+ 	      add_may_alias (nmt, al);
+ 	    }
+ 	}
+     }
+ }
Index: tree-ssa-loop-ivopts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop-ivopts.c,v
retrieving revision 2.37
diff -c -3 -p -r2.37 tree-ssa-loop-ivopts.c
*** tree-ssa-loop-ivopts.c	20 Dec 2004 03:11:52 -0000	2.37
--- tree-ssa-loop-ivopts.c	23 Dec 2004 02:23:43 -0000
*************** unshare_and_remove_ssa_names (tree ref)
*** 4565,4610 ****
  static void
  rewrite_address_base (block_stmt_iterator *bsi, tree *op, tree with)
  {
!   tree bvar, var, new_var, new_name, copy, name;
    tree orig;
  
!   var = bvar = get_base_address (*op);
  
!   if (!var || TREE_CODE (with) != SSA_NAME)
      goto do_rewrite;
  
!   gcc_assert (TREE_CODE (var) != ALIGN_INDIRECT_REF);
!   gcc_assert (TREE_CODE (var) != MISALIGNED_INDIRECT_REF);
!   if (TREE_CODE (var) == INDIRECT_REF)
!     var = TREE_OPERAND (var, 0);
!   if (TREE_CODE (var) == SSA_NAME)
      {
!       name = var;
!       var = SSA_NAME_VAR (var);
      }
-   else if (DECL_P (var))
-     name = NULL_TREE;
    else
!     goto do_rewrite;
!     
!   if (var_ann (var)->type_mem_tag)
!     var = var_ann (var)->type_mem_tag;
! 
!   /* We need to add a memory tag for the variable.  But we do not want
!      to add it to the temporary used for the computations, since this leads
!      to problems in redundancy elimination when there are common parts
!      in two computations referring to the different arrays.  So we copy
!      the variable to a new temporary.  */
    copy = build2 (MODIFY_EXPR, void_type_node, NULL_TREE, with);
    if (name)
!     new_name = duplicate_ssa_name (name, copy);
    else
!     {
!       new_var = create_tmp_var (TREE_TYPE (with), "ruatmp");
!       add_referenced_tmp_var (new_var);
!       var_ann (new_var)->type_mem_tag = var;
!       new_name = make_ssa_name (new_var, copy);
!     }
    TREE_OPERAND (copy, 0) = new_name;
    bsi_insert_before (bsi, copy, BSI_SAME_STMT);
    with = new_name;
--- 4565,4610 ----
  static void
  rewrite_address_base (block_stmt_iterator *bsi, tree *op, tree with)
  {
!   tree base, new_var, new_name, copy, name;
    tree orig;
  
!   base = get_base_address (*op);
  
!   if (!base || TREE_CODE (with) != SSA_NAME)
      goto do_rewrite;
  
!   gcc_assert (TREE_CODE (base) != ALIGN_INDIRECT_REF);
!   gcc_assert (TREE_CODE (base) != MISALIGNED_INDIRECT_REF);
! 
!   if (TREE_CODE (base) == INDIRECT_REF)
!     {
!       name = TREE_OPERAND (base, 0);
!       gcc_assert (TREE_CODE (name) == SSA_NAME);
!     }
!   else if (SSA_VAR_P (base))
      {
!       gcc_assert (TREE_CODE (base) != SSA_NAME);
!       name = NULL;
      }
    else
!     {
!       /* Constant strings and aggregates.  */
!       gcc_assert (TREE_CODE (base) == STRING_CST
! 		  || TREE_CODE (base) == CONSTRUCTOR);
!       goto do_rewrite;
!     }
! 
!   /* Prepare a pointer with the appropriate aliasing info and copy the
!      address to it.  */
    copy = build2 (MODIFY_EXPR, void_type_node, NULL_TREE, with);
+   new_var = create_tmp_var (TREE_TYPE (with), "ruatmp");
+   add_referenced_tmp_var (new_var);
+   new_name = make_ssa_name (new_var, copy);
    if (name)
!     copy_alias_info (new_name, name);
    else
!     set_single_alias (new_name, base);
! 
    TREE_OPERAND (copy, 0) = new_name;
    bsi_insert_before (bsi, copy, BSI_SAME_STMT);
    with = new_name;
*************** do_rewrite:
*** 4622,4628 ****
  
    *op = build1 (INDIRECT_REF, TREE_TYPE (*op), with);
  
!   /* Record the original reference, for purposes of alias analysis.  */
    REF_ORIGINAL (*op) = orig;
  }
  
--- 4622,4628 ----
  
    *op = build1 (INDIRECT_REF, TREE_TYPE (*op), with);
  
!   /* Record the original reference, for purposes of rtl alias analysis.  */
    REF_ORIGINAL (*op) = orig;
  }
  



More information about the Gcc-patches mailing list