[PATCH]: alias slowdown patch

Daniel Berlin dberlin@dberlin.org
Tue Nov 21 15:57:00 GMT 2006


Here ya go.  This should fix your time and memory issues.

For cplusplus_grammar.ii i get:

 tree PTA              :   1.76 ( 3%) usr   0.09 ( 1%) sys   2.03 (
2%) wall    3591 kB ( 1%) ggc
 tree alias analysis   :   7.93 (12%) usr   1.26 ( 9%) sys   9.95
(11%) wall    3986 kB ( 1%) ggc


Note that the remaining "tree alias analysis" time is actually copying
the bitmap sets from PTA to SSA_NAME_PTR_INFO, 5 times, for 100000
variables.  We then take these bitmaps from SSA_NAME_PTR_INFO, and
explicitly enumerate them into vectors in the form of add_may_alias.

This is a bit dumb.

The second worst part is that we know only about 30000 of them have
different points-to sets, but there is no way to explain this to what
is asking us.

While fixing the timing issue, i discovered serious memory usage
issues that occur if we try to compute the real points-to sets instead
of punting (which is what i've really done with this patch).
In fact, I got it to compute the complete points-to sets in 3 seconds,
using 50 meg of memory.
However, we then take these sets, and explicitly enumerate them into
these two places I mentioned above, and waste 800 meg of memory
keeping them around.

So for now, i have punted and we don't compute the points-to set for
global variables anymore to avoid this, but this is really a kludge
(if you were to say, move the large table into the function, you would
hit the same problem)

I want to move us to something other than sparse bitmaps for points-to
(BDD's), because they are about 100x more memory efficient (it is like
sharing all the same bits of the bitmaps for all the points-to sets at
once), but real overall memory savings will mean we are going to have
to stop explicitly enumerating *all* of our points-to sets into
bitmaps at once during alias analysis like we do now.
It is perfectly fine and fast to enumerate the set for one variable at
a time from the BDD (it's cached), as long as we stop trying to keep
the bitmaps around.

As our points-to sets get bigger (which is inveitable if we have to
handle codes like this, and move to interprocedural analysis), this is
only going to get worse and worse.

I can make it fast, but without changing the way we postprocess these
sets, i can't make it memory efficient.

Thoughts?

(I will commit this patch to 4.2 branch and mainline once it finishes
bootstrap/regtesting. It already passed bootstrap once, though that
version had a few should-be-cosmetic differences than this one, just
to CYA :P )

--Dan

2006-11-21  Daniel Berlin  <dberlin@dberlin.org>

	* tree-ssa-structalias.c: Update comments.
	(var_escaped_vars): Remove.
	(escaped_vars_tree): Remove.
	(escaped_vars_id): Remove.
	(constraint_expr_type): Add INCLUDES.
	(graph_size): Removed.
	(dump_constraint): Support INCLUDES.
	(build_constraint_graph): Ditto.
	(collapse_nodes): Add merge_solutions argument.
	Don't merge attributes.
	(process_unification_queue): Just use collapse_nodes.
	(perform_var_substitution): Update call to collapse_nodes.
	(get_constraint_exp_from_ssa_var): Use INCLUDES.
	(process_constraint): Fix non-field sensitive handling
	Handle includes.
	(get_constraint_for): Use INCLUDES.
	(make_constraint_from_escaped): Use nonlocal_vars_id.
	(make_constraint_to_escaped): Removed.
	(find_global_initializers): Removed.
	(create_variable_info_for): Do not make constraints to escaped
	vars anymore.
	(dump_solution_for_var): Don't print out the equivalent points-to
	sets, just use the name of the variable it shares it with.
	(intra_create_variable_infos): Use INCLUDES.
	Move initialization of nonlocal variable to init_base_vars.
	(init_base_vars): Init nonlocal variable here.
	Remove escaped_vars initialization.
	(find_escape_constraints): Removed.
	(delete_points_to_sets): Remove dead code.
-------------- next part --------------
--- gcc/tree-ssa-structalias.c	(/mirror/gcc-trunk)	(revision 173)
+++ gcc/tree-ssa-structalias.c	(/local/gcc-clean)	(revision 173)
@@ -72,9 +72,10 @@ Foundation, Inc., 51 Franklin Street, Fi
    of C Code in a Second" by ""Nevin Heintze and Olivier Tardieu" at
    http://citeseer.ist.psu.edu/heintze01ultrafast.html 
 
-   There are three types of constraint expressions, DEREF, ADDRESSOF, and
-   SCALAR.  Each constraint expression consists of a constraint type,
-   a variable, and an offset.  
+   There are three types of real constraint expressions, DEREF,
+   ADDRESSOF, and SCALAR.  There is one type of fake constraint
+   expression, called INCLUDES.  Each constraint expression consists
+   of a constraint type, a variable, and an offset.
    
    SCALAR is a constraint expression type used to represent x, whether
    it appears on the LHS or the RHS of a statement.
@@ -82,6 +83,10 @@ Foundation, Inc., 51 Franklin Street, Fi
    it appears on the LHS or the RHS of a statement. 
    ADDRESSOF is a constraint expression used to represent &x, whether
    it appears on the LHS or the RHS of a statement.
+   INCLUDES is a constraint expression type used to represent just a
+   setting of a bit in the points-to set without having the address
+   taken.  It exists mainly for abstraction sake, and is used for
+   initializing fake variables like the ESCAPED_VARS set.
    
    Each pointer variable in the program is assigned an integer id, and
    each field of a structure variable is assigned an integer id as well.
@@ -322,14 +327,8 @@ static varinfo_t var_integer;
 static tree integer_tree;
 static unsigned int integer_id;
 
-/* Variable that represents escaped variables.  This is used to give
-   incoming pointer variables a better set than ANYTHING.  */
-static varinfo_t var_escaped_vars;
-static tree escaped_vars_tree;
-static unsigned int escaped_vars_id;
-
-/* Variable that represents non-local variables before we expand it to
-   one for each type.  */
+/* Variable that represents non-local variables.  */
+static varinfo_t var_nonlocal;
 static unsigned int nonlocal_vars_id;
 
 /* Lookup a heap var for FROM, and return it if we find one.  */
@@ -391,7 +390,7 @@ new_var_info (tree t, unsigned int id, c
   return ret;
 }
 
-typedef enum {SCALAR, DEREF, ADDRESSOF} constraint_expr_type;
+typedef enum {SCALAR, DEREF, ADDRESSOF, INCLUDES} constraint_expr_type;
 
 /* An expression that appears in a constraint.  */
 
@@ -486,7 +485,6 @@ struct constraint_graph
 typedef struct constraint_graph *constraint_graph_t;
 
 static constraint_graph_t graph;
-static int graph_size;
 
 /* Create a new constraint consisting of LHS and RHS expressions.  */
 
@@ -508,7 +506,7 @@ dump_constraint (FILE *file, constraint_
   if (c->lhs.type == ADDRESSOF)
     fprintf (file, "&");
   else if (c->lhs.type == DEREF)
-    fprintf (file, "*");  
+    fprintf (file, "*");
   fprintf (file, "%s", get_varinfo_fc (c->lhs.var)->name);
   if (c->lhs.offset != 0)
     fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->lhs.offset);
@@ -517,9 +515,13 @@ dump_constraint (FILE *file, constraint_
     fprintf (file, "&");
   else if (c->rhs.type == DEREF)
     fprintf (file, "*");
+  else if (c->rhs.type == INCLUDES)
+    fprintf (file, "{");
   fprintf (file, "%s", get_varinfo_fc (c->rhs.var)->name);
   if (c->rhs.offset != 0)
     fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->rhs.offset);
+  if (c->rhs.type == INCLUDES)
+    fprintf (file, "}");
   fprintf (file, "\n");
 }
 
@@ -1200,6 +1202,7 @@ build_constraint_graph (void)
 {
   int i = 0;
   constraint_t c;
+  int graph_size;
 
   graph = XNEW (struct constraint_graph);
   graph_size = VEC_length (varinfo_t, varmap) + 1;
@@ -1227,7 +1230,7 @@ build_constraint_graph (void)
 	  if (!(get_varinfo (lhsvar)->is_special_var))
 	    insert_into_complex (rhsvar, c);
 	}
-      else if (rhs.type == ADDRESSOF)
+      else if (rhs.type == ADDRESSOF || rhs.type == INCLUDES)
 	{
 	  /* x = &y */
 	  bitmap_set_bit (get_varinfo (lhsvar)->solution, rhsvar);
@@ -1325,26 +1328,33 @@ scc_visit (constraint_graph_t graph, str
 }
 
 
-/* Collapse two variables into one variable.  */
+/* Collapse two variables into one variable, merging solutions if
+   requested.  */
 
 static void
-collapse_nodes (constraint_graph_t graph, unsigned int to, unsigned int from)
+collapse_nodes (constraint_graph_t graph, unsigned int to, unsigned int from,
+		bool merge_solutions)
 {
   bitmap tosol, fromsol;
 
-  condense_varmap_nodes (to, from);
-  tosol = get_varinfo (to)->solution;
-  fromsol = get_varinfo (from)->solution;
-  bitmap_ior_into (tosol, fromsol);
   merge_graph_nodes (graph, to, from);
+  condense_varmap_nodes (to, from);
+  if (merge_solutions)
+    {
+      tosol = get_varinfo (to)->solution;
+      fromsol = get_varinfo (from)->solution;
+      bitmap_ior_into (tosol, fromsol);
+      BITMAP_FREE (fromsol);
+    }
 
   if (valid_graph_edge (graph, to, to))
     {
-      if (graph->zero_weight_preds[to])
+      if (graph->zero_weight_succs[to])
 	{
 	  bitmap_clear_bit (graph->zero_weight_preds[to], to);
 	  bitmap_clear_bit (graph->zero_weight_succs[to], to);
 	}
+
       if (valid_weighted_graph_edge (graph, to, to))
 	{
 	  bitmap weights = *(get_graph_weights (graph, to, to));
@@ -1352,9 +1362,6 @@ collapse_nodes (constraint_graph_t graph
 	    erase_graph_self_edge (graph, to);
 	}
     }
-  BITMAP_FREE (fromsol);
-  get_varinfo (to)->address_taken |= get_varinfo (from)->address_taken;
-  get_varinfo (to)->indirect_target |= get_varinfo (from)->indirect_target;
 }
 
 
@@ -1409,8 +1416,7 @@ process_unification_queue (constraint_gr
       else
 	stats.unified_vars_static++;
       bitmap_ior_into (tmp, get_varinfo (tounify)->solution);
-      merge_graph_nodes (graph, n, tounify);
-      condense_varmap_nodes (n, tounify);
+      collapse_nodes (graph, n, tounify, false);
       
       if (update_changed && TEST_BIT (changed, tounify))
 	{
@@ -1444,22 +1450,6 @@ process_unification_queue (constraint_gr
 		}
 	    }
 	  bitmap_clear (tmp);
-
-	  if (valid_graph_edge (graph, n, n))
-	    {
-	      if (graph->zero_weight_succs[n])
-		{
-		  if (graph->zero_weight_preds[n])
-		    bitmap_clear_bit (graph->zero_weight_preds[n], n);
-		  bitmap_clear_bit (graph->zero_weight_succs[n], n);
-		}
-	      if (valid_weighted_graph_edge (graph, n, n))
-		{
-		  bitmap weights = *(get_graph_weights (graph, n, n));
-		  if (!weights || bitmap_empty_p (weights))
-		    erase_graph_self_edge (graph, n);
-		}
-	    }
 	}
     }
   BITMAP_FREE (tmp);
@@ -1878,7 +1868,7 @@ perform_var_substitution (constraint_gra
       bitmap tmp;
       unsigned int k;
       bitmap_iterator bi;
-
+      
       /* We can't eliminate things whose address is taken, or which is
 	 the target of a dereference.  */
       if (vi->address_taken || vi->indirect_target)
@@ -1976,7 +1966,7 @@ perform_var_substitution (constraint_gra
 	{
 	  /* Found an equivalence */
 	  get_varinfo (i)->node = root;
-	  collapse_nodes (graph, root, i);
+	  collapse_nodes (graph, root, i, true);
 	  if (dump_file && (dump_flags & TDF_DETAILS))
 	    fprintf (dump_file, "Collapsing %s into %s\n",
 		     get_varinfo (i)->name,
@@ -2266,7 +2256,7 @@ get_constraint_exp_from_ssa_var (tree t)
      say it points to readonly memory instead.  */
   if (cexpr.var == anything_id && TREE_READONLY (t))
     {
-      cexpr.type = ADDRESSOF;
+      cexpr.type = INCLUDES;
       cexpr.var = readonly_id;
     }
     
@@ -2285,18 +2275,27 @@ process_constraint (constraint_t t)
   
   gcc_assert (rhs.var < VEC_length (varinfo_t, varmap));
   gcc_assert (lhs.var < VEC_length (varinfo_t, varmap));
-
+  
+  gcc_assert (lhs.type != INCLUDES);
+  
   if (lhs.type == DEREF)
     get_varinfo (lhs.var)->directly_dereferenced = true;
   if (rhs.type == DEREF)
     get_varinfo (rhs.var)->directly_dereferenced = true;
+
+  if (!use_field_sensitive)
+    {
+      t->rhs.offset = 0;
+      t->lhs.offset = 0;
+    }
   
   /* ANYTHING == ANYTHING is pointless.  */
   if (lhs.var == anything_id && rhs.var == anything_id)
     return;
 
   /* If we have &ANYTHING = something, convert to SOMETHING = &ANYTHING) */
-  else if (lhs.var == anything_id && lhs.type == ADDRESSOF)
+  else if (lhs.var == anything_id 
+	   && (lhs.type == INCLUDES || lhs.type == ADDRESSOF))
     {
       rhs = t->lhs;
       t->lhs = t->rhs;
@@ -2327,11 +2326,8 @@ process_constraint (constraint_t t)
       varinfo_t vi;
       gcc_assert (rhs.offset == 0);
       
-      /* No need to mark address taken simply because of escaped vars
-	 constraints.  */
-      if (lhs.var != escaped_vars_id)
-	for (vi = get_varinfo (rhs.var); vi != NULL; vi = vi->next)
-	  vi->address_taken = true;
+      for (vi = get_varinfo (rhs.var); vi != NULL; vi = vi->next)
+	vi->address_taken = true;
 
       VEC_safe_push (constraint_t, heap, constraints, t);
     }
@@ -2655,14 +2651,14 @@ get_constraint_for (tree t, VEC (ce_s, h
 		vi = get_varinfo (temp.var);
 		vi->is_artificial_var = 1;
 		vi->is_heap_var = 1;
-		temp.type = ADDRESSOF;
+		temp.type = INCLUDES;
 		temp.offset = 0;
 		VEC_safe_push (ce_s, heap, *results, &temp);
 		return;
 	      }
 	    else
 	      {
-		temp.var = escaped_vars_id;
+		temp.var = anything_id;
 		temp.type = SCALAR;
 		temp.offset = 0;
 		VEC_safe_push (ce_s, heap, *results, &temp);
@@ -3817,24 +3813,9 @@ make_constraint_from_escaped (varinfo_t 
   lhs.offset = 0;
   lhs.type = SCALAR;
   
-  rhs.var = escaped_vars_id;
+  rhs.var = nonlocal_vars_id;
   rhs.offset = 0;
-  rhs.type = SCALAR;
-  process_constraint (new_constraint (lhs, rhs));
-}
-
-/* Create a constraint to the ESCAPED_VARS variable from constraint
-   expression RHS. */
-
-static void
-make_constraint_to_escaped (struct constraint_expr rhs)
-{
-  struct constraint_expr lhs;
-  
-  lhs.var = escaped_vars_id;
-  lhs.offset = 0;
-  lhs.type = SCALAR;
-
+  rhs.type = INCLUDES;
   process_constraint (new_constraint (lhs, rhs));
 }
 
@@ -3988,59 +3969,6 @@ check_for_overlaps (VEC (fieldoff_s,heap
   return false;
 }
 
-/* This function is called through walk_tree to walk global
-   initializers looking for constraints we need to add to the
-   constraint list.  */
-
-static tree
-find_global_initializers (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
-			  void *viv)
-{
-  varinfo_t vi = (varinfo_t)viv;
-  tree t = *tp;
-
-  switch (TREE_CODE (t))
-    {
-      /* Dereferences and addressofs are the only important things
-	 here, and i don't even remember if dereferences are legal
-	 here in initializers.  */
-    case INDIRECT_REF:
-    case ADDR_EXPR:
-      {
-	struct constraint_expr *c;
-	size_t i;
-	
-	VEC(ce_s, heap) *rhsc = NULL;
-	get_constraint_for (t, &rhsc);
-	for (i = 0; VEC_iterate (ce_s, rhsc, i, c); i++)
-	  {
-	    struct constraint_expr lhs;
-	    
-	    lhs.var = vi->id;
-	    lhs.type = SCALAR;
-	    lhs.offset = 0;
-	    process_constraint (new_constraint (lhs, *c));
-	  }
-
-	VEC_free (ce_s, heap, rhsc);
-      }
-      break;
-    case VAR_DECL:
-      /* We might not have walked this because we skip
-	 DECL_EXTERNALs during the initial scan.  */
-      if (referenced_vars)
-	{
-	  get_var_ann (t);
-	  if (referenced_var_check_and_insert (t))
-	    mark_sym_for_renaming (t);
-	}
-      break;
-    default:
-      break;
-    }
-  return NULL_TREE;
-}
-
 /* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
    This will also create any varinfo structures necessary for fields
    of DECL.  */
@@ -4098,27 +4026,7 @@ create_variable_info_for (tree decl, con
   insert_id_for_tree (vi->decl, index);  
   VEC_safe_push (varinfo_t, heap, varmap, vi);
   if (is_global && (!flag_whole_program || !in_ipa_mode))
-    {
-      make_constraint_from_escaped (vi);
-
-      /* If the variable can't be aliased, there is no point in
-	 putting it in the set of nonlocal vars.  */
-      if (may_be_aliased (vi->decl))
-	{
-	  struct constraint_expr rhs;
-	  rhs.var = index;
-	  rhs.type = ADDRESSOF;
-	  rhs.offset = 0;
-	  make_constraint_to_escaped (rhs);
-	} 
-
-      if (TREE_CODE (decl) != FUNCTION_DECL && DECL_INITIAL (decl))
-	{
-	  walk_tree_without_duplicates (&DECL_INITIAL (decl),
-					find_global_initializers,
-					(void *)vi);
-	}
-    }
+    make_constraint_from_escaped (vi);
 
   stats.total_vars++;
   if (use_field_sensitive 
@@ -4198,20 +4106,7 @@ create_variable_info_for (tree decl, con
 	  insert_into_field_list (vi, newvi);
 	  VEC_safe_push (varinfo_t, heap, varmap, newvi);
 	  if (is_global && (!flag_whole_program || !in_ipa_mode))
-	    {
-	      /* If the variable can't be aliased, there is no point in
-		 putting it in the set of nonlocal vars.  */
-	      if (may_be_aliased (vi->decl))
-		{
-		  struct constraint_expr rhs;
-	      
-		  rhs.var = newindex;
-		  rhs.type = ADDRESSOF;
-		  rhs.offset = 0;
-		  make_constraint_to_escaped (rhs);
-		} 
 	      make_constraint_from_escaped (newvi);
-	    }
 	  
 	  stats.total_vars++;
 	}
@@ -4229,12 +4124,20 @@ dump_solution_for_var (FILE *file, unsig
   unsigned int i;
   bitmap_iterator bi; 
   
-  fprintf (file, "%s = { ", vi->name);
-  EXECUTE_IF_SET_IN_BITMAP (get_varinfo (vi->node)->solution, 0, i, bi)
+  if (vi->node != var)
+    {
+      varinfo_t vipt = get_varinfo (vi->node);
+      fprintf (file, "%s = same as %s\n", vi->name, vipt->name);
+    }
+  else
     {
-      fprintf (file, "%s ", get_varinfo (i)->name);
+      fprintf (file, "%s = { ", vi->name);
+      EXECUTE_IF_SET_IN_BITMAP (get_varinfo (vi->node)->solution, 0, i, bi)
+	{
+	  fprintf (file, "%s ", get_varinfo (i)->name);
+	}
+      fprintf (file, "}\n");
     }
-  fprintf (file, "}\n");
 }
 
 /* Print the points-to solution for VAR to stdout.  */
@@ -4253,7 +4156,6 @@ intra_create_variable_infos (void)
 {
   tree t;
   struct constraint_expr lhs, rhs;
-  varinfo_t nonlocal_vi;
 
   /* For each incoming pointer argument arg, ARG = ESCAPED_VARS or a
      dummy variable if flag_argument_noalias > 2. */
@@ -4296,7 +4198,7 @@ intra_create_variable_infos (void)
 	  vi->is_artificial_var = 1;
 	  vi->is_heap_var = 1;
 	  rhs.var = id;
-	  rhs.type = ADDRESSOF;
+	  rhs.type = INCLUDES;
 	  rhs.offset = 0;
           for (p = get_varinfo (lhs.var); p; p = p->next)
 	    {
@@ -4311,28 +4213,6 @@ intra_create_variable_infos (void)
 	    make_constraint_from_escaped (p);
 	}
     }
-  if (!nonlocal_all)
-    nonlocal_all = create_nonlocal_var (void_type_node);
-
-  /* Create variable info for the nonlocal var if it does not
-     exist.  */
-  nonlocal_vars_id = create_variable_info_for (nonlocal_all,
-					       get_name (nonlocal_all));
-  nonlocal_vi = get_varinfo (nonlocal_vars_id);
-  nonlocal_vi->is_artificial_var = 1;
-  nonlocal_vi->is_heap_var = 1; 
-  nonlocal_vi->is_unknown_size_var = 1;
-  nonlocal_vi->directly_dereferenced = true;
-
-  rhs.var = nonlocal_vars_id;
-  rhs.type = ADDRESSOF;
-  rhs.offset = 0;
-  
-  lhs.var = escaped_vars_id;
-  lhs.type = SCALAR;
-  lhs.offset = 0;
-  
-  process_constraint (new_constraint (lhs, rhs));
 }
 
 /* Set bits in INTO corresponding to the variable uids in solution set
@@ -4514,7 +4394,7 @@ dump_sa_points_to_info (FILE *outfile)
       fprintf (outfile, "Iterations:               %d\n", stats.iterations);
       fprintf (outfile, "Number of edges:          %d\n", stats.num_edges);
     }
-
+  
   for (i = 0; i < VEC_length (varinfo_t, varmap); i++)
     dump_solution_for_var (outfile, i);
 }
@@ -4570,7 +4450,7 @@ init_base_vars (void)
   lhs.type = SCALAR;
   lhs.var = anything_id;
   lhs.offset = 0;
-  rhs.type = ADDRESSOF;
+  rhs.type = INCLUDES;
   rhs.var = anything_id;
   rhs.offset = 0;
   var_anything->address_taken = true;
@@ -4601,7 +4481,7 @@ init_base_vars (void)
   lhs.type = SCALAR;
   lhs.var = readonly_id;
   lhs.offset = 0;
-  rhs.type = ADDRESSOF;
+  rhs.type = INCLUDES;
   rhs.var = anything_id;
   rhs.offset = 0;
   
@@ -4626,30 +4506,29 @@ init_base_vars (void)
   lhs.type = SCALAR;
   lhs.var = integer_id;
   lhs.offset = 0;
-  rhs.type = ADDRESSOF;
+  rhs.type = INCLUDES;
   rhs.var = anything_id;
   rhs.offset = 0;
   process_constraint (new_constraint (lhs, rhs));
-  
-  /* Create the ESCAPED_VARS variable used to represent variables that
-     escape this function.  */
-  escaped_vars_tree = create_tmp_var_raw (void_type_node, "ESCAPED_VARS");
-  var_escaped_vars = new_var_info (escaped_vars_tree, 4, "ESCAPED_VARS", 4);
-  insert_id_for_tree (escaped_vars_tree, 4);
-  var_escaped_vars->is_artificial_var = 1;
-  var_escaped_vars->size = ~0;
-  var_escaped_vars->fullsize = ~0;
-  var_escaped_vars->offset = 0;
-  var_escaped_vars->next = NULL;
-  escaped_vars_id = 4;
-  VEC_safe_push (varinfo_t, heap, varmap, var_escaped_vars);
 
-  /* ESCAPED_VARS = *ESCAPED_VARS */
+  if (!nonlocal_all)
+    nonlocal_all = create_nonlocal_var (void_type_node);
+
+  /* Create variable info for the nonlocal var if it does not
+     exist.  */
+  nonlocal_vars_id = create_variable_info_for (nonlocal_all,
+					       get_name (nonlocal_all));
+  var_nonlocal = get_varinfo (nonlocal_vars_id);
+  var_nonlocal->is_artificial_var = 1;
+  var_nonlocal->is_heap_var = 1; 
+  var_nonlocal->is_unknown_size_var = 1;
+  var_nonlocal->directly_dereferenced = true;  
+
   lhs.type = SCALAR;
-  lhs.var = escaped_vars_id;
+  lhs.var = nonlocal_vars_id;
   lhs.offset = 0;
-  rhs.type = DEREF;
-  rhs.var = escaped_vars_id;
+  rhs.type = INCLUDES;
+  rhs.var = nonlocal_vars_id;
   rhs.offset = 0;
   process_constraint (new_constraint (lhs, rhs));
   
@@ -4678,105 +4557,6 @@ init_alias_vars (void)
   init_base_vars ();
 }
 
-/* Given a statement STMT, generate necessary constraints to
-   escaped_vars for the escaping variables.  */
-
-static void
-find_escape_constraints (tree stmt)
-{
-  enum escape_type stmt_escape_type = is_escape_site (stmt);
-  tree rhs;
-  VEC(ce_s, heap) *rhsc = NULL;
-  struct constraint_expr *c;
-  size_t i;
-
-  if (stmt_escape_type == NO_ESCAPE)
-    return;
-
-  if (TREE_CODE (stmt) == RETURN_EXPR)
-    {
-      /* Returns are either bare, with an embedded MODIFY_EXPR, or
-	 just a plain old expression.  */
-      if (!TREE_OPERAND (stmt, 0))
-	return;
-      if (TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR)
-	rhs = TREE_OPERAND (TREE_OPERAND (stmt, 0), 1);
-      else
-	rhs = TREE_OPERAND (stmt, 0);
-
-      get_constraint_for (rhs, &rhsc);
-      for (i = 0; VEC_iterate (ce_s, rhsc, i, c); i++)
-	make_constraint_to_escaped (*c);
-      VEC_free (ce_s, heap, rhsc);
-      return;
-    }
-  else if (TREE_CODE (stmt) == ASM_EXPR)
-    {
-      /* Whatever the inputs of the ASM are, escape.  */
-      tree arg;
-
-      for (arg = ASM_INPUTS (stmt); arg; arg = TREE_CHAIN (arg))
-	{
-	  rhsc = NULL;
-	  get_constraint_for (TREE_VALUE (arg), &rhsc);
-	  for (i = 0; VEC_iterate (ce_s, rhsc, i, c); i++)
-	    make_constraint_to_escaped (*c);
-	  VEC_free (ce_s, heap, rhsc);
-	}
-      return;
-    }
-  else if (TREE_CODE (stmt) == CALL_EXPR
-	   || (TREE_CODE (stmt) == MODIFY_EXPR
-	       && TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR))
-    {
-      /* Calls cause all of the arguments passed in to escape.  */
-      tree arg;
-
-      if (TREE_CODE (stmt) == MODIFY_EXPR)
-	stmt = TREE_OPERAND (stmt, 1);
-      for (arg = TREE_OPERAND (stmt, 1); arg; arg = TREE_CHAIN (arg))
-	{
-	  if (POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arg))))
-	    {
-	      rhsc = NULL;
-	      get_constraint_for (TREE_VALUE (arg), &rhsc);
-	      for (i = 0; VEC_iterate (ce_s, rhsc, i, c); i++)
-		make_constraint_to_escaped (*c);
-	      VEC_free (ce_s, heap, rhsc);
-	    }
-	}
-      return;
-    }
-  else
-    {
-      gcc_assert (TREE_CODE (stmt) == MODIFY_EXPR);
-    }
-
-  gcc_assert (stmt_escape_type == ESCAPE_BAD_CAST
-	      || stmt_escape_type == ESCAPE_STORED_IN_GLOBAL
-	      || stmt_escape_type == ESCAPE_UNKNOWN);
-  rhs = TREE_OPERAND (stmt, 1);
-  
-  /* Look through casts for the real escaping variable.
-     Constants don't really escape, so ignore them.
-     Otherwise, whatever escapes must be on our RHS.  */
-  if (TREE_CODE (rhs) == NOP_EXPR
-      || TREE_CODE (rhs) == CONVERT_EXPR
-      || TREE_CODE (rhs) == NON_LVALUE_EXPR)
-    {
-      get_constraint_for (TREE_OPERAND (rhs, 0), &rhsc);
-    }
-  else if (CONSTANT_CLASS_P (rhs))
-    return;
-  else
-    {
-      get_constraint_for (rhs, &rhsc);
-    }
-  for (i = 0; VEC_iterate (ce_s, rhsc, i, c); i++)
-    make_constraint_to_escaped (*c);
-  VEC_free (ce_s, heap, rhsc);
-}
-
 /* Create points-to sets for the current function.  See the comments
    at the start of the file for an algorithmic overview.  */
 
@@ -4815,7 +4595,6 @@ compute_points_to_sets (struct alias_inf
 	  tree stmt = bsi_stmt (bsi);
 
 	  find_func_aliases (stmt);
-	  find_escape_constraints (stmt);
 	  /* Update various related attributes like escaped
 	     addresses, pointer dereferences for loads and stores.
 	     This is used when creating name tags and alias
@@ -4869,10 +4648,6 @@ delete_points_to_sets (void)
   
   for (i = 0; VEC_iterate (varinfo_t, varmap, i, v); i++)
     {
-      /* Nonlocal vars may add more varinfos.  */
-      if (i >= graph_size)
-	break;
-
       VEC_free (constraint_edge_t, heap, graph->succs[i]);
       VEC_free (constraint_edge_t, heap, graph->preds[i]);
       VEC_free (constraint_t, heap, v->complex);

Property changes on: 
___________________________________________________________________
Name: svk:merge
 +138bc75d-0d04-0410-961f-82ee72b054a4:/trunk:119018
 +7dca8dba-45c1-47dc-8958-1a7301c5ed47:/local-gcc/md-constraint:113709
 +f367781f-d768-471e-ba66-e306e17dff77:/local/gen-rework-20060122:110130



More information about the Gcc-patches mailing list