darwin.h: Guard section variables with #ifndef USED_FOR_TARGET.
[official-gcc.git] / gcc / tree-ssa-structalias.c
blob34485d0a754102dd514fa063f511ab54332ac450
1 /* Tree based points-to analysis
2 Copyright (C) 2005 Free Software Foundation, Inc.
3 Contributed by Daniel Berlin <dberlin@dberlin.org>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "ggc.h"
27 #include "obstack.h"
28 #include "bitmap.h"
29 #include "flags.h"
30 #include "rtl.h"
31 #include "tm_p.h"
32 #include "hard-reg-set.h"
33 #include "basic-block.h"
34 #include "output.h"
35 #include "errors.h"
36 #include "diagnostic.h"
37 #include "tree.h"
38 #include "c-common.h"
39 #include "tree-flow.h"
40 #include "tree-inline.h"
41 #include "varray.h"
42 #include "c-tree.h"
43 #include "tree-gimple.h"
44 #include "hashtab.h"
45 #include "function.h"
46 #include "cgraph.h"
47 #include "tree-pass.h"
48 #include "timevar.h"
49 #include "alloc-pool.h"
50 #include "splay-tree.h"
51 #include "tree-ssa-structalias.h"
53 /* The idea behind this analyzer is to generate set constraints from the
54 program, then solve the resulting constraints in order to generate the
55 points-to sets.
57 Set constraints are a way of modeling program analysis problems that
58 involve sets. They consist of an inclusion constraint language,
59 describing the variables (each variable is a set) and operations that
60 are involved on the variables, and a set of rules that derive facts
61 from these operations. To solve a system of set constraints, you derive
62 all possible facts under the rules, which gives you the correct sets
63 as a consequence.
65 See "Efficient Field-sensitive pointer analysis for C" by "David
66 J. Pearce and Paul H. J. Kelly and Chris Hankin, at
67 http://citeseer.ist.psu.edu/pearce04efficient.html
69 Also see "Ultra-fast Aliasing Analysis using CLA: A Million Lines
70 of C Code in a Second" by ""Nevin Heintze and Olivier Tardieu" at
71 http://citeseer.ist.psu.edu/heintze01ultrafast.html
73 There are three types of constraint expressions, DEREF, ADDRESSOF, and
74 SCALAR. Each constraint expression consists of a constraint type,
75 a variable, and an offset.
77 SCALAR is a constraint expression type used to represent x, whether
78 it appears on the LHS or the RHS of a statement.
79 DEREF is a constraint expression type used to represent *x, whether
80 it appears on the LHS or the RHS of a statement.
81 ADDRESSOF is a constraint expression used to represent &x, whether
82 it appears on the LHS or the RHS of a statement.
84 Each pointer variable in the program is assigned an integer id, and
85 each field of a structure variable is assigned an integer id as well.
87 Structure variables are linked to their list of fields through a "next
88 field" in each variable that points to the next field in offset
89 order.
90 Each variable for a structure field has
92 1. "size", that tells the size in bits of that field.
93 2. "fullsize, that tells the size in bits of the entire structure.
94 3. "offset", that tells the offset in bits from the beginning of the
95 structure to this field.
97 Thus,
98 struct f
100 int a;
101 int b;
102 } foo;
103 int *bar;
105 looks like
107 foo.a -> id 1, size 32, offset 0, fullsize 64, next foo.b
108 foo.b -> id 2, size 32, offset 32, fullsize 64, next NULL
109 bar -> id 3, size 32, offset 0, fullsize 32, next NULL
112 In order to solve the system of set constraints, the following is
113 done:
115 1. Each constraint variable x has a solution set associated with it,
116 Sol(x).
118 2. Constraints are separated into direct, copy, and complex.
119 Direct constraints are ADDRESSOF constraints that require no extra
120 processing, such as P = &Q
121 Copy constraints are those of the form P = Q.
122 Complex constraints are all the constraints involving dereferences.
124 3. All direct constraints of the form P = &Q are processed, such
125 that Q is added to Sol(P)
127 4. All complex constraints for a given constraint variable are stored in a
128 linked list attached to that variable's node.
130 5. A directed graph is built out of the copy constraints. Each
131 constraint variable is a node in the graph, and an edge from
132 Q to P is added for each copy constraint of the form P = Q
134 6. The graph is then walked, and solution sets are
135 propagated along the copy edges, such that an edge from Q to P
136 causes Sol(P) <- Sol(P) union Sol(Q).
138 7. As we visit each node, all complex constraints associated with
139 that node are processed by adding appropriate copy edges to the graph, or the
140 appropriate variables to the solution set.
142 8. The process of walking the graph is iterated until no solution
143 sets change.
145 Prior to walking the graph in steps 6 and 7, We perform static
146 cycle elimination on the constraint graph, as well
147 as off-line variable substitution.
149 TODO: Adding offsets to pointer-to-structures can be handled (IE not punted
150 on and turned into anything), but isn't. You can just see what offset
151 inside the pointed-to struct it's going to access.
153 TODO: Constant bounded arrays can be handled as if they were structs of the
154 same number of elements.
156 TODO: Modeling heap and incoming pointers becomes much better if we
157 add fields to them as we discover them, which we could do.
159 TODO: We could handle unions, but to be honest, it's probably not
160 worth the pain or slowdown. */
162 static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
163 htab_t heapvar_for_stmt;
164 static bool use_field_sensitive = true;
165 static unsigned int create_variable_info_for (tree, const char *);
166 static struct constraint_expr get_constraint_for (tree, bool *);
167 static void build_constraint_graph (void);
169 static bitmap_obstack ptabitmap_obstack;
170 static bitmap_obstack iteration_obstack;
171 DEF_VEC_P(constraint_t);
172 DEF_VEC_ALLOC_P(constraint_t,heap);
174 static struct constraint_stats
176 unsigned int total_vars;
177 unsigned int collapsed_vars;
178 unsigned int unified_vars_static;
179 unsigned int unified_vars_dynamic;
180 unsigned int iterations;
181 } stats;
183 struct variable_info
185 /* ID of this variable */
186 unsigned int id;
188 /* Name of this variable */
189 const char *name;
191 /* Tree that this variable is associated with. */
192 tree decl;
194 /* Offset of this variable, in bits, from the base variable */
195 unsigned HOST_WIDE_INT offset;
197 /* Size of the variable, in bits. */
198 unsigned HOST_WIDE_INT size;
200 /* Full size of the base variable, in bits. */
201 unsigned HOST_WIDE_INT fullsize;
203 /* A link to the variable for the next field in this structure. */
204 struct variable_info *next;
206 /* Node in the graph that represents the constraints and points-to
207 solution for the variable. */
208 unsigned int node;
210 /* True if the address of this variable is taken. Needed for
211 variable substitution. */
212 unsigned int address_taken:1;
214 /* True if this variable is the target of a dereference. Needed for
215 variable substitution. */
216 unsigned int indirect_target:1;
218 /* True if this is a variable created by the constraint analysis, such as
219 heap variables and constraints we had to break up. */
220 unsigned int is_artificial_var:1;
222 /* True if this is a special variable whose solution set should not be
223 changed. */
224 unsigned int is_special_var:1;
226 /* True for variables whose size is not known or variable. */
227 unsigned int is_unknown_size_var:1;
229 /* True for variables that have unions somewhere in them. */
230 unsigned int has_union:1;
232 /* True if this is a heap variable. */
233 unsigned int is_heap_var:1;
235 /* Points-to set for this variable. */
236 bitmap solution;
238 /* Variable ids represented by this node. */
239 bitmap variables;
241 /* Vector of complex constraints for this node. Complex
242 constraints are those involving dereferences. */
243 VEC(constraint_t,heap) *complex;
245 /* Variable id this was collapsed to due to type unsafety.
246 This should be unused completely after build_constraint_graph, or
247 something is broken. */
248 struct variable_info *collapsed_to;
250 typedef struct variable_info *varinfo_t;
252 static varinfo_t first_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT);
254 /* Pool of variable info structures. */
255 static alloc_pool variable_info_pool;
257 DEF_VEC_P(varinfo_t);
259 DEF_VEC_ALLOC_P(varinfo_t, heap);
261 /* Table of variable info structures for constraint variables. Indexed directly
262 by variable info id. */
263 static VEC(varinfo_t,heap) *varmap;
265 /* Return the varmap element N */
267 static inline varinfo_t
268 get_varinfo (unsigned int n)
270 return VEC_index(varinfo_t, varmap, n);
273 /* Return the varmap element N, following the collapsed_to link. */
275 static inline varinfo_t
276 get_varinfo_fc (unsigned int n)
278 varinfo_t v = VEC_index(varinfo_t, varmap, n);
280 if (v->collapsed_to)
281 return v->collapsed_to;
282 return v;
285 /* Variable that represents the unknown pointer. */
286 static varinfo_t var_anything;
287 static tree anything_tree;
288 static unsigned int anything_id;
290 /* Variable that represents the NULL pointer. */
291 static varinfo_t var_nothing;
292 static tree nothing_tree;
293 static unsigned int nothing_id;
295 /* Variable that represents read only memory. */
296 static varinfo_t var_readonly;
297 static tree readonly_tree;
298 static unsigned int readonly_id;
300 /* Variable that represents integers. This is used for when people do things
301 like &0->a.b. */
302 static varinfo_t var_integer;
303 static tree integer_tree;
304 static unsigned int integer_id;
306 /* Variable that represents arbitrary offsets into an object. Used to
307 represent pointer arithmetic, which may not legally escape the
308 bounds of an object. */
309 static varinfo_t var_anyoffset;
310 static tree anyoffset_tree;
311 static unsigned int anyoffset_id;
314 /* Lookup a heap var for FROM, and return it if we find one. */
316 static tree
317 heapvar_lookup (tree from)
319 struct tree_map *h, in;
320 in.from = from;
322 h = htab_find_with_hash (heapvar_for_stmt, &in, htab_hash_pointer (from));
323 if (h)
324 return h->to;
325 return NULL_TREE;
328 /* Insert a mapping FROM->TO in the heap var for statement
329 hashtable. */
331 static void
332 heapvar_insert (tree from, tree to)
334 struct tree_map *h;
335 void **loc;
337 h = ggc_alloc (sizeof (struct tree_map));
338 h->hash = htab_hash_pointer (from);
339 h->from = from;
340 h->to = to;
341 loc = htab_find_slot_with_hash (heapvar_for_stmt, h, h->hash, INSERT);
342 *(struct tree_map **) loc = h;
345 /* Return a new variable info structure consisting for a variable
346 named NAME, and using constraint graph node NODE. */
348 static varinfo_t
349 new_var_info (tree t, unsigned int id, const char *name, unsigned int node)
351 varinfo_t ret = pool_alloc (variable_info_pool);
353 ret->id = id;
354 ret->name = name;
355 ret->decl = t;
356 ret->node = node;
357 ret->address_taken = false;
358 ret->indirect_target = false;
359 ret->is_artificial_var = false;
360 ret->is_heap_var = false;
361 ret->is_special_var = false;
362 ret->is_unknown_size_var = false;
363 ret->has_union = false;
364 ret->solution = BITMAP_ALLOC (&ptabitmap_obstack);
365 bitmap_clear (ret->solution);
366 ret->variables = BITMAP_ALLOC (&ptabitmap_obstack);
367 bitmap_clear (ret->variables);
368 ret->complex = NULL;
369 ret->next = NULL;
370 ret->collapsed_to = NULL;
371 return ret;
374 typedef enum {SCALAR, DEREF, ADDRESSOF} constraint_expr_type;
376 /* An expression that appears in a constraint. */
378 struct constraint_expr
380 /* Constraint type. */
381 constraint_expr_type type;
383 /* Variable we are referring to in the constraint. */
384 unsigned int var;
386 /* Offset, in bits, of this constraint from the beginning of
387 variables it ends up referring to.
389 IOW, in a deref constraint, we would deref, get the result set,
390 then add OFFSET to each member. */
391 unsigned HOST_WIDE_INT offset;
394 static struct constraint_expr do_deref (struct constraint_expr);
396 /* Our set constraints are made up of two constraint expressions, one
397 LHS, and one RHS.
399 As described in the introduction, our set constraints each represent an
400 operation between set valued variables.
402 struct constraint
404 struct constraint_expr lhs;
405 struct constraint_expr rhs;
408 /* List of constraints that we use to build the constraint graph from. */
410 static VEC(constraint_t,heap) *constraints;
411 static alloc_pool constraint_pool;
413 /* An edge in the constraint graph. We technically have no use for
414 the src, since it will always be the same node that we are indexing
415 into the pred/succ arrays with, but it's nice for checking
416 purposes. The edges are weighted, with a bit set in weights for
417 each edge from src to dest with that weight. */
419 struct constraint_edge
421 unsigned int src;
422 unsigned int dest;
423 bitmap weights;
426 typedef struct constraint_edge *constraint_edge_t;
427 static alloc_pool constraint_edge_pool;
429 /* Return a new constraint edge from SRC to DEST. */
431 static constraint_edge_t
432 new_constraint_edge (unsigned int src, unsigned int dest)
434 constraint_edge_t ret = pool_alloc (constraint_edge_pool);
435 ret->src = src;
436 ret->dest = dest;
437 ret->weights = NULL;
438 return ret;
441 DEF_VEC_P(constraint_edge_t);
442 DEF_VEC_ALLOC_P(constraint_edge_t,heap);
445 /* The constraint graph is simply a set of adjacency vectors, one per
446 variable. succs[x] is the vector of successors for variable x, and preds[x]
447 is the vector of predecessors for variable x.
448 IOW, all edges are "forward" edges, which is not like our CFG.
449 So remember that
450 preds[x]->src == x, and
451 succs[x]->src == x. */
453 struct constraint_graph
455 VEC(constraint_edge_t,heap) **succs;
456 VEC(constraint_edge_t,heap) **preds;
459 typedef struct constraint_graph *constraint_graph_t;
461 static constraint_graph_t graph;
463 /* Create a new constraint consisting of LHS and RHS expressions. */
465 static constraint_t
466 new_constraint (const struct constraint_expr lhs,
467 const struct constraint_expr rhs)
469 constraint_t ret = pool_alloc (constraint_pool);
470 ret->lhs = lhs;
471 ret->rhs = rhs;
472 return ret;
475 /* Print out constraint C to FILE. */
477 void
478 dump_constraint (FILE *file, constraint_t c)
480 if (c->lhs.type == ADDRESSOF)
481 fprintf (file, "&");
482 else if (c->lhs.type == DEREF)
483 fprintf (file, "*");
484 fprintf (file, "%s", get_varinfo_fc (c->lhs.var)->name);
485 if (c->lhs.offset != 0)
486 fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->lhs.offset);
487 fprintf (file, " = ");
488 if (c->rhs.type == ADDRESSOF)
489 fprintf (file, "&");
490 else if (c->rhs.type == DEREF)
491 fprintf (file, "*");
492 fprintf (file, "%s", get_varinfo_fc (c->rhs.var)->name);
493 if (c->rhs.offset != 0)
494 fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->rhs.offset);
495 fprintf (file, "\n");
498 /* Print out constraint C to stderr. */
500 void
501 debug_constraint (constraint_t c)
503 dump_constraint (stderr, c);
506 /* Print out all constraints to FILE */
508 void
509 dump_constraints (FILE *file)
511 int i;
512 constraint_t c;
513 for (i = 0; VEC_iterate (constraint_t, constraints, i, c); i++)
514 dump_constraint (file, c);
517 /* Print out all constraints to stderr. */
519 void
520 debug_constraints (void)
522 dump_constraints (stderr);
525 /* SOLVER FUNCTIONS
527 The solver is a simple worklist solver, that works on the following
528 algorithm:
530 sbitmap changed_nodes = all ones;
531 changed_count = number of nodes;
532 For each node that was already collapsed:
533 changed_count--;
536 while (changed_count > 0)
538 compute topological ordering for constraint graph
540 find and collapse cycles in the constraint graph (updating
541 changed if necessary)
543 for each node (n) in the graph in topological order:
544 changed_count--;
546 Process each complex constraint associated with the node,
547 updating changed if necessary.
549 For each outgoing edge from n, propagate the solution from n to
550 the destination of the edge, updating changed as necessary.
552 } */
554 /* Return true if two constraint expressions A and B are equal. */
556 static bool
557 constraint_expr_equal (struct constraint_expr a, struct constraint_expr b)
559 return a.type == b.type
560 && a.var == b.var
561 && a.offset == b.offset;
564 /* Return true if constraint expression A is less than constraint expression
565 B. This is just arbitrary, but consistent, in order to give them an
566 ordering. */
568 static bool
569 constraint_expr_less (struct constraint_expr a, struct constraint_expr b)
571 if (a.type == b.type)
573 if (a.var == b.var)
574 return a.offset < b.offset;
575 else
576 return a.var < b.var;
578 else
579 return a.type < b.type;
582 /* Return true if constraint A is less than constraint B. This is just
583 arbitrary, but consistent, in order to give them an ordering. */
585 static bool
586 constraint_less (const constraint_t a, const constraint_t b)
588 if (constraint_expr_less (a->lhs, b->lhs))
589 return true;
590 else if (constraint_expr_less (b->lhs, a->lhs))
591 return false;
592 else
593 return constraint_expr_less (a->rhs, b->rhs);
596 /* Return true if two constraints A and B are equal. */
598 static bool
599 constraint_equal (struct constraint a, struct constraint b)
601 return constraint_expr_equal (a.lhs, b.lhs)
602 && constraint_expr_equal (a.rhs, b.rhs);
606 /* Find a constraint LOOKFOR in the sorted constraint vector VEC */
608 static constraint_t
609 constraint_vec_find (VEC(constraint_t,heap) *vec,
610 struct constraint lookfor)
612 unsigned int place;
613 constraint_t found;
615 if (vec == NULL)
616 return NULL;
618 place = VEC_lower_bound (constraint_t, vec, &lookfor, constraint_less);
619 if (place >= VEC_length (constraint_t, vec))
620 return NULL;
621 found = VEC_index (constraint_t, vec, place);
622 if (!constraint_equal (*found, lookfor))
623 return NULL;
624 return found;
627 /* Union two constraint vectors, TO and FROM. Put the result in TO. */
629 static void
630 constraint_set_union (VEC(constraint_t,heap) **to,
631 VEC(constraint_t,heap) **from)
633 int i;
634 constraint_t c;
636 for (i = 0; VEC_iterate (constraint_t, *from, i, c); i++)
638 if (constraint_vec_find (*to, *c) == NULL)
640 unsigned int place = VEC_lower_bound (constraint_t, *to, c,
641 constraint_less);
642 VEC_safe_insert (constraint_t, heap, *to, place, c);
647 /* Take a solution set SET, add OFFSET to each member of the set, and
648 overwrite SET with the result when done. */
650 static void
651 solution_set_add (bitmap set, unsigned HOST_WIDE_INT offset)
653 bitmap result = BITMAP_ALLOC (&iteration_obstack);
654 unsigned int i;
655 bitmap_iterator bi;
657 EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi)
659 /* If this is a properly sized variable, only add offset if it's
660 less than end. Otherwise, it is globbed to a single
661 variable. */
663 if ((get_varinfo (i)->offset + offset) < get_varinfo (i)->fullsize)
665 unsigned HOST_WIDE_INT fieldoffset = get_varinfo (i)->offset + offset;
666 varinfo_t v = first_vi_for_offset (get_varinfo (i), fieldoffset);
667 if (!v)
668 continue;
669 bitmap_set_bit (result, v->id);
671 else if (get_varinfo (i)->is_artificial_var
672 || get_varinfo (i)->has_union
673 || get_varinfo (i)->is_unknown_size_var)
675 bitmap_set_bit (result, i);
679 bitmap_copy (set, result);
680 BITMAP_FREE (result);
683 /* Union solution sets TO and FROM, and add INC to each member of FROM in the
684 process. */
686 static bool
687 set_union_with_increment (bitmap to, bitmap from, unsigned HOST_WIDE_INT inc)
689 if (inc == 0)
690 return bitmap_ior_into (to, from);
691 else
693 bitmap tmp;
694 bool res;
696 tmp = BITMAP_ALLOC (&iteration_obstack);
697 bitmap_copy (tmp, from);
698 solution_set_add (tmp, inc);
699 res = bitmap_ior_into (to, tmp);
700 BITMAP_FREE (tmp);
701 return res;
705 /* Insert constraint C into the list of complex constraints for VAR. */
707 static void
708 insert_into_complex (unsigned int var, constraint_t c)
710 varinfo_t vi = get_varinfo (var);
711 unsigned int place = VEC_lower_bound (constraint_t, vi->complex, c,
712 constraint_less);
713 VEC_safe_insert (constraint_t, heap, vi->complex, place, c);
717 /* Compare two constraint edges A and B, return true if they are equal. */
719 static bool
720 constraint_edge_equal (struct constraint_edge a, struct constraint_edge b)
722 return a.src == b.src && a.dest == b.dest;
725 /* Compare two constraint edges, return true if A is less than B */
727 static bool
728 constraint_edge_less (const constraint_edge_t a, const constraint_edge_t b)
730 if (a->dest < b->dest)
731 return true;
732 else if (a->dest == b->dest)
733 return a->src < b->src;
734 else
735 return false;
738 /* Find the constraint edge that matches LOOKFOR, in VEC.
739 Return the edge, if found, NULL otherwise. */
741 static constraint_edge_t
742 constraint_edge_vec_find (VEC(constraint_edge_t,heap) *vec,
743 struct constraint_edge lookfor)
745 unsigned int place;
746 constraint_edge_t edge;
748 place = VEC_lower_bound (constraint_edge_t, vec, &lookfor,
749 constraint_edge_less);
750 edge = VEC_index (constraint_edge_t, vec, place);
751 if (!constraint_edge_equal (*edge, lookfor))
752 return NULL;
753 return edge;
756 /* Condense two variable nodes into a single variable node, by moving
757 all associated info from SRC to TO. */
759 static void
760 condense_varmap_nodes (unsigned int to, unsigned int src)
762 varinfo_t tovi = get_varinfo (to);
763 varinfo_t srcvi = get_varinfo (src);
764 unsigned int i;
765 constraint_t c;
766 bitmap_iterator bi;
768 /* the src node, and all its variables, are now the to node. */
769 srcvi->node = to;
770 EXECUTE_IF_SET_IN_BITMAP (srcvi->variables, 0, i, bi)
771 get_varinfo (i)->node = to;
773 /* Merge the src node variables and the to node variables. */
774 bitmap_set_bit (tovi->variables, src);
775 bitmap_ior_into (tovi->variables, srcvi->variables);
776 bitmap_clear (srcvi->variables);
778 /* Move all complex constraints from src node into to node */
779 for (i = 0; VEC_iterate (constraint_t, srcvi->complex, i, c); i++)
781 /* In complex constraints for node src, we may have either
782 a = *src, and *src = a. */
784 if (c->rhs.type == DEREF)
785 c->rhs.var = to;
786 else
787 c->lhs.var = to;
789 constraint_set_union (&tovi->complex, &srcvi->complex);
790 VEC_free (constraint_t, heap, srcvi->complex);
791 srcvi->complex = NULL;
794 /* Erase EDGE from GRAPH. This routine only handles self-edges
795 (e.g. an edge from a to a). */
797 static void
798 erase_graph_self_edge (constraint_graph_t graph, struct constraint_edge edge)
800 VEC(constraint_edge_t,heap) *predvec = graph->preds[edge.src];
801 VEC(constraint_edge_t,heap) *succvec = graph->succs[edge.dest];
802 unsigned int place;
803 gcc_assert (edge.src == edge.dest);
805 /* Remove from the successors. */
806 place = VEC_lower_bound (constraint_edge_t, succvec, &edge,
807 constraint_edge_less);
809 /* Make sure we found the edge. */
810 #ifdef ENABLE_CHECKING
812 constraint_edge_t tmp = VEC_index (constraint_edge_t, succvec, place);
813 gcc_assert (constraint_edge_equal (*tmp, edge));
815 #endif
816 VEC_ordered_remove (constraint_edge_t, succvec, place);
818 /* Remove from the predecessors. */
819 place = VEC_lower_bound (constraint_edge_t, predvec, &edge,
820 constraint_edge_less);
822 /* Make sure we found the edge. */
823 #ifdef ENABLE_CHECKING
825 constraint_edge_t tmp = VEC_index (constraint_edge_t, predvec, place);
826 gcc_assert (constraint_edge_equal (*tmp, edge));
828 #endif
829 VEC_ordered_remove (constraint_edge_t, predvec, place);
832 /* Remove edges involving NODE from GRAPH. */
834 static void
835 clear_edges_for_node (constraint_graph_t graph, unsigned int node)
837 VEC(constraint_edge_t,heap) *succvec = graph->succs[node];
838 VEC(constraint_edge_t,heap) *predvec = graph->preds[node];
839 constraint_edge_t c;
840 int i;
842 /* Walk the successors, erase the associated preds. */
843 for (i = 0; VEC_iterate (constraint_edge_t, succvec, i, c); i++)
844 if (c->dest != node)
846 unsigned int place;
847 struct constraint_edge lookfor;
848 lookfor.src = c->dest;
849 lookfor.dest = node;
850 place = VEC_lower_bound (constraint_edge_t, graph->preds[c->dest],
851 &lookfor, constraint_edge_less);
852 VEC_ordered_remove (constraint_edge_t, graph->preds[c->dest], place);
854 /* Walk the preds, erase the associated succs. */
855 for (i =0; VEC_iterate (constraint_edge_t, predvec, i, c); i++)
856 if (c->dest != node)
858 unsigned int place;
859 struct constraint_edge lookfor;
860 lookfor.src = c->dest;
861 lookfor.dest = node;
862 place = VEC_lower_bound (constraint_edge_t, graph->succs[c->dest],
863 &lookfor, constraint_edge_less);
864 VEC_ordered_remove (constraint_edge_t, graph->succs[c->dest], place);
867 VEC_free (constraint_edge_t, heap, graph->preds[node]);
868 VEC_free (constraint_edge_t, heap, graph->succs[node]);
869 graph->preds[node] = NULL;
870 graph->succs[node] = NULL;
873 static bool edge_added = false;
875 /* Add edge NEWE to the graph. */
877 static bool
878 add_graph_edge (constraint_graph_t graph, struct constraint_edge newe)
880 unsigned int place;
881 unsigned int src = newe.src;
882 unsigned int dest = newe.dest;
883 VEC(constraint_edge_t,heap) *vec;
885 vec = graph->preds[src];
886 place = VEC_lower_bound (constraint_edge_t, vec, &newe,
887 constraint_edge_less);
888 if (place == VEC_length (constraint_edge_t, vec)
889 || VEC_index (constraint_edge_t, vec, place)->dest != dest)
891 constraint_edge_t edge = new_constraint_edge (src, dest);
892 bitmap weightbitmap;
894 weightbitmap = BITMAP_ALLOC (&ptabitmap_obstack);
895 edge->weights = weightbitmap;
896 VEC_safe_insert (constraint_edge_t, heap, graph->preds[edge->src],
897 place, edge);
898 edge = new_constraint_edge (dest, src);
899 edge->weights = weightbitmap;
900 place = VEC_lower_bound (constraint_edge_t, graph->succs[edge->src],
901 edge, constraint_edge_less);
902 VEC_safe_insert (constraint_edge_t, heap, graph->succs[edge->src],
903 place, edge);
904 edge_added = true;
905 return true;
907 else
908 return false;
912 /* Return the bitmap representing the weights of edge LOOKFOR */
914 static bitmap
915 get_graph_weights (constraint_graph_t graph, struct constraint_edge lookfor)
917 constraint_edge_t edge;
918 unsigned int src = lookfor.src;
919 VEC(constraint_edge_t,heap) *vec;
920 vec = graph->preds[src];
921 edge = constraint_edge_vec_find (vec, lookfor);
922 gcc_assert (edge != NULL);
923 return edge->weights;
927 /* Merge GRAPH nodes FROM and TO into node TO. */
929 static void
930 merge_graph_nodes (constraint_graph_t graph, unsigned int to,
931 unsigned int from)
933 VEC(constraint_edge_t,heap) *succvec = graph->succs[from];
934 VEC(constraint_edge_t,heap) *predvec = graph->preds[from];
935 int i;
936 constraint_edge_t c;
938 /* Merge all the predecessor edges. */
940 for (i = 0; VEC_iterate (constraint_edge_t, predvec, i, c); i++)
942 unsigned int d = c->dest;
943 struct constraint_edge olde;
944 struct constraint_edge newe;
945 bitmap temp;
946 bitmap weights;
947 if (c->dest == from)
948 d = to;
949 newe.src = to;
950 newe.dest = d;
951 add_graph_edge (graph, newe);
952 olde.src = from;
953 olde.dest = c->dest;
954 olde.weights = NULL;
955 temp = get_graph_weights (graph, olde);
956 weights = get_graph_weights (graph, newe);
957 bitmap_ior_into (weights, temp);
960 /* Merge all the successor edges. */
961 for (i = 0; VEC_iterate (constraint_edge_t, succvec, i, c); i++)
963 unsigned int d = c->dest;
964 struct constraint_edge olde;
965 struct constraint_edge newe;
966 bitmap temp;
967 bitmap weights;
968 if (c->dest == from)
969 d = to;
970 newe.src = d;
971 newe.dest = to;
972 add_graph_edge (graph, newe);
973 olde.src = c->dest;
974 olde.dest = from;
975 olde.weights = NULL;
976 temp = get_graph_weights (graph, olde);
977 weights = get_graph_weights (graph, newe);
978 bitmap_ior_into (weights, temp);
980 clear_edges_for_node (graph, from);
983 /* Add a graph edge to GRAPH, going from TO to FROM, with WEIGHT, if
984 it doesn't exist in the graph already.
985 Return false if the edge already existed, true otherwise. */
987 static bool
988 int_add_graph_edge (constraint_graph_t graph, unsigned int to,
989 unsigned int from, unsigned HOST_WIDE_INT weight)
991 if (to == from && weight == 0)
993 return false;
995 else
997 bool r;
998 struct constraint_edge edge;
999 edge.src = to;
1000 edge.dest = from;
1001 edge.weights = NULL;
1002 r = add_graph_edge (graph, edge);
1003 r |= !bitmap_bit_p (get_graph_weights (graph, edge), weight);
1004 bitmap_set_bit (get_graph_weights (graph, edge), weight);
1005 return r;
1010 /* Return true if LOOKFOR is an existing graph edge. */
1012 static bool
1013 valid_graph_edge (constraint_graph_t graph, struct constraint_edge lookfor)
1015 return constraint_edge_vec_find (graph->preds[lookfor.src], lookfor) != NULL;
1019 /* Build the constraint graph. */
1021 static void
1022 build_constraint_graph (void)
1024 int i = 0;
1025 constraint_t c;
1027 graph = xmalloc (sizeof (struct constraint_graph));
1028 graph->succs = xcalloc (VEC_length (varinfo_t, varmap),
1029 sizeof (*graph->succs));
1030 graph->preds = xcalloc (VEC_length (varinfo_t, varmap),
1031 sizeof (*graph->preds));
1033 for (i = 0; VEC_iterate (constraint_t, constraints, i, c); i++)
1035 struct constraint_expr lhs = c->lhs;
1036 struct constraint_expr rhs = c->rhs;
1037 unsigned int lhsvar = get_varinfo_fc (lhs.var)->id;
1038 unsigned int rhsvar = get_varinfo_fc (rhs.var)->id;
1040 if (lhs.type == DEREF)
1042 /* *x = y or *x = &y (complex) */
1043 if (rhs.type == ADDRESSOF || rhsvar > anything_id)
1044 insert_into_complex (lhsvar, c);
1046 else if (rhs.type == DEREF)
1048 /* !special var= *y */
1049 if (!(get_varinfo (lhsvar)->is_special_var))
1050 insert_into_complex (rhsvar, c);
1052 else if (rhs.type == ADDRESSOF)
1054 /* x = &y */
1055 bitmap_set_bit (get_varinfo (lhsvar)->solution, rhsvar);
1057 else if (lhsvar > anything_id)
1059 /* Ignore 0 weighted self edges, as they can't possibly contribute
1060 anything */
1061 if (lhsvar != rhsvar || rhs.offset != 0 || lhs.offset != 0)
1064 struct constraint_edge edge;
1065 edge.src = lhsvar;
1066 edge.dest = rhsvar;
1067 /* x = y (simple) */
1068 add_graph_edge (graph, edge);
1069 bitmap_set_bit (get_graph_weights (graph, edge),
1070 rhs.offset);
1078 /* Changed variables on the last iteration. */
1079 static unsigned int changed_count;
1080 static sbitmap changed;
1082 DEF_VEC_I(unsigned);
1083 DEF_VEC_ALLOC_I(unsigned,heap);
1086 /* Strongly Connected Component visitation info. */
1088 struct scc_info
1090 sbitmap visited;
1091 sbitmap in_component;
1092 int current_index;
1093 unsigned int *visited_index;
1094 VEC(unsigned,heap) *scc_stack;
1095 VEC(unsigned,heap) *unification_queue;
1099 /* Recursive routine to find strongly connected components in GRAPH.
1100 SI is the SCC info to store the information in, and N is the id of current
1101 graph node we are processing.
1103 This is Tarjan's strongly connected component finding algorithm, as
1104 modified by Nuutila to keep only non-root nodes on the stack.
1105 The algorithm can be found in "On finding the strongly connected
1106 connected components in a directed graph" by Esko Nuutila and Eljas
1107 Soisalon-Soininen, in Information Processing Letters volume 49,
1108 number 1, pages 9-14. */
1110 static void
1111 scc_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
1113 constraint_edge_t c;
1114 int i;
1116 gcc_assert (get_varinfo (n)->node == n);
1117 SET_BIT (si->visited, n);
1118 RESET_BIT (si->in_component, n);
1119 si->visited_index[n] = si->current_index ++;
1121 /* Visit all the successors. */
1122 for (i = 0; VEC_iterate (constraint_edge_t, graph->succs[n], i, c); i++)
1124 /* We only want to find and collapse the zero weight edges. */
1125 if (bitmap_bit_p (c->weights, 0))
1127 unsigned int w = c->dest;
1128 if (!TEST_BIT (si->visited, w))
1129 scc_visit (graph, si, w);
1130 if (!TEST_BIT (si->in_component, w))
1132 unsigned int t = get_varinfo (w)->node;
1133 unsigned int nnode = get_varinfo (n)->node;
1134 if (si->visited_index[t] < si->visited_index[nnode])
1135 get_varinfo (n)->node = t;
1140 /* See if any components have been identified. */
1141 if (get_varinfo (n)->node == n)
1143 unsigned int t = si->visited_index[n];
1144 SET_BIT (si->in_component, n);
1145 while (VEC_length (unsigned, si->scc_stack) != 0
1146 && t < si->visited_index[VEC_last (unsigned, si->scc_stack)])
1148 unsigned int w = VEC_pop (unsigned, si->scc_stack);
1149 get_varinfo (w)->node = n;
1150 SET_BIT (si->in_component, w);
1151 /* Mark this node for collapsing. */
1152 VEC_safe_push (unsigned, heap, si->unification_queue, w);
1155 else
1156 VEC_safe_push (unsigned, heap, si->scc_stack, n);
1160 /* Collapse two variables into one variable. */
1162 static void
1163 collapse_nodes (constraint_graph_t graph, unsigned int to, unsigned int from)
1165 bitmap tosol, fromsol;
1166 struct constraint_edge edge;
1169 condense_varmap_nodes (to, from);
1170 tosol = get_varinfo (to)->solution;
1171 fromsol = get_varinfo (from)->solution;
1172 bitmap_ior_into (tosol, fromsol);
1173 merge_graph_nodes (graph, to, from);
1174 edge.src = to;
1175 edge.dest = to;
1176 edge.weights = NULL;
1177 if (valid_graph_edge (graph, edge))
1179 bitmap weights = get_graph_weights (graph, edge);
1180 bitmap_clear_bit (weights, 0);
1181 if (bitmap_empty_p (weights))
1182 erase_graph_self_edge (graph, edge);
1184 bitmap_clear (fromsol);
1185 get_varinfo (to)->address_taken |= get_varinfo (from)->address_taken;
1186 get_varinfo (to)->indirect_target |= get_varinfo (from)->indirect_target;
1190 /* Unify nodes in GRAPH that we have found to be part of a cycle.
1191 SI is the Strongly Connected Components information structure that tells us
1192 what components to unify.
1193 UPDATE_CHANGED should be set to true if the changed sbitmap and changed
1194 count should be updated to reflect the unification. */
1196 static void
1197 process_unification_queue (constraint_graph_t graph, struct scc_info *si,
1198 bool update_changed)
1200 size_t i = 0;
1201 bitmap tmp = BITMAP_ALLOC (update_changed ? &iteration_obstack : NULL);
1202 bitmap_clear (tmp);
1204 /* We proceed as follows:
1206 For each component in the queue (components are delineated by
1207 when current_queue_element->node != next_queue_element->node):
1209 rep = representative node for component
1211 For each node (tounify) to be unified in the component,
1212 merge the solution for tounify into tmp bitmap
1214 clear solution for tounify
1216 merge edges from tounify into rep
1218 merge complex constraints from tounify into rep
1220 update changed count to note that tounify will never change
1221 again
1223 Merge tmp into solution for rep, marking rep changed if this
1224 changed rep's solution.
1226 Delete any 0 weighted self-edges we now have for rep. */
1227 while (i != VEC_length (unsigned, si->unification_queue))
1229 unsigned int tounify = VEC_index (unsigned, si->unification_queue, i);
1230 unsigned int n = get_varinfo (tounify)->node;
1232 if (dump_file && (dump_flags & TDF_DETAILS))
1233 fprintf (dump_file, "Unifying %s to %s\n",
1234 get_varinfo (tounify)->name,
1235 get_varinfo (n)->name);
1236 if (update_changed)
1237 stats.unified_vars_dynamic++;
1238 else
1239 stats.unified_vars_static++;
1240 bitmap_ior_into (tmp, get_varinfo (tounify)->solution);
1241 merge_graph_nodes (graph, n, tounify);
1242 condense_varmap_nodes (n, tounify);
1244 if (update_changed && TEST_BIT (changed, tounify))
1246 RESET_BIT (changed, tounify);
1247 if (!TEST_BIT (changed, n))
1248 SET_BIT (changed, n);
1249 else
1251 gcc_assert (changed_count > 0);
1252 changed_count--;
1256 bitmap_clear (get_varinfo (tounify)->solution);
1257 ++i;
1259 /* If we've either finished processing the entire queue, or
1260 finished processing all nodes for component n, update the solution for
1261 n. */
1262 if (i == VEC_length (unsigned, si->unification_queue)
1263 || get_varinfo (VEC_index (unsigned, si->unification_queue, i))->node != n)
1265 struct constraint_edge edge;
1267 /* If the solution changes because of the merging, we need to mark
1268 the variable as changed. */
1269 if (bitmap_ior_into (get_varinfo (n)->solution, tmp))
1271 if (update_changed && !TEST_BIT (changed, n))
1273 SET_BIT (changed, n);
1274 changed_count++;
1277 bitmap_clear (tmp);
1278 edge.src = n;
1279 edge.dest = n;
1280 edge.weights = NULL;
1281 if (valid_graph_edge (graph, edge))
1283 bitmap weights = get_graph_weights (graph, edge);
1284 bitmap_clear_bit (weights, 0);
1285 if (bitmap_empty_p (weights))
1286 erase_graph_self_edge (graph, edge);
1290 BITMAP_FREE (tmp);
1294 /* Information needed to compute the topological ordering of a graph. */
1296 struct topo_info
1298 /* sbitmap of visited nodes. */
1299 sbitmap visited;
1300 /* Array that stores the topological order of the graph, *in
1301 reverse*. */
1302 VEC(unsigned,heap) *topo_order;
1306 /* Initialize and return a topological info structure. */
1308 static struct topo_info *
1309 init_topo_info (void)
1311 size_t size = VEC_length (varinfo_t, varmap);
1312 struct topo_info *ti = xmalloc (sizeof (struct topo_info));
1313 ti->visited = sbitmap_alloc (size);
1314 sbitmap_zero (ti->visited);
1315 ti->topo_order = VEC_alloc (unsigned, heap, 1);
1316 return ti;
1320 /* Free the topological sort info pointed to by TI. */
1322 static void
1323 free_topo_info (struct topo_info *ti)
1325 sbitmap_free (ti->visited);
1326 VEC_free (unsigned, heap, ti->topo_order);
1327 free (ti);
1330 /* Visit the graph in topological order, and store the order in the
1331 topo_info structure. */
1333 static void
1334 topo_visit (constraint_graph_t graph, struct topo_info *ti,
1335 unsigned int n)
1337 VEC(constraint_edge_t,heap) *succs = graph->succs[n];
1338 constraint_edge_t c;
1339 int i;
1340 SET_BIT (ti->visited, n);
1341 for (i = 0; VEC_iterate (constraint_edge_t, succs, i, c); i++)
1343 if (!TEST_BIT (ti->visited, c->dest))
1344 topo_visit (graph, ti, c->dest);
1346 VEC_safe_push (unsigned, heap, ti->topo_order, n);
1349 /* Return true if variable N + OFFSET is a legal field of N. */
1351 static bool
1352 type_safe (unsigned int n, unsigned HOST_WIDE_INT *offset)
1354 varinfo_t ninfo = get_varinfo (n);
1356 /* For things we've globbed to single variables, any offset into the
1357 variable acts like the entire variable, so that it becomes offset
1358 0. */
1359 if (ninfo->is_special_var
1360 || ninfo->is_artificial_var
1361 || ninfo->is_unknown_size_var)
1363 *offset = 0;
1364 return true;
1366 return (get_varinfo (n)->offset + *offset) < get_varinfo (n)->fullsize;
1369 /* Process a constraint C that represents *x = &y. */
1371 static void
1372 do_da_constraint (constraint_graph_t graph ATTRIBUTE_UNUSED,
1373 constraint_t c, bitmap delta)
1375 unsigned int rhs = c->rhs.var;
1376 unsigned int j;
1377 bitmap_iterator bi;
1379 /* For each member j of Delta (Sol(x)), add x to Sol(j) */
1380 EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
1382 unsigned HOST_WIDE_INT offset = c->lhs.offset;
1383 if (type_safe (j, &offset) && !(get_varinfo (j)->is_special_var))
1385 /* *x != NULL && *x != ANYTHING*/
1386 varinfo_t v;
1387 unsigned int t;
1388 bitmap sol;
1389 unsigned HOST_WIDE_INT fieldoffset = get_varinfo (j)->offset + offset;
1391 v = first_vi_for_offset (get_varinfo (j), fieldoffset);
1392 if (!v)
1393 continue;
1394 t = v->node;
1395 sol = get_varinfo (t)->solution;
1396 if (!bitmap_bit_p (sol, rhs))
1398 bitmap_set_bit (sol, rhs);
1399 if (!TEST_BIT (changed, t))
1401 SET_BIT (changed, t);
1402 changed_count++;
1406 else if (dump_file && !(get_varinfo (j)->is_special_var))
1407 fprintf (dump_file, "Untypesafe usage in do_da_constraint.\n");
1412 /* Process a constraint C that represents x = *y, using DELTA as the
1413 starting solution. */
1415 static void
1416 do_sd_constraint (constraint_graph_t graph, constraint_t c,
1417 bitmap delta)
1419 unsigned int lhs = get_varinfo (c->lhs.var)->node;
1420 bool flag = false;
1421 bitmap sol = get_varinfo (lhs)->solution;
1422 unsigned int j;
1423 bitmap_iterator bi;
1425 /* For each variable j in delta (Sol(y)), add
1426 an edge in the graph from j to x, and union Sol(j) into Sol(x). */
1427 EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
1429 unsigned HOST_WIDE_INT roffset = c->rhs.offset;
1430 if (type_safe (j, &roffset))
1432 varinfo_t v;
1433 unsigned HOST_WIDE_INT fieldoffset = get_varinfo (j)->offset + roffset;
1434 unsigned int t;
1436 v = first_vi_for_offset (get_varinfo (j), fieldoffset);
1437 if (!v)
1438 continue;
1439 t = v->node;
1440 if (int_add_graph_edge (graph, lhs, t, 0))
1441 flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
1443 else if (dump_file && !(get_varinfo (j)->is_special_var))
1444 fprintf (dump_file, "Untypesafe usage in do_sd_constraint\n");
1448 /* If the LHS solution changed, mark the var as changed. */
1449 if (flag)
1451 get_varinfo (lhs)->solution = sol;
1452 if (!TEST_BIT (changed, lhs))
1454 SET_BIT (changed, lhs);
1455 changed_count++;
1460 /* Process a constraint C that represents *x = y. */
1462 static void
1463 do_ds_constraint (constraint_graph_t graph, constraint_t c, bitmap delta)
1465 unsigned int rhs = get_varinfo (c->rhs.var)->node;
1466 unsigned HOST_WIDE_INT roff = c->rhs.offset;
1467 bitmap sol = get_varinfo (rhs)->solution;
1468 unsigned int j;
1469 bitmap_iterator bi;
1471 /* For each member j of delta (Sol(x)), add an edge from y to j and
1472 union Sol(y) into Sol(j) */
1473 EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
1475 unsigned HOST_WIDE_INT loff = c->lhs.offset;
1476 if (type_safe (j, &loff) && !(get_varinfo(j)->is_special_var))
1478 varinfo_t v;
1479 unsigned int t;
1480 unsigned HOST_WIDE_INT fieldoffset = get_varinfo (j)->offset + loff;
1482 v = first_vi_for_offset (get_varinfo (j), fieldoffset);
1483 if (!v)
1484 continue;
1485 t = v->node;
1486 if (int_add_graph_edge (graph, t, rhs, roff))
1488 bitmap tmp = get_varinfo (t)->solution;
1489 if (set_union_with_increment (tmp, sol, roff))
1491 get_varinfo (t)->solution = tmp;
1492 if (t == rhs)
1494 sol = get_varinfo (rhs)->solution;
1496 if (!TEST_BIT (changed, t))
1498 SET_BIT (changed, t);
1499 changed_count++;
1504 else if (dump_file && !(get_varinfo (j)->is_special_var))
1505 fprintf (dump_file, "Untypesafe usage in do_ds_constraint\n");
1509 /* Handle a non-simple (simple meaning requires no iteration), non-copy
1510 constraint (IE *x = &y, x = *y, and *x = y). */
1512 static void
1513 do_complex_constraint (constraint_graph_t graph, constraint_t c, bitmap delta)
1515 if (c->lhs.type == DEREF)
1517 if (c->rhs.type == ADDRESSOF)
1519 /* *x = &y */
1520 do_da_constraint (graph, c, delta);
1522 else
1524 /* *x = y */
1525 do_ds_constraint (graph, c, delta);
1528 else
1530 /* x = *y */
1531 if (!(get_varinfo (c->lhs.var)->is_special_var))
1532 do_sd_constraint (graph, c, delta);
1536 /* Initialize and return a new SCC info structure. */
1538 static struct scc_info *
1539 init_scc_info (void)
1541 struct scc_info *si = xmalloc (sizeof (struct scc_info));
1542 size_t size = VEC_length (varinfo_t, varmap);
1544 si->current_index = 0;
1545 si->visited = sbitmap_alloc (size);
1546 sbitmap_zero (si->visited);
1547 si->in_component = sbitmap_alloc (size);
1548 sbitmap_ones (si->in_component);
1549 si->visited_index = xcalloc (sizeof (unsigned int), size + 1);
1550 si->scc_stack = VEC_alloc (unsigned, heap, 1);
1551 si->unification_queue = VEC_alloc (unsigned, heap, 1);
1552 return si;
1555 /* Free an SCC info structure pointed to by SI */
1557 static void
1558 free_scc_info (struct scc_info *si)
1560 sbitmap_free (si->visited);
1561 sbitmap_free (si->in_component);
1562 free (si->visited_index);
1563 VEC_free (unsigned, heap, si->scc_stack);
1564 VEC_free (unsigned, heap, si->unification_queue);
1565 free(si);
1569 /* Find cycles in GRAPH that occur, using strongly connected components, and
1570 collapse the cycles into a single representative node. if UPDATE_CHANGED
1571 is true, then update the changed sbitmap to note those nodes whose
1572 solutions have changed as a result of collapsing. */
1574 static void
1575 find_and_collapse_graph_cycles (constraint_graph_t graph, bool update_changed)
1577 unsigned int i;
1578 unsigned int size = VEC_length (varinfo_t, varmap);
1579 struct scc_info *si = init_scc_info ();
1581 for (i = 0; i != size; ++i)
1582 if (!TEST_BIT (si->visited, i) && get_varinfo (i)->node == i)
1583 scc_visit (graph, si, i);
1584 process_unification_queue (graph, si, update_changed);
1585 free_scc_info (si);
1588 /* Compute a topological ordering for GRAPH, and store the result in the
1589 topo_info structure TI. */
1591 static void
1592 compute_topo_order (constraint_graph_t graph,
1593 struct topo_info *ti)
1595 unsigned int i;
1596 unsigned int size = VEC_length (varinfo_t, varmap);
1598 for (i = 0; i != size; ++i)
1599 if (!TEST_BIT (ti->visited, i) && get_varinfo (i)->node == i)
1600 topo_visit (graph, ti, i);
1603 /* Return true if bitmap B is empty, or a bitmap other than bit 0 is set. */
1605 static bool
1606 bitmap_other_than_zero_bit_set (bitmap b)
1608 unsigned int i;
1609 bitmap_iterator bi;
1611 if (bitmap_empty_p (b))
1612 return false;
1613 EXECUTE_IF_SET_IN_BITMAP (b, 1, i, bi)
1614 return true;
1615 return false;
1618 /* Perform offline variable substitution.
1620 This is a linear time way of identifying variables that must have
1621 equivalent points-to sets, including those caused by static cycles,
1622 and single entry subgraphs, in the constraint graph.
1624 The technique is described in "Off-line variable substitution for
1625 scaling points-to analysis" by Atanas Rountev and Satish Chandra,
1626 in "ACM SIGPLAN Notices" volume 35, number 5, pages 47-56. */
1628 static void
1629 perform_var_substitution (constraint_graph_t graph)
1631 struct topo_info *ti = init_topo_info ();
1633 /* Compute the topological ordering of the graph, then visit each
1634 node in topological order. */
1635 compute_topo_order (graph, ti);
1637 while (VEC_length (unsigned, ti->topo_order) != 0)
1639 unsigned int i = VEC_pop (unsigned, ti->topo_order);
1640 unsigned int pred;
1641 varinfo_t vi = get_varinfo (i);
1642 bool okay_to_elim = false;
1643 unsigned int root = VEC_length (varinfo_t, varmap);
1644 VEC(constraint_edge_t,heap) *predvec = graph->preds[i];
1645 constraint_edge_t ce;
1646 bitmap tmp;
1648 /* We can't eliminate things whose address is taken, or which is
1649 the target of a dereference. */
1650 if (vi->address_taken || vi->indirect_target)
1651 continue;
1653 /* See if all predecessors of I are ripe for elimination */
1654 for (pred = 0; VEC_iterate (constraint_edge_t, predvec, pred, ce); pred++)
1656 bitmap weight;
1657 unsigned int w;
1658 weight = get_graph_weights (graph, *ce);
1660 /* We can't eliminate variables that have nonzero weighted
1661 edges between them. */
1662 if (bitmap_other_than_zero_bit_set (weight))
1664 okay_to_elim = false;
1665 break;
1667 w = get_varinfo (ce->dest)->node;
1669 /* We can't eliminate the node if one of the predecessors is
1670 part of a different strongly connected component. */
1671 if (!okay_to_elim)
1673 root = w;
1674 okay_to_elim = true;
1676 else if (w != root)
1678 okay_to_elim = false;
1679 break;
1682 /* Theorem 4 in Rountev and Chandra: If i is a direct node,
1683 then Solution(i) is a subset of Solution (w), where w is a
1684 predecessor in the graph.
1685 Corollary: If all predecessors of i have the same
1686 points-to set, then i has that same points-to set as
1687 those predecessors. */
1688 tmp = BITMAP_ALLOC (NULL);
1689 bitmap_and_compl (tmp, get_varinfo (i)->solution,
1690 get_varinfo (w)->solution);
1691 if (!bitmap_empty_p (tmp))
1693 okay_to_elim = false;
1694 BITMAP_FREE (tmp);
1695 break;
1697 BITMAP_FREE (tmp);
1700 /* See if the root is different than the original node.
1701 If so, we've found an equivalence. */
1702 if (root != get_varinfo (i)->node && okay_to_elim)
1704 /* Found an equivalence */
1705 get_varinfo (i)->node = root;
1706 collapse_nodes (graph, root, i);
1707 if (dump_file && (dump_flags & TDF_DETAILS))
1708 fprintf (dump_file, "Collapsing %s into %s\n",
1709 get_varinfo (i)->name,
1710 get_varinfo (root)->name);
1711 stats.collapsed_vars++;
1715 free_topo_info (ti);
1719 /* Solve the constraint graph GRAPH using our worklist solver.
1720 This is based on the PW* family of solvers from the "Efficient Field
1721 Sensitive Pointer Analysis for C" paper.
1722 It works by iterating over all the graph nodes, processing the complex
1723 constraints and propagating the copy constraints, until everything stops
1724 changed. This corresponds to steps 6-8 in the solving list given above. */
1726 static void
1727 solve_graph (constraint_graph_t graph)
1729 unsigned int size = VEC_length (varinfo_t, varmap);
1730 unsigned int i;
1732 changed_count = size;
1733 changed = sbitmap_alloc (size);
1734 sbitmap_ones (changed);
1736 /* The already collapsed/unreachable nodes will never change, so we
1737 need to account for them in changed_count. */
1738 for (i = 0; i < size; i++)
1739 if (get_varinfo (i)->node != i)
1740 changed_count--;
1742 while (changed_count > 0)
1744 unsigned int i;
1745 struct topo_info *ti = init_topo_info ();
1746 stats.iterations++;
1748 bitmap_obstack_initialize (&iteration_obstack);
1750 if (edge_added)
1752 /* We already did cycle elimination once, when we did
1753 variable substitution, so we don't need it again for the
1754 first iteration. */
1755 if (stats.iterations > 1)
1756 find_and_collapse_graph_cycles (graph, true);
1758 edge_added = false;
1761 compute_topo_order (graph, ti);
1763 while (VEC_length (unsigned, ti->topo_order) != 0)
1765 i = VEC_pop (unsigned, ti->topo_order);
1766 gcc_assert (get_varinfo (i)->node == i);
1768 /* If the node has changed, we need to process the
1769 complex constraints and outgoing edges again. */
1770 if (TEST_BIT (changed, i))
1772 unsigned int j;
1773 constraint_t c;
1774 constraint_edge_t e;
1775 bitmap solution;
1776 VEC(constraint_t,heap) *complex = get_varinfo (i)->complex;
1777 VEC(constraint_edge_t,heap) *succs;
1779 RESET_BIT (changed, i);
1780 changed_count--;
1782 /* Process the complex constraints */
1783 solution = get_varinfo (i)->solution;
1784 for (j = 0; VEC_iterate (constraint_t, complex, j, c); j++)
1785 do_complex_constraint (graph, c, solution);
1787 /* Propagate solution to all successors. */
1788 succs = graph->succs[i];
1789 for (j = 0; VEC_iterate (constraint_edge_t, succs, j, e); j++)
1791 bitmap tmp = get_varinfo (e->dest)->solution;
1792 bool flag = false;
1793 unsigned int k;
1794 bitmap weights = e->weights;
1795 bitmap_iterator bi;
1797 gcc_assert (!bitmap_empty_p (weights));
1798 EXECUTE_IF_SET_IN_BITMAP (weights, 0, k, bi)
1799 flag |= set_union_with_increment (tmp, solution, k);
1801 if (flag)
1803 get_varinfo (e->dest)->solution = tmp;
1804 if (!TEST_BIT (changed, e->dest))
1806 SET_BIT (changed, e->dest);
1807 changed_count++;
1813 free_topo_info (ti);
1814 bitmap_obstack_release (&iteration_obstack);
1817 sbitmap_free (changed);
1821 /* CONSTRAINT AND VARIABLE GENERATION FUNCTIONS */
1823 /* Map from trees to variable ids. */
1824 static htab_t id_for_tree;
1826 typedef struct tree_id
1828 tree t;
1829 unsigned int id;
1830 } *tree_id_t;
1832 /* Hash a tree id structure. */
1834 static hashval_t
1835 tree_id_hash (const void *p)
1837 const tree_id_t ta = (tree_id_t) p;
1838 return htab_hash_pointer (ta->t);
1841 /* Return true if the tree in P1 and the tree in P2 are the same. */
1843 static int
1844 tree_id_eq (const void *p1, const void *p2)
1846 const tree_id_t ta1 = (tree_id_t) p1;
1847 const tree_id_t ta2 = (tree_id_t) p2;
1848 return ta1->t == ta2->t;
1851 /* Insert ID as the variable id for tree T in the hashtable. */
1853 static void
1854 insert_id_for_tree (tree t, int id)
1856 void **slot;
1857 struct tree_id finder;
1858 tree_id_t new_pair;
1860 finder.t = t;
1861 slot = htab_find_slot (id_for_tree, &finder, INSERT);
1862 gcc_assert (*slot == NULL);
1863 new_pair = xmalloc (sizeof (struct tree_id));
1864 new_pair->t = t;
1865 new_pair->id = id;
1866 *slot = (void *)new_pair;
1869 /* Find the variable id for tree T in ID_FOR_TREE. If T does not
1870 exist in the hash table, return false, otherwise, return true and
1871 set *ID to the id we found. */
1873 static bool
1874 lookup_id_for_tree (tree t, unsigned int *id)
1876 tree_id_t pair;
1877 struct tree_id finder;
1879 finder.t = t;
1880 pair = htab_find (id_for_tree, &finder);
1881 if (pair == NULL)
1882 return false;
1883 *id = pair->id;
1884 return true;
1887 /* Return a printable name for DECL */
1889 static const char *
1890 alias_get_name (tree decl)
1892 const char *res = get_name (decl);
1893 char *temp;
1894 int num_printed = 0;
1896 if (res != NULL)
1897 return res;
1899 res = "NULL";
1900 if (TREE_CODE (decl) == SSA_NAME)
1902 num_printed = asprintf (&temp, "%s_%u",
1903 alias_get_name (SSA_NAME_VAR (decl)),
1904 SSA_NAME_VERSION (decl));
1906 else if (DECL_P (decl))
1908 num_printed = asprintf (&temp, "D.%u", DECL_UID (decl));
1910 if (num_printed > 0)
1912 res = ggc_strdup (temp);
1913 free (temp);
1915 return res;
1918 /* Find the variable id for tree T in the hashtable.
1919 If T doesn't exist in the hash table, create an entry for it. */
1921 static unsigned int
1922 get_id_for_tree (tree t)
1924 tree_id_t pair;
1925 struct tree_id finder;
1927 finder.t = t;
1928 pair = htab_find (id_for_tree, &finder);
1929 if (pair == NULL)
1930 return create_variable_info_for (t, alias_get_name (t));
1932 return pair->id;
1935 /* Get a constraint expression from an SSA_VAR_P node. */
1937 static struct constraint_expr
1938 get_constraint_exp_from_ssa_var (tree t)
1940 struct constraint_expr cexpr;
1942 gcc_assert (SSA_VAR_P (t) || DECL_P (t));
1944 /* For parameters, get at the points-to set for the actual parm
1945 decl. */
1946 if (TREE_CODE (t) == SSA_NAME
1947 && TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL
1948 && default_def (SSA_NAME_VAR (t)) == t)
1949 return get_constraint_exp_from_ssa_var (SSA_NAME_VAR (t));
1951 cexpr.type = SCALAR;
1953 cexpr.var = get_id_for_tree (t);
1954 /* If we determine the result is "anything", and we know this is readonly,
1955 say it points to readonly memory instead. */
1956 if (cexpr.var == anything_id && TREE_READONLY (t))
1958 cexpr.type = ADDRESSOF;
1959 cexpr.var = readonly_id;
1962 cexpr.offset = 0;
1963 return cexpr;
1966 /* Process a completed constraint T, and add it to the constraint
1967 list. */
1969 static void
1970 process_constraint (constraint_t t)
1972 struct constraint_expr rhs = t->rhs;
1973 struct constraint_expr lhs = t->lhs;
1975 gcc_assert (rhs.var < VEC_length (varinfo_t, varmap));
1976 gcc_assert (lhs.var < VEC_length (varinfo_t, varmap));
1978 /* ANYTHING == ANYTHING is pointless. */
1979 if (lhs.var == anything_id && rhs.var == anything_id)
1980 return;
1982 /* If we have &ANYTHING = something, convert to SOMETHING = &ANYTHING) */
1983 else if (lhs.var == anything_id && lhs.type == ADDRESSOF)
1985 rhs = t->lhs;
1986 t->lhs = t->rhs;
1987 t->rhs = rhs;
1988 process_constraint (t);
1990 /* This can happen in our IR with things like n->a = *p */
1991 else if (rhs.type == DEREF && lhs.type == DEREF && rhs.var != anything_id)
1993 /* Split into tmp = *rhs, *lhs = tmp */
1994 tree rhsdecl = get_varinfo (rhs.var)->decl;
1995 tree pointertype = TREE_TYPE (rhsdecl);
1996 tree pointedtotype = TREE_TYPE (pointertype);
1997 tree tmpvar = create_tmp_var_raw (pointedtotype, "doubledereftmp");
1998 struct constraint_expr tmplhs = get_constraint_exp_from_ssa_var (tmpvar);
2000 /* If this is an aggregate of known size, we should have passed
2001 this off to do_structure_copy, and it should have broken it
2002 up. */
2003 gcc_assert (!AGGREGATE_TYPE_P (pointedtotype)
2004 || get_varinfo (rhs.var)->is_unknown_size_var);
2006 process_constraint (new_constraint (tmplhs, rhs));
2007 process_constraint (new_constraint (lhs, tmplhs));
2009 else if (rhs.type == ADDRESSOF)
2011 varinfo_t vi;
2012 gcc_assert (rhs.offset == 0);
2014 for (vi = get_varinfo (rhs.var); vi != NULL; vi = vi->next)
2015 vi->address_taken = true;
2017 VEC_safe_push (constraint_t, heap, constraints, t);
2019 else
2021 if (lhs.type != DEREF && rhs.type == DEREF)
2022 get_varinfo (lhs.var)->indirect_target = true;
2023 VEC_safe_push (constraint_t, heap, constraints, t);
2028 /* Return the position, in bits, of FIELD_DECL from the beginning of its
2029 structure. */
2031 static unsigned HOST_WIDE_INT
2032 bitpos_of_field (const tree fdecl)
2035 if (TREE_CODE (DECL_FIELD_OFFSET (fdecl)) != INTEGER_CST
2036 || TREE_CODE (DECL_FIELD_BIT_OFFSET (fdecl)) != INTEGER_CST)
2037 return -1;
2039 return (tree_low_cst (DECL_FIELD_OFFSET (fdecl), 1) * 8)
2040 + tree_low_cst (DECL_FIELD_BIT_OFFSET (fdecl), 1);
2044 /* Return true if an access to [ACCESSPOS, ACCESSSIZE]
2045 overlaps with a field at [FIELDPOS, FIELDSIZE] */
2047 static bool
2048 offset_overlaps_with_access (const unsigned HOST_WIDE_INT fieldpos,
2049 const unsigned HOST_WIDE_INT fieldsize,
2050 const unsigned HOST_WIDE_INT accesspos,
2051 const unsigned HOST_WIDE_INT accesssize)
2053 if (fieldpos == accesspos && fieldsize == accesssize)
2054 return true;
2055 if (accesspos >= fieldpos && accesspos < (fieldpos + fieldsize))
2056 return true;
2057 if (accesspos < fieldpos && (accesspos + accesssize > fieldpos))
2058 return true;
2060 return false;
2063 /* Given a COMPONENT_REF T, return the constraint_expr for it. */
2065 static struct constraint_expr
2066 get_constraint_for_component_ref (tree t, bool *need_anyoffset)
2068 struct constraint_expr result;
2069 HOST_WIDE_INT bitsize = -1;
2070 HOST_WIDE_INT bitpos;
2071 tree offset = NULL_TREE;
2072 enum machine_mode mode;
2073 int unsignedp;
2074 int volatilep;
2075 tree forzero;
2077 result.offset = 0;
2078 result.type = SCALAR;
2079 result.var = 0;
2081 /* Some people like to do cute things like take the address of
2082 &0->a.b */
2083 forzero = t;
2084 while (!SSA_VAR_P (forzero) && !CONSTANT_CLASS_P (forzero))
2085 forzero = TREE_OPERAND (forzero, 0);
2087 if (CONSTANT_CLASS_P (forzero) && integer_zerop (forzero))
2089 result.offset = 0;
2090 result.var = integer_id;
2091 result.type = SCALAR;
2092 return result;
2095 t = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
2096 &unsignedp, &volatilep, false);
2097 result = get_constraint_for (t, need_anyoffset);
2099 /* This can also happen due to weird offsetof type macros. */
2100 if (TREE_CODE (t) != ADDR_EXPR && result.type == ADDRESSOF)
2101 result.type = SCALAR;
2103 /* If we know where this goes, then yay. Otherwise, booo. */
2105 if (offset == NULL && bitsize != -1)
2107 result.offset = bitpos;
2109 else if (need_anyoffset)
2111 result.offset = 0;
2112 *need_anyoffset = true;
2114 else
2116 result.var = anything_id;
2117 result.offset = 0;
2120 if (result.type == SCALAR)
2122 /* In languages like C, you can access one past the end of an
2123 array. You aren't allowed to dereference it, so we can
2124 ignore this constraint. When we handle pointer subtraction,
2125 we may have to do something cute here. */
2127 if (result.offset < get_varinfo (result.var)->fullsize)
2129 /* It's also not true that the constraint will actually start at the
2130 right offset, it may start in some padding. We only care about
2131 setting the constraint to the first actual field it touches, so
2132 walk to find it. */
2133 varinfo_t curr;
2134 for (curr = get_varinfo (result.var); curr; curr = curr->next)
2136 if (offset_overlaps_with_access (curr->offset, curr->size,
2137 result.offset, bitsize))
2139 result.var = curr->id;
2140 break;
2144 /* assert that we found *some* field there. The user couldn't be
2145 accessing *only* padding. */
2147 gcc_assert (curr);
2149 else
2150 if (dump_file && (dump_flags & TDF_DETAILS))
2151 fprintf (dump_file, "Access to past the end of variable, ignoring\n");
2153 result.offset = 0;
2156 return result;
2160 /* Dereference the constraint expression CONS, and return the result.
2161 DEREF (ADDRESSOF) = SCALAR
2162 DEREF (SCALAR) = DEREF
2163 DEREF (DEREF) = (temp = DEREF1; result = DEREF(temp))
2164 This is needed so that we can handle dereferencing DEREF constraints. */
2166 static struct constraint_expr
2167 do_deref (struct constraint_expr cons)
2169 if (cons.type == SCALAR)
2171 cons.type = DEREF;
2172 return cons;
2174 else if (cons.type == ADDRESSOF)
2176 cons.type = SCALAR;
2177 return cons;
2179 else if (cons.type == DEREF)
2181 tree tmpvar = create_tmp_var_raw (ptr_type_node, "derefmp");
2182 struct constraint_expr tmplhs = get_constraint_exp_from_ssa_var (tmpvar);
2183 process_constraint (new_constraint (tmplhs, cons));
2184 cons.var = tmplhs.var;
2185 return cons;
2187 gcc_unreachable ();
2191 /* Given a tree T, return the constraint expression for it. */
2193 static struct constraint_expr
2194 get_constraint_for (tree t, bool *need_anyoffset)
2196 struct constraint_expr temp;
2198 /* x = integer is all glommed to a single variable, which doesn't
2199 point to anything by itself. That is, of course, unless it is an
2200 integer constant being treated as a pointer, in which case, we
2201 will return that this is really the addressof anything. This
2202 happens below, since it will fall into the default case. The only
2203 case we know something about an integer treated like a pointer is
2204 when it is the NULL pointer, and then we just say it points to
2205 NULL. */
2206 if (TREE_CODE (t) == INTEGER_CST
2207 && !POINTER_TYPE_P (TREE_TYPE (t)))
2209 temp.var = integer_id;
2210 temp.type = SCALAR;
2211 temp.offset = 0;
2212 return temp;
2214 else if (TREE_CODE (t) == INTEGER_CST
2215 && integer_zerop (t))
2217 temp.var = nothing_id;
2218 temp.type = ADDRESSOF;
2219 temp.offset = 0;
2220 return temp;
2223 switch (TREE_CODE_CLASS (TREE_CODE (t)))
2225 case tcc_expression:
2227 switch (TREE_CODE (t))
2229 case ADDR_EXPR:
2231 temp = get_constraint_for (TREE_OPERAND (t, 0), need_anyoffset);
2232 if (temp.type == DEREF)
2233 temp.type = SCALAR;
2234 else
2235 temp.type = ADDRESSOF;
2236 return temp;
2238 break;
2239 case CALL_EXPR:
2241 /* XXX: In interprocedural mode, if we didn't have the
2242 body, we would need to do *each pointer argument =
2243 &ANYTHING added. */
2244 if (call_expr_flags (t) & (ECF_MALLOC | ECF_MAY_BE_ALLOCA))
2246 varinfo_t vi;
2247 tree heapvar = heapvar_lookup (t);
2249 if (heapvar == NULL)
2251 heapvar = create_tmp_var_raw (ptr_type_node, "HEAP");
2252 DECL_EXTERNAL (heapvar) = 1;
2253 add_referenced_tmp_var (heapvar);
2254 heapvar_insert (t, heapvar);
2257 temp.var = create_variable_info_for (heapvar,
2258 alias_get_name (heapvar));
2260 vi = get_varinfo (temp.var);
2261 vi->is_artificial_var = 1;
2262 vi->is_heap_var = 1;
2263 temp.type = ADDRESSOF;
2264 temp.offset = 0;
2265 return temp;
2267 /* FALLTHRU */
2268 default:
2270 temp.type = ADDRESSOF;
2271 temp.var = anything_id;
2272 temp.offset = 0;
2273 return temp;
2277 case tcc_reference:
2279 switch (TREE_CODE (t))
2281 case INDIRECT_REF:
2283 temp = get_constraint_for (TREE_OPERAND (t, 0), need_anyoffset);
2284 temp = do_deref (temp);
2285 return temp;
2287 case ARRAY_REF:
2288 case ARRAY_RANGE_REF:
2289 case COMPONENT_REF:
2290 temp = get_constraint_for_component_ref (t, need_anyoffset);
2291 return temp;
2292 default:
2294 temp.type = ADDRESSOF;
2295 temp.var = anything_id;
2296 temp.offset = 0;
2297 return temp;
2301 case tcc_unary:
2303 switch (TREE_CODE (t))
2305 case NOP_EXPR:
2306 case CONVERT_EXPR:
2307 case NON_LVALUE_EXPR:
2309 tree op = TREE_OPERAND (t, 0);
2311 /* Cast from non-pointer to pointers are bad news for us.
2312 Anything else, we see through */
2313 if (!(POINTER_TYPE_P (TREE_TYPE (t))
2314 && ! POINTER_TYPE_P (TREE_TYPE (op))))
2315 return get_constraint_for (op, need_anyoffset);
2317 /* FALLTHRU */
2319 default:
2321 temp.type = ADDRESSOF;
2322 temp.var = anything_id;
2323 temp.offset = 0;
2324 return temp;
2328 case tcc_exceptional:
2330 switch (TREE_CODE (t))
2332 case PHI_NODE:
2333 return get_constraint_for (PHI_RESULT (t), need_anyoffset);
2334 case SSA_NAME:
2335 return get_constraint_exp_from_ssa_var (t);
2336 default:
2338 temp.type = ADDRESSOF;
2339 temp.var = anything_id;
2340 temp.offset = 0;
2341 return temp;
2345 case tcc_declaration:
2346 return get_constraint_exp_from_ssa_var (t);
2347 default:
2349 temp.type = ADDRESSOF;
2350 temp.var = anything_id;
2351 temp.offset = 0;
2352 return temp;
2358 /* Handle the structure copy case where we have a simple structure copy
2359 between LHS and RHS that is of SIZE (in bits)
2361 For each field of the lhs variable (lhsfield)
2362 For each field of the rhs variable at lhsfield.offset (rhsfield)
2363 add the constraint lhsfield = rhsfield
2365 If we fail due to some kind of type unsafety or other thing we
2366 can't handle, return false. We expect the caller to collapse the
2367 variable in that case. */
2369 static bool
2370 do_simple_structure_copy (const struct constraint_expr lhs,
2371 const struct constraint_expr rhs,
2372 const unsigned HOST_WIDE_INT size)
2374 varinfo_t p = get_varinfo (lhs.var);
2375 unsigned HOST_WIDE_INT pstart, last;
2376 pstart = p->offset;
2377 last = p->offset + size;
2378 for (; p && p->offset < last; p = p->next)
2380 varinfo_t q;
2381 struct constraint_expr templhs = lhs;
2382 struct constraint_expr temprhs = rhs;
2383 unsigned HOST_WIDE_INT fieldoffset;
2385 templhs.var = p->id;
2386 q = get_varinfo (temprhs.var);
2387 fieldoffset = p->offset - pstart;
2388 q = first_vi_for_offset (q, q->offset + fieldoffset);
2389 if (!q)
2390 return false;
2391 temprhs.var = q->id;
2392 process_constraint (new_constraint (templhs, temprhs));
2394 return true;
2398 /* Handle the structure copy case where we have a structure copy between a
2399 aggregate on the LHS and a dereference of a pointer on the RHS
2400 that is of SIZE (in bits)
2402 For each field of the lhs variable (lhsfield)
2403 rhs.offset = lhsfield->offset
2404 add the constraint lhsfield = rhs
2407 static void
2408 do_rhs_deref_structure_copy (const struct constraint_expr lhs,
2409 const struct constraint_expr rhs,
2410 const unsigned HOST_WIDE_INT size)
2412 varinfo_t p = get_varinfo (lhs.var);
2413 unsigned HOST_WIDE_INT pstart,last;
2414 pstart = p->offset;
2415 last = p->offset + size;
2417 for (; p && p->offset < last; p = p->next)
2419 varinfo_t q;
2420 struct constraint_expr templhs = lhs;
2421 struct constraint_expr temprhs = rhs;
2422 unsigned HOST_WIDE_INT fieldoffset;
2425 if (templhs.type == SCALAR)
2426 templhs.var = p->id;
2427 else
2428 templhs.offset = p->offset;
2430 q = get_varinfo (temprhs.var);
2431 fieldoffset = p->offset - pstart;
2432 temprhs.offset += fieldoffset;
2433 process_constraint (new_constraint (templhs, temprhs));
2437 /* Handle the structure copy case where we have a structure copy
2438 between a aggregate on the RHS and a dereference of a pointer on
2439 the LHS that is of SIZE (in bits)
2441 For each field of the rhs variable (rhsfield)
2442 lhs.offset = rhsfield->offset
2443 add the constraint lhs = rhsfield
2446 static void
2447 do_lhs_deref_structure_copy (const struct constraint_expr lhs,
2448 const struct constraint_expr rhs,
2449 const unsigned HOST_WIDE_INT size)
2451 varinfo_t p = get_varinfo (rhs.var);
2452 unsigned HOST_WIDE_INT pstart,last;
2453 pstart = p->offset;
2454 last = p->offset + size;
2456 for (; p && p->offset < last; p = p->next)
2458 varinfo_t q;
2459 struct constraint_expr templhs = lhs;
2460 struct constraint_expr temprhs = rhs;
2461 unsigned HOST_WIDE_INT fieldoffset;
2464 if (temprhs.type == SCALAR)
2465 temprhs.var = p->id;
2466 else
2467 temprhs.offset = p->offset;
2469 q = get_varinfo (templhs.var);
2470 fieldoffset = p->offset - pstart;
2471 templhs.offset += fieldoffset;
2472 process_constraint (new_constraint (templhs, temprhs));
2476 /* Sometimes, frontends like to give us bad type information. This
2477 function will collapse all the fields from VAR to the end of VAR,
2478 into VAR, so that we treat those fields as a single variable.
2479 We return the variable they were collapsed into. */
2481 static unsigned int
2482 collapse_rest_of_var (unsigned int var)
2484 varinfo_t currvar = get_varinfo (var);
2485 varinfo_t field;
2487 for (field = currvar->next; field; field = field->next)
2489 if (dump_file)
2490 fprintf (dump_file, "Type safety: Collapsing var %s into %s\n",
2491 field->name, currvar->name);
2493 gcc_assert (!field->collapsed_to);
2494 field->collapsed_to = currvar;
2497 currvar->next = NULL;
2498 currvar->size = currvar->fullsize - currvar->offset;
2500 return currvar->id;
2503 /* Handle aggregate copies by expanding into copies of the respective
2504 fields of the structures. */
2506 static void
2507 do_structure_copy (tree lhsop, tree rhsop)
2509 struct constraint_expr lhs, rhs, tmp;
2510 varinfo_t p;
2511 unsigned HOST_WIDE_INT lhssize;
2512 unsigned HOST_WIDE_INT rhssize;
2514 lhs = get_constraint_for (lhsop, NULL);
2515 rhs = get_constraint_for (rhsop, NULL);
2517 /* If we have special var = x, swap it around. */
2518 if (lhs.var <= integer_id && !(get_varinfo (rhs.var)->is_special_var))
2520 tmp = lhs;
2521 lhs = rhs;
2522 rhs = tmp;
2525 /* This is fairly conservative for the RHS == ADDRESSOF case, in that it's
2526 possible it's something we could handle. However, most cases falling
2527 into this are dealing with transparent unions, which are slightly
2528 weird. */
2529 if (rhs.type == ADDRESSOF && !(get_varinfo (rhs.var)->is_special_var))
2531 rhs.type = ADDRESSOF;
2532 rhs.var = anything_id;
2535 /* If the RHS is a special var, or an addressof, set all the LHS fields to
2536 that special var. */
2537 if (rhs.var <= integer_id)
2539 for (p = get_varinfo (lhs.var); p; p = p->next)
2541 struct constraint_expr templhs = lhs;
2542 struct constraint_expr temprhs = rhs;
2543 if (templhs.type == SCALAR )
2544 templhs.var = p->id;
2545 else
2546 templhs.offset += p->offset;
2547 process_constraint (new_constraint (templhs, temprhs));
2550 else
2552 tree rhstype = TREE_TYPE (rhsop);
2553 tree lhstype = TREE_TYPE (lhsop);
2554 tree rhstypesize = TYPE_SIZE (rhstype);
2555 tree lhstypesize = TYPE_SIZE (lhstype);
2557 /* If we have a variably sized types on the rhs or lhs, and a deref
2558 constraint, add the constraint, lhsconstraint = &ANYTHING.
2559 This is conservatively correct because either the lhs is an unknown
2560 sized var (if the constraint is SCALAR), or the lhs is a DEREF
2561 constraint, and every variable it can point to must be unknown sized
2562 anyway, so we don't need to worry about fields at all. */
2563 if ((rhs.type == DEREF && TREE_CODE (rhstypesize) != INTEGER_CST)
2564 || (lhs.type == DEREF && TREE_CODE (lhstypesize) != INTEGER_CST))
2566 rhs.var = anything_id;
2567 rhs.type = ADDRESSOF;
2568 rhs.offset = 0;
2569 process_constraint (new_constraint (lhs, rhs));
2570 return;
2573 /* The size only really matters insofar as we don't set more or less of
2574 the variable. If we hit an unknown size var, the size should be the
2575 whole darn thing. */
2576 if (get_varinfo (rhs.var)->is_unknown_size_var)
2577 rhssize = ~0;
2578 else
2579 rhssize = TREE_INT_CST_LOW (rhstypesize);
2581 if (get_varinfo (lhs.var)->is_unknown_size_var)
2582 lhssize = ~0;
2583 else
2584 lhssize = TREE_INT_CST_LOW (lhstypesize);
2587 if (rhs.type == SCALAR && lhs.type == SCALAR)
2589 if (!do_simple_structure_copy (lhs, rhs, MIN (lhssize, rhssize)))
2591 lhs.var = collapse_rest_of_var (lhs.var);
2592 rhs.var = collapse_rest_of_var (rhs.var);
2593 lhs.offset = 0;
2594 rhs.offset = 0;
2595 lhs.type = SCALAR;
2596 rhs.type = SCALAR;
2597 process_constraint (new_constraint (lhs, rhs));
2600 else if (lhs.type != DEREF && rhs.type == DEREF)
2601 do_rhs_deref_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
2602 else if (lhs.type == DEREF && rhs.type != DEREF)
2603 do_lhs_deref_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
2604 else
2606 tree pointedtotype = lhstype;
2607 tree tmpvar;
2609 gcc_assert (rhs.type == DEREF && lhs.type == DEREF);
2610 tmpvar = create_tmp_var_raw (pointedtotype, "structcopydereftmp");
2611 do_structure_copy (tmpvar, rhsop);
2612 do_structure_copy (lhsop, tmpvar);
2617 /* Update related alias information kept in AI. This is used when
2618 building name tags, alias sets and deciding grouping heuristics.
2619 STMT is the statement to process. This function also updates
2620 ADDRESSABLE_VARS. */
2622 static void
2623 update_alias_info (tree stmt, struct alias_info *ai)
2625 bitmap addr_taken;
2626 use_operand_p use_p;
2627 ssa_op_iter iter;
2628 bool stmt_escapes_p = is_escape_site (stmt, ai);
2629 tree op;
2631 /* Mark all the variables whose address are taken by the statement. */
2632 addr_taken = addresses_taken (stmt);
2633 if (addr_taken)
2635 bitmap_ior_into (addressable_vars, addr_taken);
2637 /* If STMT is an escape point, all the addresses taken by it are
2638 call-clobbered. */
2639 if (stmt_escapes_p)
2641 bitmap_iterator bi;
2642 unsigned i;
2644 EXECUTE_IF_SET_IN_BITMAP (addr_taken, 0, i, bi)
2645 mark_call_clobbered (referenced_var (i));
2649 /* Process each operand use. If an operand may be aliased, keep
2650 track of how many times it's being used. For pointers, determine
2651 whether they are dereferenced by the statement, or whether their
2652 value escapes, etc. */
2653 FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
2655 tree op, var;
2656 var_ann_t v_ann;
2657 struct ptr_info_def *pi;
2658 bool is_store, is_potential_deref;
2659 unsigned num_uses, num_derefs;
2661 op = USE_FROM_PTR (use_p);
2663 /* If STMT is a PHI node, OP may be an ADDR_EXPR. If so, add it
2664 to the set of addressable variables. */
2665 if (TREE_CODE (op) == ADDR_EXPR)
2667 gcc_assert (TREE_CODE (stmt) == PHI_NODE);
2669 /* PHI nodes don't have annotations for pinning the set
2670 of addresses taken, so we collect them here.
2672 FIXME, should we allow PHI nodes to have annotations
2673 so that they can be treated like regular statements?
2674 Currently, they are treated as second-class
2675 statements. */
2676 add_to_addressable_set (TREE_OPERAND (op, 0), &addressable_vars);
2677 continue;
2680 /* Ignore constants. */
2681 if (TREE_CODE (op) != SSA_NAME)
2682 continue;
2684 var = SSA_NAME_VAR (op);
2685 v_ann = var_ann (var);
2687 /* If the operand's variable may be aliased, keep track of how
2688 many times we've referenced it. This is used for alias
2689 grouping in compute_flow_insensitive_aliasing. */
2690 if (may_be_aliased (var))
2691 NUM_REFERENCES_INC (v_ann);
2693 /* We are only interested in pointers. */
2694 if (!POINTER_TYPE_P (TREE_TYPE (op)))
2695 continue;
2697 pi = get_ptr_info (op);
2699 /* Add OP to AI->PROCESSED_PTRS, if it's not there already. */
2700 if (!TEST_BIT (ai->ssa_names_visited, SSA_NAME_VERSION (op)))
2702 SET_BIT (ai->ssa_names_visited, SSA_NAME_VERSION (op));
2703 VARRAY_PUSH_TREE (ai->processed_ptrs, op);
2706 /* If STMT is a PHI node, then it will not have pointer
2707 dereferences and it will not be an escape point. */
2708 if (TREE_CODE (stmt) == PHI_NODE)
2709 continue;
2711 /* Determine whether OP is a dereferenced pointer, and if STMT
2712 is an escape point, whether OP escapes. */
2713 count_uses_and_derefs (op, stmt, &num_uses, &num_derefs, &is_store);
2715 /* Handle a corner case involving address expressions of the
2716 form '&PTR->FLD'. The problem with these expressions is that
2717 they do not represent a dereference of PTR. However, if some
2718 other transformation propagates them into an INDIRECT_REF
2719 expression, we end up with '*(&PTR->FLD)' which is folded
2720 into 'PTR->FLD'.
2722 So, if the original code had no other dereferences of PTR,
2723 the aliaser will not create memory tags for it, and when
2724 &PTR->FLD gets propagated to INDIRECT_REF expressions, the
2725 memory operations will receive no V_MAY_DEF/VUSE operands.
2727 One solution would be to have count_uses_and_derefs consider
2728 &PTR->FLD a dereference of PTR. But that is wrong, since it
2729 is not really a dereference but an offset calculation.
2731 What we do here is to recognize these special ADDR_EXPR
2732 nodes. Since these expressions are never GIMPLE values (they
2733 are not GIMPLE invariants), they can only appear on the RHS
2734 of an assignment and their base address is always an
2735 INDIRECT_REF expression. */
2736 is_potential_deref = false;
2737 if (TREE_CODE (stmt) == MODIFY_EXPR
2738 && TREE_CODE (TREE_OPERAND (stmt, 1)) == ADDR_EXPR
2739 && !is_gimple_val (TREE_OPERAND (stmt, 1)))
2741 /* If the RHS if of the form &PTR->FLD and PTR == OP, then
2742 this represents a potential dereference of PTR. */
2743 tree rhs = TREE_OPERAND (stmt, 1);
2744 tree base = get_base_address (TREE_OPERAND (rhs, 0));
2745 if (TREE_CODE (base) == INDIRECT_REF
2746 && TREE_OPERAND (base, 0) == op)
2747 is_potential_deref = true;
2750 if (num_derefs > 0 || is_potential_deref)
2752 /* Mark OP as dereferenced. In a subsequent pass,
2753 dereferenced pointers that point to a set of
2754 variables will be assigned a name tag to alias
2755 all the variables OP points to. */
2756 pi->is_dereferenced = 1;
2758 /* Keep track of how many time we've dereferenced each
2759 pointer. */
2760 NUM_REFERENCES_INC (v_ann);
2762 /* If this is a store operation, mark OP as being
2763 dereferenced to store, otherwise mark it as being
2764 dereferenced to load. */
2765 if (is_store)
2766 bitmap_set_bit (ai->dereferenced_ptrs_store, DECL_UID (var));
2767 else
2768 bitmap_set_bit (ai->dereferenced_ptrs_load, DECL_UID (var));
2771 if (stmt_escapes_p && num_derefs < num_uses)
2773 /* If STMT is an escape point and STMT contains at
2774 least one direct use of OP, then the value of OP
2775 escapes and so the pointed-to variables need to
2776 be marked call-clobbered. */
2777 pi->value_escapes_p = 1;
2779 /* If the statement makes a function call, assume
2780 that pointer OP will be dereferenced in a store
2781 operation inside the called function. */
2782 if (get_call_expr_in (stmt))
2784 bitmap_set_bit (ai->dereferenced_ptrs_store, DECL_UID (var));
2785 pi->is_dereferenced = 1;
2790 if (TREE_CODE (stmt) == PHI_NODE)
2791 return;
2793 /* Update reference counter for definitions to any
2794 potentially aliased variable. This is used in the alias
2795 grouping heuristics. */
2796 FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
2798 tree var = SSA_NAME_VAR (op);
2799 var_ann_t ann = var_ann (var);
2800 bitmap_set_bit (ai->written_vars, DECL_UID (var));
2801 if (may_be_aliased (var))
2802 NUM_REFERENCES_INC (ann);
2806 /* Mark variables in V_MAY_DEF operands as being written to. */
2807 FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_VIRTUAL_DEFS)
2809 tree var = DECL_P (op) ? op : SSA_NAME_VAR (op);
2810 bitmap_set_bit (ai->written_vars, DECL_UID (var));
2815 /* Handle pointer arithmetic EXPR when creating aliasing constraints.
2816 Expressions of the type PTR + CST can be handled in two ways:
2818 1- If the constraint for PTR is ADDRESSOF for a non-structure
2819 variable, then we can use it directly because adding or
2820 subtracting a constant may not alter the original ADDRESSOF
2821 constraint (i.e., pointer arithmetic may not legally go outside
2822 an object's boundaries).
2824 2- If the constraint for PTR is ADDRESSOF for a structure variable,
2825 then if CST is a compile-time constant that can be used as an
2826 offset, we can determine which sub-variable will be pointed-to
2827 by the expression.
2829 Return true if the expression is handled. For any other kind of
2830 expression, return false so that each operand can be added as a
2831 separate constraint by the caller. */
2833 static bool
2834 handle_ptr_arith (struct constraint_expr lhs, tree expr)
2836 tree op0, op1;
2837 struct constraint_expr base, offset;
2839 if (TREE_CODE (expr) != PLUS_EXPR)
2840 return false;
2842 op0 = TREE_OPERAND (expr, 0);
2843 op1 = TREE_OPERAND (expr, 1);
2845 base = get_constraint_for (op0, NULL);
2847 offset.var = anyoffset_id;
2848 offset.type = ADDRESSOF;
2849 offset.offset = 0;
2851 process_constraint (new_constraint (lhs, base));
2852 process_constraint (new_constraint (lhs, offset));
2854 return true;
2858 /* Walk statement T setting up aliasing constraints according to the
2859 references found in T. This function is the main part of the
2860 constraint builder. AI points to auxiliary alias information used
2861 when building alias sets and computing alias grouping heuristics. */
2863 static void
2864 find_func_aliases (tree t, struct alias_info *ai)
2866 struct constraint_expr lhs, rhs;
2868 /* Update various related attributes like escaped addresses, pointer
2869 dereferences for loads and stores. This is used when creating
2870 name tags and alias sets. */
2871 update_alias_info (t, ai);
2873 /* Now build constraints expressions. */
2874 if (TREE_CODE (t) == PHI_NODE)
2876 /* Only care about pointers and structures containing
2877 pointers. */
2878 if (POINTER_TYPE_P (TREE_TYPE (PHI_RESULT (t)))
2879 || AGGREGATE_TYPE_P (TREE_TYPE (PHI_RESULT (t))))
2881 int i;
2883 lhs = get_constraint_for (PHI_RESULT (t), NULL);
2884 for (i = 0; i < PHI_NUM_ARGS (t); i++)
2886 rhs = get_constraint_for (PHI_ARG_DEF (t, i), NULL);
2887 process_constraint (new_constraint (lhs, rhs));
2891 else if (TREE_CODE (t) == MODIFY_EXPR)
2893 tree lhsop = TREE_OPERAND (t, 0);
2894 tree rhsop = TREE_OPERAND (t, 1);
2895 int i;
2897 if (AGGREGATE_TYPE_P (TREE_TYPE (lhsop))
2898 && AGGREGATE_TYPE_P (TREE_TYPE (rhsop)))
2900 do_structure_copy (lhsop, rhsop);
2902 else
2904 /* Only care about operations with pointers, structures
2905 containing pointers, dereferences, and call expressions. */
2906 if (POINTER_TYPE_P (TREE_TYPE (lhsop))
2907 || AGGREGATE_TYPE_P (TREE_TYPE (lhsop))
2908 || TREE_CODE (rhsop) == CALL_EXPR)
2910 lhs = get_constraint_for (lhsop, NULL);
2911 switch (TREE_CODE_CLASS (TREE_CODE (rhsop)))
2913 /* RHS that consist of unary operations,
2914 exceptional types, or bare decls/constants, get
2915 handled directly by get_constraint_for. */
2916 case tcc_reference:
2917 case tcc_declaration:
2918 case tcc_constant:
2919 case tcc_exceptional:
2920 case tcc_expression:
2921 case tcc_unary:
2923 tree anyoffsetrhs = rhsop;
2924 bool need_anyoffset = false;
2925 rhs = get_constraint_for (rhsop, &need_anyoffset);
2926 process_constraint (new_constraint (lhs, rhs));
2928 STRIP_NOPS (anyoffsetrhs);
2929 /* When taking the address of an aggregate
2930 type, from the LHS we can access any field
2931 of the RHS. */
2932 if (need_anyoffset || (rhs.type == ADDRESSOF
2933 && !(get_varinfo (rhs.var)->is_special_var)
2934 && AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (anyoffsetrhs)))))
2936 rhs.var = anyoffset_id;
2937 rhs.type = ADDRESSOF;
2938 rhs.offset = 0;
2939 process_constraint (new_constraint (lhs, rhs));
2942 break;
2944 case tcc_binary:
2946 /* For pointer arithmetic of the form
2947 PTR + CST, we can simply use PTR's
2948 constraint because pointer arithmetic is
2949 not allowed to go out of bounds. */
2950 if (handle_ptr_arith (lhs, rhsop))
2951 break;
2953 /* FALLTHRU */
2955 /* Otherwise, walk each operand. Notice that we
2956 can't use the operand interface because we need
2957 to process expressions other than simple operands
2958 (e.g. INDIRECT_REF, ADDR_EXPR, CALL_EXPR). */
2959 default:
2960 for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (rhsop)); i++)
2962 tree op = TREE_OPERAND (rhsop, i);
2963 rhs = get_constraint_for (op, NULL);
2964 process_constraint (new_constraint (lhs, rhs));
2971 /* After promoting variables and computing aliasing we will
2972 need to re-scan most statements. FIXME: Try to minimize the
2973 number of statements re-scanned. It's not really necessary to
2974 re-scan *all* statements. */
2975 mark_stmt_modified (t);
2979 /* Find the first varinfo in the same variable as START that overlaps with
2980 OFFSET.
2981 Effectively, walk the chain of fields for the variable START to find the
2982 first field that overlaps with OFFSET.
2983 Return NULL if we can't find one. */
2985 static varinfo_t
2986 first_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset)
2988 varinfo_t curr = start;
2989 while (curr)
2991 /* We may not find a variable in the field list with the actual
2992 offset when when we have glommed a structure to a variable.
2993 In that case, however, offset should still be within the size
2994 of the variable. */
2995 if (offset >= curr->offset && offset < (curr->offset + curr->size))
2996 return curr;
2997 curr = curr->next;
2999 return NULL;
3003 /* Insert the varinfo FIELD into the field list for BASE, ordered by
3004 offset. */
3006 static void
3007 insert_into_field_list (varinfo_t base, varinfo_t field)
3009 varinfo_t prev = base;
3010 varinfo_t curr = base->next;
3012 if (curr == NULL)
3014 prev->next = field;
3015 field->next = NULL;
3017 else
3019 while (curr)
3021 if (field->offset <= curr->offset)
3022 break;
3023 prev = curr;
3024 curr = curr->next;
3026 field->next = prev->next;
3027 prev->next = field;
3031 /* qsort comparison function for two fieldoff's PA and PB */
3033 static int
3034 fieldoff_compare (const void *pa, const void *pb)
3036 const fieldoff_s *foa = (const fieldoff_s *)pa;
3037 const fieldoff_s *fob = (const fieldoff_s *)pb;
3038 HOST_WIDE_INT foasize, fobsize;
3040 if (foa->offset != fob->offset)
3041 return foa->offset - fob->offset;
3043 foasize = TREE_INT_CST_LOW (DECL_SIZE (foa->field));
3044 fobsize = TREE_INT_CST_LOW (DECL_SIZE (fob->field));
3045 return foasize - fobsize;
3048 /* Sort a fieldstack according to the field offset and sizes. */
3049 void sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack)
3051 qsort (VEC_address (fieldoff_s, fieldstack),
3052 VEC_length (fieldoff_s, fieldstack),
3053 sizeof (fieldoff_s),
3054 fieldoff_compare);
3057 /* Given a TYPE, and a vector of field offsets FIELDSTACK, push all the fields
3058 of TYPE onto fieldstack, recording their offsets along the way.
3059 OFFSET is used to keep track of the offset in this entire structure, rather
3060 than just the immediately containing structure. Returns the number
3061 of fields pushed.
3062 HAS_UNION is set to true if we find a union type as a field of
3063 TYPE. */
3066 push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
3067 HOST_WIDE_INT offset, bool *has_union)
3069 tree field;
3070 int count = 0;
3072 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
3073 if (TREE_CODE (field) == FIELD_DECL)
3075 bool push = false;
3076 int pushed = 0;
3078 if (has_union
3079 && (TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
3080 || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE))
3081 *has_union = true;
3083 if (!var_can_have_subvars (field))
3084 push = true;
3085 else if (!(pushed = push_fields_onto_fieldstack
3086 (TREE_TYPE (field), fieldstack,
3087 offset + bitpos_of_field (field), has_union))
3088 && DECL_SIZE (field)
3089 && !integer_zerop (DECL_SIZE (field)))
3090 /* Empty structures may have actual size, like in C++. So
3091 see if we didn't push any subfields and the size is
3092 nonzero, push the field onto the stack */
3093 push = true;
3095 if (push)
3097 fieldoff_s *pair;
3099 pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
3100 pair->field = field;
3101 pair->offset = offset + bitpos_of_field (field);
3102 count++;
3104 else
3105 count += pushed;
3108 return count;
3111 static void
3112 make_constraint_to_anything (varinfo_t vi)
3114 struct constraint_expr lhs, rhs;
3116 lhs.var = vi->id;
3117 lhs.offset = 0;
3118 lhs.type = SCALAR;
3120 rhs.var = anything_id;
3121 rhs.offset =0 ;
3122 rhs.type = ADDRESSOF;
3123 process_constraint (new_constraint (lhs, rhs));
3127 /* Return true if FIELDSTACK contains fields that overlap.
3128 FIELDSTACK is assumed to be sorted by offset. */
3130 static bool
3131 check_for_overlaps (VEC (fieldoff_s,heap) *fieldstack)
3133 fieldoff_s *fo = NULL;
3134 unsigned int i;
3135 HOST_WIDE_INT lastoffset = -1;
3137 for (i = 0; VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
3139 if (fo->offset == lastoffset)
3140 return true;
3141 lastoffset = fo->offset;
3143 return false;
3146 /* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
3147 This will also create any varinfo structures necessary for fields
3148 of DECL. */
3150 static unsigned int
3151 create_variable_info_for (tree decl, const char *name)
3153 unsigned int index = VEC_length (varinfo_t, varmap);
3154 varinfo_t vi;
3155 tree decltype = TREE_TYPE (decl);
3156 bool notokay = false;
3157 bool hasunion;
3158 bool is_global = DECL_P (decl) ? is_global_var (decl) : false;
3159 VEC (fieldoff_s,heap) *fieldstack = NULL;
3162 hasunion = TREE_CODE (decltype) == UNION_TYPE
3163 || TREE_CODE (decltype) == QUAL_UNION_TYPE;
3164 if (var_can_have_subvars (decl) && use_field_sensitive && !hasunion)
3166 push_fields_onto_fieldstack (decltype, &fieldstack, 0, &hasunion);
3167 if (hasunion)
3169 VEC_free (fieldoff_s, heap, fieldstack);
3170 notokay = true;
3175 /* If the variable doesn't have subvars, we may end up needing to
3176 sort the field list and create fake variables for all the
3177 fields. */
3178 vi = new_var_info (decl, index, name, index);
3179 vi->decl = decl;
3180 vi->offset = 0;
3181 vi->has_union = hasunion;
3182 if (!TYPE_SIZE (decltype)
3183 || TREE_CODE (TYPE_SIZE (decltype)) != INTEGER_CST
3184 || TREE_CODE (decltype) == ARRAY_TYPE
3185 || TREE_CODE (decltype) == UNION_TYPE
3186 || TREE_CODE (decltype) == QUAL_UNION_TYPE)
3188 vi->is_unknown_size_var = true;
3189 vi->fullsize = ~0;
3190 vi->size = ~0;
3192 else
3194 vi->fullsize = TREE_INT_CST_LOW (TYPE_SIZE (decltype));
3195 vi->size = vi->fullsize;
3198 insert_id_for_tree (vi->decl, index);
3199 VEC_safe_push (varinfo_t, heap, varmap, vi);
3200 if (is_global)
3201 make_constraint_to_anything (vi);
3203 stats.total_vars++;
3204 if (use_field_sensitive
3205 && !notokay
3206 && !vi->is_unknown_size_var
3207 && var_can_have_subvars (decl))
3209 unsigned int newindex = VEC_length (varinfo_t, varmap);
3210 fieldoff_s *fo = NULL;
3211 unsigned int i;
3212 tree field;
3214 for (i = 0; !notokay && VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
3216 if (!DECL_SIZE (fo->field)
3217 || TREE_CODE (DECL_SIZE (fo->field)) != INTEGER_CST
3218 || TREE_CODE (TREE_TYPE (fo->field)) == ARRAY_TYPE
3219 || fo->offset < 0)
3221 notokay = true;
3222 break;
3226 /* We can't sort them if we have a field with a variable sized type,
3227 which will make notokay = true. In that case, we are going to return
3228 without creating varinfos for the fields anyway, so sorting them is a
3229 waste to boot. */
3230 if (!notokay)
3232 sort_fieldstack (fieldstack);
3233 /* Due to some C++ FE issues, like PR 22488, we might end up
3234 what appear to be overlapping fields even though they,
3235 in reality, do not overlap. Until the C++ FE is fixed,
3236 we will simply disable field-sensitivity for these cases. */
3237 notokay = check_for_overlaps (fieldstack);
3241 if (VEC_length (fieldoff_s, fieldstack) != 0)
3242 fo = VEC_index (fieldoff_s, fieldstack, 0);
3244 if (fo == NULL || notokay)
3246 vi->is_unknown_size_var = 1;
3247 vi->fullsize = ~0;
3248 vi->size = ~0;
3249 VEC_free (fieldoff_s, heap, fieldstack);
3250 return index;
3253 field = fo->field;
3254 vi->size = TREE_INT_CST_LOW (DECL_SIZE (field));
3255 vi->offset = fo->offset;
3256 for (i = 1; VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
3258 varinfo_t newvi;
3259 const char *newname;
3260 char *tempname;
3262 field = fo->field;
3263 newindex = VEC_length (varinfo_t, varmap);
3264 asprintf (&tempname, "%s.%s", vi->name, alias_get_name (field));
3265 newname = ggc_strdup (tempname);
3266 free (tempname);
3267 newvi = new_var_info (decl, newindex, newname, newindex);
3268 newvi->offset = fo->offset;
3269 newvi->size = TREE_INT_CST_LOW (DECL_SIZE (field));
3270 newvi->fullsize = vi->fullsize;
3271 insert_into_field_list (vi, newvi);
3272 VEC_safe_push (varinfo_t, heap, varmap, newvi);
3273 if (is_global)
3274 make_constraint_to_anything (newvi);
3276 stats.total_vars++;
3278 VEC_free (fieldoff_s, heap, fieldstack);
3280 return index;
3283 /* Print out the points-to solution for VAR to FILE. */
3285 void
3286 dump_solution_for_var (FILE *file, unsigned int var)
3288 varinfo_t vi = get_varinfo (var);
3289 unsigned int i;
3290 bitmap_iterator bi;
3292 fprintf (file, "%s = { ", vi->name);
3293 EXECUTE_IF_SET_IN_BITMAP (get_varinfo (vi->node)->solution, 0, i, bi)
3295 fprintf (file, "%s ", get_varinfo (i)->name);
3297 fprintf (file, "}\n");
3300 /* Print the points-to solution for VAR to stdout. */
3302 void
3303 debug_solution_for_var (unsigned int var)
3305 dump_solution_for_var (stdout, var);
3309 /* Create varinfo structures for all of the variables in the
3310 function for intraprocedural mode. */
3312 static void
3313 intra_create_variable_infos (void)
3315 tree t;
3317 /* For each incoming argument arg, ARG = &ANYTHING */
3318 for (t = DECL_ARGUMENTS (current_function_decl); t; t = TREE_CHAIN (t))
3320 struct constraint_expr lhs;
3321 struct constraint_expr rhs;
3322 varinfo_t p;
3324 lhs.offset = 0;
3325 lhs.type = SCALAR;
3326 lhs.var = create_variable_info_for (t, alias_get_name (t));
3328 rhs.var = anything_id;
3329 rhs.type = ADDRESSOF;
3330 rhs.offset = 0;
3332 for (p = get_varinfo (lhs.var); p; p = p->next)
3334 struct constraint_expr temp = lhs;
3335 temp.var = p->id;
3336 process_constraint (new_constraint (temp, rhs));
3342 /* Set bits in INTO corresponding to the variable uids in solution set
3343 FROM */
3345 static void
3346 set_uids_in_ptset (bitmap into, bitmap from)
3348 unsigned int i;
3349 bitmap_iterator bi;
3350 bool found_anyoffset = false;
3351 subvar_t sv;
3353 EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
3355 varinfo_t vi = get_varinfo (i);
3357 /* If we find ANYOFFSET in the solution and the solution
3358 includes SFTs for some structure, then all the SFTs in that
3359 structure will need to be added to the alias set. */
3360 if (vi->id == anyoffset_id)
3362 found_anyoffset = true;
3363 continue;
3366 /* The only artificial variables that are allowed in a may-alias
3367 set are heap variables. */
3368 if (vi->is_artificial_var && !vi->is_heap_var)
3369 continue;
3371 if (vi->has_union && get_subvars_for_var (vi->decl) != NULL)
3373 /* Variables containing unions may need to be converted to
3374 their SFT's, because SFT's can have unions and we cannot. */
3375 for (sv = get_subvars_for_var (vi->decl); sv; sv = sv->next)
3376 bitmap_set_bit (into, DECL_UID (sv->var));
3378 else if (TREE_CODE (vi->decl) == VAR_DECL
3379 || TREE_CODE (vi->decl) == PARM_DECL)
3381 if (found_anyoffset
3382 && var_can_have_subvars (vi->decl)
3383 && get_subvars_for_var (vi->decl))
3385 /* If ANYOFFSET is in the solution set and VI->DECL is
3386 an aggregate variable with sub-variables, then any of
3387 the SFTs inside VI->DECL may have been accessed. Add
3388 all the sub-vars for VI->DECL. */
3389 for (sv = get_subvars_for_var (vi->decl); sv; sv = sv->next)
3390 bitmap_set_bit (into, DECL_UID (sv->var));
3392 else if (var_can_have_subvars (vi->decl)
3393 && get_subvars_for_var (vi->decl))
3395 /* If VI->DECL is an aggregate for which we created
3396 SFTs, add the SFT corresponding to VI->OFFSET. */
3397 tree sft = get_subvar_at (vi->decl, vi->offset);
3398 bitmap_set_bit (into, DECL_UID (sft));
3400 else
3402 /* Otherwise, just add VI->DECL to the alias set. */
3403 bitmap_set_bit (into, DECL_UID (vi->decl));
3410 static bool have_alias_info = false;
3412 /* Given a pointer variable P, fill in its points-to set, or return
3413 false if we can't. */
3415 bool
3416 find_what_p_points_to (tree p)
3418 unsigned int id = 0;
3420 if (!have_alias_info)
3421 return false;
3423 if (lookup_id_for_tree (p, &id))
3425 varinfo_t vi = get_varinfo (id);
3427 if (vi->is_artificial_var)
3428 return false;
3430 /* See if this is a field or a structure. */
3431 if (vi->size != vi->fullsize)
3433 /* Nothing currently asks about structure fields directly,
3434 but when they do, we need code here to hand back the
3435 points-to set. */
3436 if (!var_can_have_subvars (vi->decl)
3437 || get_subvars_for_var (vi->decl) == NULL)
3438 return false;
3440 else
3442 struct ptr_info_def *pi = get_ptr_info (p);
3443 unsigned int i;
3444 bitmap_iterator bi;
3446 /* This variable may have been collapsed, let's get the real
3447 variable. */
3448 vi = get_varinfo (vi->node);
3450 /* Translate artificial variables into SSA_NAME_PTR_INFO
3451 attributes. */
3452 EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
3454 varinfo_t vi = get_varinfo (i);
3456 if (vi->is_artificial_var)
3458 /* FIXME. READONLY should be handled better so that
3459 flow insensitive aliasing can disregard writable
3460 aliases. */
3461 if (vi->id == nothing_id)
3462 pi->pt_null = 1;
3463 else if (vi->id == anything_id)
3464 pi->pt_anything = 1;
3465 else if (vi->id == readonly_id)
3466 pi->pt_anything = 1;
3467 else if (vi->id == integer_id)
3468 pi->pt_anything = 1;
3469 else if (vi->is_heap_var)
3470 pi->pt_global_mem = 1;
3474 if (pi->pt_anything)
3475 return false;
3477 if (!pi->pt_vars)
3478 pi->pt_vars = BITMAP_GGC_ALLOC ();
3480 set_uids_in_ptset (pi->pt_vars, vi->solution);
3482 if (bitmap_empty_p (pi->pt_vars))
3483 pi->pt_vars = NULL;
3485 return true;
3489 return false;
3493 /* Initialize things necessary to perform PTA */
3495 static void
3496 init_alias_vars (void)
3498 bitmap_obstack_initialize (&ptabitmap_obstack);
3502 /* Dump points-to information to OUTFILE. */
3504 void
3505 dump_sa_points_to_info (FILE *outfile)
3507 unsigned int i;
3509 fprintf (outfile, "\nPoints-to sets\n\n");
3511 if (dump_flags & TDF_STATS)
3513 fprintf (outfile, "Stats:\n");
3514 fprintf (outfile, "Total vars: %d\n", stats.total_vars);
3515 fprintf (outfile, "Statically unified vars: %d\n",
3516 stats.unified_vars_static);
3517 fprintf (outfile, "Collapsed vars: %d\n", stats.collapsed_vars);
3518 fprintf (outfile, "Dynamically unified vars: %d\n",
3519 stats.unified_vars_dynamic);
3520 fprintf (outfile, "Iterations: %d\n", stats.iterations);
3523 for (i = 0; i < VEC_length (varinfo_t, varmap); i++)
3524 dump_solution_for_var (outfile, i);
3528 /* Debug points-to information to stderr. */
3530 void
3531 debug_sa_points_to_info (void)
3533 dump_sa_points_to_info (stderr);
3537 /* Initialize the always-existing constraint variables for NULL
3538 ANYTHING, READONLY, and INTEGER */
3540 static void
3541 init_base_vars (void)
3543 struct constraint_expr lhs, rhs;
3545 /* Create the NULL variable, used to represent that a variable points
3546 to NULL. */
3547 nothing_tree = create_tmp_var_raw (void_type_node, "NULL");
3548 var_nothing = new_var_info (nothing_tree, 0, "NULL", 0);
3549 insert_id_for_tree (nothing_tree, 0);
3550 var_nothing->is_artificial_var = 1;
3551 var_nothing->offset = 0;
3552 var_nothing->size = ~0;
3553 var_nothing->fullsize = ~0;
3554 var_nothing->is_special_var = 1;
3555 nothing_id = 0;
3556 VEC_safe_push (varinfo_t, heap, varmap, var_nothing);
3558 /* Create the ANYTHING variable, used to represent that a variable
3559 points to some unknown piece of memory. */
3560 anything_tree = create_tmp_var_raw (void_type_node, "ANYTHING");
3561 var_anything = new_var_info (anything_tree, 1, "ANYTHING", 1);
3562 insert_id_for_tree (anything_tree, 1);
3563 var_anything->is_artificial_var = 1;
3564 var_anything->size = ~0;
3565 var_anything->offset = 0;
3566 var_anything->next = NULL;
3567 var_anything->fullsize = ~0;
3568 var_anything->is_special_var = 1;
3569 anything_id = 1;
3571 /* Anything points to anything. This makes deref constraints just
3572 work in the presence of linked list and other p = *p type loops,
3573 by saying that *ANYTHING = ANYTHING. */
3574 VEC_safe_push (varinfo_t, heap, varmap, var_anything);
3575 lhs.type = SCALAR;
3576 lhs.var = anything_id;
3577 lhs.offset = 0;
3578 rhs.type = ADDRESSOF;
3579 rhs.var = anything_id;
3580 rhs.offset = 0;
3581 var_anything->address_taken = true;
3583 /* This specifically does not use process_constraint because
3584 process_constraint ignores all anything = anything constraints, since all
3585 but this one are redundant. */
3586 VEC_safe_push (constraint_t, heap, constraints, new_constraint (lhs, rhs));
3588 /* Create the READONLY variable, used to represent that a variable
3589 points to readonly memory. */
3590 readonly_tree = create_tmp_var_raw (void_type_node, "READONLY");
3591 var_readonly = new_var_info (readonly_tree, 2, "READONLY", 2);
3592 var_readonly->is_artificial_var = 1;
3593 var_readonly->offset = 0;
3594 var_readonly->size = ~0;
3595 var_readonly->fullsize = ~0;
3596 var_readonly->next = NULL;
3597 var_readonly->is_special_var = 1;
3598 insert_id_for_tree (readonly_tree, 2);
3599 readonly_id = 2;
3600 VEC_safe_push (varinfo_t, heap, varmap, var_readonly);
3602 /* readonly memory points to anything, in order to make deref
3603 easier. In reality, it points to anything the particular
3604 readonly variable can point to, but we don't track this
3605 separately. */
3606 lhs.type = SCALAR;
3607 lhs.var = readonly_id;
3608 lhs.offset = 0;
3609 rhs.type = ADDRESSOF;
3610 rhs.var = anything_id;
3611 rhs.offset = 0;
3613 process_constraint (new_constraint (lhs, rhs));
3615 /* Create the INTEGER variable, used to represent that a variable points
3616 to an INTEGER. */
3617 integer_tree = create_tmp_var_raw (void_type_node, "INTEGER");
3618 var_integer = new_var_info (integer_tree, 3, "INTEGER", 3);
3619 insert_id_for_tree (integer_tree, 3);
3620 var_integer->is_artificial_var = 1;
3621 var_integer->size = ~0;
3622 var_integer->fullsize = ~0;
3623 var_integer->offset = 0;
3624 var_integer->next = NULL;
3625 var_integer->is_special_var = 1;
3626 integer_id = 3;
3627 VEC_safe_push (varinfo_t, heap, varmap, var_integer);
3629 /* *INTEGER = ANYTHING, because we don't know where a dereference of a random
3630 integer will point to. */
3631 lhs.type = SCALAR;
3632 lhs.var = integer_id;
3633 lhs.offset = 0;
3634 rhs.type = ADDRESSOF;
3635 rhs.var = anything_id;
3636 rhs.offset = 0;
3637 process_constraint (new_constraint (lhs, rhs));
3639 /* Create the ANYOFFSET variable, used to represent an arbitrary offset
3640 inside an object. This is similar to ANYTHING, but less drastic.
3641 It means that the pointer can point anywhere inside an object,
3642 but not outside of it. */
3643 anyoffset_tree = create_tmp_var_raw (void_type_node, "ANYOFFSET");
3644 anyoffset_id = 4;
3645 var_anyoffset = new_var_info (anyoffset_tree, anyoffset_id, "ANYOFFSET",
3646 anyoffset_id);
3647 insert_id_for_tree (anyoffset_tree, anyoffset_id);
3648 var_anyoffset->is_artificial_var = 1;
3649 var_anyoffset->size = ~0;
3650 var_anyoffset->offset = 0;
3651 var_anyoffset->next = NULL;
3652 var_anyoffset->fullsize = ~0;
3653 var_anyoffset->is_special_var = 1;
3654 VEC_safe_push (varinfo_t, heap, varmap, var_anyoffset);
3656 /* ANYOFFSET points to ANYOFFSET. */
3657 lhs.type = SCALAR;
3658 lhs.var = anyoffset_id;
3659 lhs.offset = 0;
3660 rhs.type = ADDRESSOF;
3661 rhs.var = anyoffset_id;
3662 rhs.offset = 0;
3663 process_constraint (new_constraint (lhs, rhs));
3666 /* Return true if we actually need to solve the constraint graph in order to
3667 get our points-to sets. This is false when, for example, no addresses are
3668 taken other than special vars, or all points-to sets with members already
3669 contain the anything variable and there are no predecessors for other
3670 sets. */
3672 static bool
3673 need_to_solve (void)
3675 int i;
3676 varinfo_t v;
3677 bool found_address_taken = false;
3678 bool found_non_anything = false;
3680 for (i = 0; VEC_iterate (varinfo_t, varmap, i, v); i++)
3682 if (v->is_special_var)
3683 continue;
3685 if (v->address_taken)
3686 found_address_taken = true;
3688 if (v->solution
3689 && !bitmap_empty_p (v->solution)
3690 && !bitmap_bit_p (v->solution, anything_id))
3691 found_non_anything = true;
3692 else if (bitmap_empty_p (v->solution)
3693 && VEC_length (constraint_edge_t, graph->preds[v->id]) != 0)
3694 found_non_anything = true;
3696 if (found_address_taken && found_non_anything)
3697 return true;
3700 return false;
3703 /* Create points-to sets for the current function. See the comments
3704 at the start of the file for an algorithmic overview. */
3706 void
3707 compute_points_to_sets (struct alias_info *ai)
3709 basic_block bb;
3711 timevar_push (TV_TREE_PTA);
3713 init_alias_vars ();
3715 constraint_pool = create_alloc_pool ("Constraint pool",
3716 sizeof (struct constraint), 30);
3717 variable_info_pool = create_alloc_pool ("Variable info pool",
3718 sizeof (struct variable_info), 30);
3719 constraint_edge_pool = create_alloc_pool ("Constraint edges",
3720 sizeof (struct constraint_edge), 30);
3722 constraints = VEC_alloc (constraint_t, heap, 8);
3723 varmap = VEC_alloc (varinfo_t, heap, 8);
3724 id_for_tree = htab_create (10, tree_id_hash, tree_id_eq, free);
3725 memset (&stats, 0, sizeof (stats));
3727 init_base_vars ();
3729 intra_create_variable_infos ();
3731 /* Now walk all statements and derive aliases. */
3732 FOR_EACH_BB (bb)
3734 block_stmt_iterator bsi;
3735 tree phi;
3737 for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
3738 if (is_gimple_reg (PHI_RESULT (phi)))
3739 find_func_aliases (phi, ai);
3741 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
3742 find_func_aliases (bsi_stmt (bsi), ai);
3745 build_constraint_graph ();
3747 if (dump_file)
3749 fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n");
3750 dump_constraints (dump_file);
3753 if (need_to_solve ())
3755 if (dump_file)
3756 fprintf (dump_file, "\nCollapsing static cycles and doing variable "
3757 "substitution:\n");
3759 find_and_collapse_graph_cycles (graph, false);
3760 perform_var_substitution (graph);
3762 if (dump_file)
3763 fprintf (dump_file, "\nSolving graph:\n");
3765 solve_graph (graph);
3768 if (dump_file)
3769 dump_sa_points_to_info (dump_file);
3771 have_alias_info = true;
3773 timevar_pop (TV_TREE_PTA);
3777 /* Delete created points-to sets. */
3779 void
3780 delete_points_to_sets (void)
3782 varinfo_t v;
3783 int i;
3785 htab_delete (id_for_tree);
3786 bitmap_obstack_release (&ptabitmap_obstack);
3787 VEC_free (constraint_t, heap, constraints);
3789 for (i = 0; VEC_iterate (varinfo_t, varmap, i, v); i++)
3791 VEC_free (constraint_edge_t, heap, graph->succs[i]);
3792 VEC_free (constraint_edge_t, heap, graph->preds[i]);
3793 VEC_free (constraint_t, heap, v->complex);
3795 free (graph->succs);
3796 free (graph->preds);
3797 free (graph);
3799 VEC_free (varinfo_t, heap, varmap);
3800 free_alloc_pool (variable_info_pool);
3801 free_alloc_pool (constraint_pool);
3802 free_alloc_pool (constraint_edge_pool);
3804 have_alias_info = false;
3807 /* Initialize the heapvar for statement mapping. */
3808 void
3809 init_alias_heapvars (void)
3811 heapvar_for_stmt = htab_create_ggc (11, tree_map_hash, tree_map_eq, NULL);
3814 void
3815 delete_alias_heapvars (void)
3817 htab_delete (heapvar_for_stmt);
3821 #include "gt-tree-ssa-structalias.h"