Merge from the pain train
[official-gcc.git] / gcc / tree-ssa-structalias.c
blob6280dcecda5f602dca629ee88daab6f752ced8c3
1 /* Tree based points-to analysis
2 Copyright (C) 2002, 2003, 2004 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 "tree-ssa-structalias.h"
30 #include "flags.h"
31 #include "rtl.h"
32 #include "tm_p.h"
33 #include "hard-reg-set.h"
34 #include "basic-block.h"
35 #include "output.h"
36 #include "errors.h"
37 #include "expr.h"
38 #include "diagnostic.h"
39 #include "tree.h"
40 #include "c-common.h"
41 #include "tree-flow.h"
42 #include "tree-inline.h"
43 #include "varray.h"
44 #include "c-tree.h"
45 #include "tree-gimple.h"
46 #include "hashtab.h"
47 #include "function.h"
48 #include "cgraph.h"
49 #include "tree-pass.h"
50 #include "timevar.h"
51 #include "alloc-pool.h"
52 #include "splay-tree.h"
54 /* The idea behind this analyzer is to generate set constraints from the
55 program, then solve the resulting constraints in order to generate the
56 points-to sets.
57 There are three types of constraint expressions, DEREF, ADDRESSOF, and
58 SCALAR. Each constraint expression consists of a type, a variable,
59 and an offset.
61 SCALAR is a constraint expression type used to represent x, whether
62 it appears on the LHS or the RHS of a statement.
63 DEREF is a constraint expression type used to represent *x, whether
64 it appears on the LHS or the RHS of a statement.
65 ADDRESSOF is a constraint expression used to represent &x, whether
66 it apepars on the LHS or the RHS of a statement.
68 Each variable in the program is assigned an integer id, and each field of a
69 variable is assigned an integer id as well.
70 Variables are linked to their fields and vice versa.
71 Each variable with subfields has a next pointer, that points to the next
72 field (ordered by offset, then size). Each subfield is it's own variable
73 as well, and has a pointer back to the ultimate containing variable,
74 through the base pointer.
75 The size field tells the size in bits of each portion of a multi-field
76 variable
77 (for scalars, size is the size of the entire variable as well), and the
78 fullsize field tells us the size in bits of the entire variable.
79 The offset field contains the offset, in bits, from the base.
81 Thus,
82 struct f
84 int a;
85 int b;
86 } foo;
87 int bar;
89 looks like
91 foo -> id 1, size 32, offset 0, fullsize 64, next foo#b, base foo
92 foo#b -> id 2, size 32, offset 32, fullsize 64, next NULL, base foo
93 bar -> id 3, size 32, offset 0, fullsize 32, next NULL, base bar
96 After constructing constraints, we put them into a constraint graph, where
97 the edges of the graph represent copy constraints (SCALAR-> SCALAR
98 constraints).
99 We then perform static cycle elimination on the constraint graph, as well
100 as off-line variable substitution.
101 Finally, we solve the constraint graph, producing our points-to solutions.
103 TODO: For extra speed in iterations, we should sort types so that types
104 with their address taken come first.
106 TODO: Adding offsets to pointer-to-structures can be handled (IE not punted
107 on and turned into anything), but isn't. You can just see what field
108 number inside the pointed-to struct it's going to access.
110 TODO: Constant bounded arrays can be handled as if they were structs of the
111 same number of elements.
113 TODO: Modeling heap and incoming pointers becomes much better if we can add
114 fields to them at solve time. We could do this with some work.
115 This may significantly slow the solver, however.
116 We'll have to investigate.
118 TODO: Use malloc vectors and a bitmap obstack, not ggc_alloc'd things.
119 Also, we allocate a lot of bitmaps we don't need. */
120 static unsigned int create_variable_info_for (tree, const char *);
121 static struct constraint_expr get_constraint_for (tree);
122 static void build_constraint_graph (void);
124 DEF_VEC_GC_P(constraint_t);
125 static struct constraint_stats
127 unsigned int total_vars;
128 unsigned int collapsed_vars;
129 unsigned int unified_vars_static;
130 unsigned int unified_vars_dynamic;
131 unsigned int iterations;
132 } stats;
134 struct variable_info
136 /* ID of this variable */
137 unsigned int id;
138 /* Name of this variable */
139 const char *name;
140 /* Tree that this variable is associated with. */
141 tree decl;
142 struct variable_info *base;
143 /* Offset of this variable, in bits, from the base variable */
144 unsigned HOST_WIDE_INT offset;
145 /* Size of the variable, in bits. */
146 unsigned HOST_WIDE_INT size;
147 /* Full size of the base variable, in bits. */
148 unsigned HOST_WIDE_INT fullsize;
149 /* A link to the variable for the next field in this structure. */
150 struct variable_info *next;
151 /* Node in the graph that represents the constraints and points-to
152 solution for the variable. */
153 unsigned int node;
154 /* True if the address of this variable is taken. Needed for
155 rountev-chandra. */
156 unsigned int address_taken:1;
157 /* True if this variable is the target of a dereference. Needed for
158 rountev-chandra. */
159 unsigned int indirect_target:1;
160 /* True if this is a variable created by the constraint analysis, such as
161 heap variables and constraints we had to break up. */
162 unsigned int is_artificial_var:1;
163 /* Because we punt on union vars right now, we have to identify them so that
164 we can mark them as not type safe. */
165 unsigned int is_unknown_size_var:1;
166 /* Points-to set for this variable. */
167 bitmap solution;
168 /* Variable ids represented by this variable node. */
169 bitmap variables;
170 /* Vector of complex constraints for this node. Complex
171 constraints are those involving dereferences. */
172 VEC(constraint_t) *complicated;
174 typedef struct variable_info *varinfo_t;
176 static varinfo_t first_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT);
177 static varinfo_t next_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT);
179 /* Pool of variable info structures. */
180 static alloc_pool variable_info_pool;
181 DEF_VEC_GC_P (varinfo_t);
182 static VEC(varinfo_t) *varmap;
183 #define get_varinfo(n) VEC_index(varinfo_t, varmap, n)
185 /* Variable that represents the unknown pointer. */
186 static varinfo_t var_anything;
187 static tree anything_tree;
188 static unsigned int anything_id;
190 /* Variable that represents the NULL pointer. */
191 static varinfo_t var_nothing;
192 static tree nothing_tree;
193 static unsigned int nothing_id;
195 /* Variable that represents readonly memory. */
196 static varinfo_t var_readonly;
197 static tree readonly_tree;
198 static unsigned int readonly_id;
200 /* Variable that represents integers. */
201 static varinfo_t var_integer;
202 static tree integer_tree;
203 static unsigned int integer_id;
205 /* Return a new variable info structure consisting for a variable
206 named NAME, ending at id END, and using constraint graph node
207 NODE. */
208 static varinfo_t
209 new_var_info (tree t, unsigned int id, const char *name, unsigned int node)
211 varinfo_t ret = pool_alloc (variable_info_pool);
212 ret->id = id;
213 ret->name = name;
214 ret->decl = t;
215 ret->node = node;
216 ret->address_taken = false;
217 ret->indirect_target = false;
218 ret->is_artificial_var = false;
219 ret->is_unknown_size_var = false;
220 ret->solution = BITMAP_GGC_ALLOC ();
221 bitmap_clear (ret->solution);
222 ret->variables = BITMAP_GGC_ALLOC ();
223 bitmap_clear (ret->variables);
224 ret->complicated = NULL;
225 ret->next = NULL;
226 return ret;
229 typedef enum {SCALAR, DEREF, ADDRESSOF} constraint_expr_type;
231 /* An expression that appears in a constraint. */
232 struct constraint_expr
234 /* Constraint type. */
235 constraint_expr_type type;
236 /* Variable we are referring to in the constraint. */
237 unsigned int var;
238 /* Offset is in bits */
239 unsigned HOST_WIDE_INT offset;
242 static struct constraint_expr do_deref (struct constraint_expr);
244 /* Constraints are made up of two constraint expressions, one LHS, and one
245 RHS. */
246 struct constraint
248 struct constraint_expr lhs;
249 struct constraint_expr rhs;
252 /* List of constraints that we use to build the constraint graph from. */
253 static VEC(constraint_t) *constraints;
254 static alloc_pool constraint_pool;
256 /* An edge in the constraint graph. We technically have no use for
257 the src, since it will always be the same node that we are indexing
258 into the pred/succ arrays with, but it's nice for checking
259 purposes.
260 The edges are weighted, with a bit set in weights if we have an edge with
261 that weight. */
262 struct constraint_edge
264 unsigned int src;
265 unsigned int dest;
266 bitmap weights;
269 typedef struct constraint_edge *constraint_edge_t;
270 static alloc_pool constraint_edge_pool;
272 /* Return a new constraint edge from SRC to DEST. */
273 static constraint_edge_t
274 new_constraint_edge (unsigned int src, unsigned int dest)
276 constraint_edge_t ret = pool_alloc (constraint_edge_pool);
277 ret->src = src;
278 ret->dest = dest;
279 ret->weights = NULL;
280 return ret;
283 DEF_VEC_GC_P (constraint_edge_t);
285 /* The constraint graph is simply a set of adjacency vectors, one per
286 variable. succs[x] is the vector of successors for variable x, and preds[x]
287 is the vector of predecessors for variable x. */
288 struct constraint_graph
290 VEC(constraint_edge_t) **succs;
291 VEC(constraint_edge_t) **preds;
294 typedef struct constraint_graph *constraint_graph_t;
296 static constraint_graph_t graph;
298 /* Create a new constraint consisting of LHS and RHS expressions. */
300 static constraint_t
301 new_constraint (const struct constraint_expr lhs,
302 const struct constraint_expr rhs)
304 constraint_t ret = pool_alloc (constraint_pool);
305 ret->lhs = lhs;
306 ret->rhs = rhs;
307 return ret;
310 /* Print out constraint C to FILE. */
312 void
313 print_constraint (FILE *file, constraint_t c)
315 if (c->lhs.type == ADDRESSOF)
316 fprintf (file, "&");
317 else if (c->lhs.type == DEREF)
318 fprintf (file, "*");
319 fprintf (file, "%s", get_varinfo (c->lhs.var)->name);
320 if (c->lhs.offset != 0)
321 fprintf (file, "+ " HOST_WIDE_INT_PRINT_DEC, c->lhs.offset);
322 fprintf (file, " = ");
323 if (c->rhs.type == ADDRESSOF)
324 fprintf (file, "&");
325 else if (c->rhs.type == DEREF)
326 fprintf (file, "*");
327 fprintf (file, "%s", get_varinfo (c->rhs.var)->name);
328 if (c->rhs.offset != 0)
329 fprintf (file, "+ " HOST_WIDE_INT_PRINT_DEC, c->rhs.offset);
330 fprintf (file, "\n");
332 void
333 debug_constraint (constraint_t c)
335 print_constraint (stdout, c);
338 void
339 print_constraints (FILE *file)
341 int i;
342 constraint_t c;
343 for (i = 0; VEC_iterate (constraint_t, constraints, i, c); i++)
344 print_constraint (file, c);
347 void
348 debug_constraints (void)
350 print_constraints (stdout);
353 /* Map from trees to variable ids. */
354 static htab_t id_for_tree;
356 typedef struct tree_id
358 tree t;
359 unsigned int id;
360 } *tree_id_t;
362 static hashval_t
363 tree_id_hash (const void *p)
365 const tree_id_t ta = (tree_id_t) p;
366 return htab_hash_pointer (ta->t);
369 static int
370 tree_id_eq (const void *p1, const void *p2)
372 const tree_id_t ta1 = (tree_id_t) p1;
373 const tree_id_t ta2 = (tree_id_t) p2;
374 return ta1->t == ta2->t;
377 /* Insert ID as the variable id for tree T in the hashtable. */
378 static void
379 insert_id_for_tree (tree t, int id)
381 void **slot;
382 struct tree_id finder;
383 tree_id_t new_pair;
385 finder.t = t;
386 slot = htab_find_slot (id_for_tree, &finder, INSERT);
387 gcc_assert (*slot == NULL);
388 new_pair = xmalloc (sizeof (struct tree_id));
389 new_pair->t = t;
390 new_pair->id = id;
391 *slot = (void *)new_pair;
394 #if 0
395 /* Find the variable ID for tree T in the hashtable. */
396 static unsigned int
397 lookup_id_for_tree (tree t)
399 tree_id_t pair;
400 struct tree_id finder;
401 finder.t = t;
402 pair = htab_find (id_for_tree, &finder);
403 gcc_assert (pair != NULL);
404 return pair->id;
406 #endif
408 /* Find the variable ID for tree T in the hashtable. */
409 static unsigned int
410 get_id_for_tree (tree t)
412 tree_id_t pair;
413 struct tree_id finder;
414 finder.t = t;
415 pair = htab_find (id_for_tree, &finder);
416 if (pair == NULL)
417 return create_variable_info_for (t, alias_get_name (t));
419 return pair->id;
422 /* Get a constraint expression from an SSA_VAR_P node. */
423 static struct constraint_expr
424 get_constraint_exp_from_ssa_var (tree t)
426 struct constraint_expr cexpr;
428 gcc_assert (SSA_VAR_P (t) || DECL_P (t));
430 if (TREE_CODE (t) == SSA_NAME
431 && TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL
432 && default_def (SSA_NAME_VAR (t)) == t
433 /*&& POINTER_TYPE_P (TREE_TYPE (t))*/)
434 return get_constraint_exp_from_ssa_var (SSA_NAME_VAR (t));
436 cexpr.type = SCALAR;
438 if (DECL_P (t)
439 && is_global_var (t)
440 && !TREE_READONLY (t))
442 cexpr.type = ADDRESSOF;
443 cexpr.var = anything_id;
445 else if (TREE_READONLY (t))
447 cexpr.type = ADDRESSOF;
448 cexpr.var = readonly_id;
450 else
451 cexpr.var = get_id_for_tree (t);
453 cexpr.offset = 0;
454 return cexpr;
457 /* Process a completed constraint T, and add it to the constraint
458 list. NEEDEXPAND is true if we need to expand this into the constraints
459 for all fields with this offset. */
461 static void
462 process_constraint (constraint_t t, bool needexpand)
464 struct constraint_expr rhs = t->rhs;
465 struct constraint_expr lhs = t->lhs;
467 gcc_assert (rhs.var < VEC_length (varinfo_t, varmap));
468 gcc_assert (lhs.var < VEC_length (varinfo_t, varmap));
470 /* ANYTHING == ANYTHING is pointless. */
471 if (lhs.var == anything_id && rhs.var == anything_id)
472 return;
474 /* If we have &ANYTHING = something, convert to SOMETHING = &ANYTHING) */
475 else if (lhs.var == anything_id && lhs.type == ADDRESSOF)
477 rhs = t->lhs;
478 t->lhs = t->rhs;
479 t->rhs = rhs;
480 /* lhs.type = SCALAR; */
481 process_constraint (t, needexpand);
483 /* This can happen in our IR with things like n->a = *p */
484 else if (rhs.type == DEREF && lhs.type == DEREF && rhs.var != anything_id)
486 /* Split into tmp = *rhs, *lhs = tmp */
487 tree rhsdecl = get_varinfo (rhs.var)->decl;
488 tree pointertype = TREE_TYPE (rhsdecl);
489 tree pointedtotype = TREE_TYPE (pointertype);
490 tree tmpvar = create_tmp_var_raw (pointedtotype, "doubledereftmp");
491 struct constraint_expr tmplhs = get_constraint_exp_from_ssa_var (tmpvar);
493 /* Unless this is an unknown size var, we should have passed this off
494 to do_structure_copy, and it should have broken it up. */
495 gcc_assert (!AGGREGATE_TYPE_P (pointedtotype)
496 || get_varinfo (rhs.var)->is_unknown_size_var);
498 process_constraint (new_constraint (tmplhs, rhs), needexpand);
499 process_constraint (new_constraint (lhs, tmplhs), needexpand);
501 else if (rhs.type == ADDRESSOF)
503 varinfo_t vi;
504 gcc_assert (rhs.offset == 0);
506 for (vi = get_varinfo (rhs.var); vi != NULL; vi = vi->next)
507 vi->address_taken = true;
509 VEC_safe_push (constraint_t, constraints, t);
511 else
513 if (lhs.type != DEREF && rhs.type == DEREF)
514 get_varinfo (lhs.var)->indirect_target = true;
515 VEC_safe_push (constraint_t, constraints, t);
520 /* Return the position, in bits, of FIELD_DECL from the beginning of it's
521 structure. */
523 static unsigned HOST_WIDE_INT
524 bitpos_of_field (const tree fdecl)
526 return (tree_low_cst (DECL_FIELD_OFFSET (fdecl), 1) * 8)
527 + tree_low_cst (DECL_FIELD_BIT_OFFSET (fdecl), 1);
530 /* Given a component ref, return the constraint_expr for it. */
532 static struct constraint_expr
533 get_constraint_for_component_ref (tree t)
535 struct constraint_expr result;
536 HOST_WIDE_INT bitsize;
537 HOST_WIDE_INT bitpos;
538 tree offset;
539 enum machine_mode mode;
540 int unsignedp;
541 int volatilep;
542 tree forzero;
544 result.offset = 0;
545 result.type = SCALAR;
546 result.var = 0;
547 forzero = t;
548 while (!SSA_VAR_P (forzero) && !CONSTANT_CLASS_P (forzero))
550 forzero = TREE_OPERAND (forzero, 0);
553 if (CONSTANT_CLASS_P (forzero) && integer_zerop (forzero))
555 result.offset = 0;
556 result.var = integer_id;
557 result.type = SCALAR;
558 return result;
560 t = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
561 &unsignedp, &volatilep, false);
562 result = get_constraint_for (t);
564 /* Errf. No point in doing something weird here. */
565 if (TREE_CODE (t) != ADDR_EXPR && result.type == ADDRESSOF)
566 result.type = SCALAR;
568 if (offset == NULL && bitsize != -1)
570 result.offset = bitpos;
572 else
574 /* MAY NEED TO CHANGE THIS TO PROCESS A CONSTRAINT FROM RESULT.VAR TO
575 ANYTHING. */
576 result.var = anything_id;
577 result.offset = 0;
580 if (result.type == SCALAR)
582 result.var = first_vi_for_offset (get_varinfo (result.var),
583 result.offset)->id;
584 result.offset= 0;
587 return result;
590 /* Dereference the constraint expression CONS, and return the result.
591 DEREF (ADDRESSOF) = SCALAR
592 DEREF (SCALAR) = DEREF
593 DEREF (DEREF) = temp = DEREF1; result = DEREF(temp)
594 This is needed so that we can handle dereferencing DEREF constraints. */
595 static struct constraint_expr
596 do_deref (struct constraint_expr cons)
598 if (cons.type == SCALAR)
600 cons.type = DEREF;
601 return cons;
603 else if (cons.type == ADDRESSOF)
605 cons.type = SCALAR;
606 return cons;
608 else if (cons.type == DEREF)
610 tree tmpvar = create_tmp_var_raw (ptr_type_node, "derefmp");
611 struct constraint_expr tmplhs = get_constraint_exp_from_ssa_var (tmpvar);
612 process_constraint (new_constraint (tmplhs, cons), true);
613 cons.var = tmplhs.var;
614 return cons;
616 gcc_unreachable ();
619 /* Given a TREE, return the constraint expression for it. */
621 static struct constraint_expr
622 get_constraint_for (tree t)
624 struct constraint_expr temp;
626 /* x = integer is all glommed to a single variable, which doesn't point to
627 anything by itself.
628 That is, of course, unless it is an integer constant being treated as a
629 pointer, in which case, we will return that this is really the addressof
630 anything. This happens below, since it will fall into the default case.
632 The only case we know something about an integer treated like a pointer
633 is when it is the NULL pointer, and then we just say it points to NULL.
635 if (TREE_CODE (t) == INTEGER_CST
636 && !POINTER_TYPE_P (TREE_TYPE (t)))
638 temp.var = integer_id;
639 temp.type = SCALAR;
640 temp.offset = 0;
641 return temp;
643 else if (TREE_CODE (t) == INTEGER_CST
644 && integer_zerop (t))
646 temp.var = nothing_id;
647 temp.type = ADDRESSOF;
648 temp.offset = 0;
649 return temp;
652 switch (TREE_CODE_CLASS (TREE_CODE (t)))
654 case tcc_expression:
656 switch (TREE_CODE (t))
658 case ADDR_EXPR:
660 temp = get_constraint_for (TREE_OPERAND (t, 0));
661 if (temp.type == DEREF)
662 temp.type = SCALAR;
663 else
664 temp.type = ADDRESSOF;
665 return temp;
667 case CALL_EXPR:
669 /* FIXME: Pointers directly passed to calls need to have *pointer =
670 &ANYTHING added, things with their address taken need to have x
671 = &ANYTHING added.
672 At least until we do interprocedural analysis
675 if (call_expr_flags (t) & (ECF_MALLOC | ECF_MAY_BE_ALLOCA))
677 tree heapvar = create_tmp_var_raw (ptr_type_node, "HEAP");
678 temp.var = create_variable_info_for (heapvar,
679 alias_get_name (heapvar));
681 get_varinfo (temp.var)->is_artificial_var = 1;
682 temp.type = ADDRESSOF;
683 temp.offset = 0;
684 return temp;
686 default:
688 temp.type = ADDRESSOF;
689 temp.var = anything_id;
690 temp.offset = 0;
691 return temp;
695 case tcc_reference:
697 switch (TREE_CODE (t))
699 case INDIRECT_REF:
701 temp = get_constraint_for (TREE_OPERAND (t, 0));
702 temp = do_deref (temp);
703 return temp;
705 case ARRAY_REF:
706 case COMPONENT_REF:
707 temp = get_constraint_for_component_ref (t);
708 return temp;
709 /* return get_constraint_for (get_base_address (t));*/
710 default:
712 temp.type = ADDRESSOF;
713 temp.var = anything_id;
714 temp.offset = 0;
715 return temp;
719 case tcc_unary:
721 switch (TREE_CODE (t))
723 case NOP_EXPR:
724 case CONVERT_EXPR:
725 case NON_LVALUE_EXPR:
727 tree op = TREE_OPERAND (t, 0);
729 /* Cast from non-pointer to pointers are bad news for us.
730 Anything else, we see through */
731 if (!(POINTER_TYPE_P (TREE_TYPE (t)) &&
732 ! POINTER_TYPE_P (TREE_TYPE (op))))
733 return get_constraint_for (op);
735 default:
737 temp.type = ADDRESSOF;
738 temp.var = anything_id;
739 temp.offset = 0;
740 return temp;
744 case tcc_exceptional:
746 switch (TREE_CODE (t))
748 case PHI_NODE:
749 return get_constraint_for (PHI_RESULT (t));
750 case SSA_NAME:
751 return get_constraint_exp_from_ssa_var (t);
752 default:
754 temp.type = ADDRESSOF;
755 temp.var = anything_id;
756 temp.offset = 0;
757 return temp;
761 case tcc_declaration:
762 return get_constraint_exp_from_ssa_var (t);
763 default:
765 temp.type = ADDRESSOF;
766 temp.var = anything_id;
767 temp.offset = 0;
768 return temp;
774 /* Handle the structure copy case where we have a simple structure copy
775 between LHS and RHS that is of SIZE (in bits)
777 For each field of the lhs variable (lhsfield)
778 For each field of the rhs variable at lhsfield.offset (rhsfield)
779 add the constraint lhsfield = rhsfield
782 static void
783 do_simple_structure_copy (const struct constraint_expr lhs,
784 const struct constraint_expr rhs,
785 const unsigned HOST_WIDE_INT size)
787 varinfo_t p = get_varinfo (lhs.var);
788 unsigned HOST_WIDE_INT pstart,last;
789 pstart = p->offset;
790 last = p->offset + size;
791 /* Grrr. O(n^2) for now */
792 for (; p && p->offset < last; p = p->next)
794 varinfo_t q;
795 struct constraint_expr templhs = lhs;
796 struct constraint_expr temprhs = rhs;
797 unsigned HOST_WIDE_INT fieldoffset;
798 templhs.var = p->id;
800 q = get_varinfo (temprhs.var);
801 fieldoffset = p->offset - pstart;
803 for (q = first_vi_for_offset (q, fieldoffset);
804 q != NULL;
805 q = next_vi_for_offset (q, fieldoffset))
807 temprhs.var = q->id;
808 process_constraint (new_constraint (templhs, temprhs), false);
814 /* Handle the structure copy case where we have a structure copy between a
815 aggregate on the LHS and a dereference of a pointer on the RHS
816 that is of SIZE (in bits)
818 For each field of the lhs variable (lhsfield)
819 rhs.offset = lhsfield->offset
820 add the constraint lhsfield = rhs
822 static void
823 do_rhs_deref_structure_copy (const struct constraint_expr lhs,
824 const struct constraint_expr rhs,
825 const unsigned HOST_WIDE_INT size)
827 varinfo_t p = get_varinfo (lhs.var);
828 unsigned HOST_WIDE_INT pstart,last;
829 pstart = p->offset;
830 last = p->offset + size;
832 for (; p && p->offset < last; p = p->next)
834 varinfo_t q;
835 struct constraint_expr templhs = lhs;
836 struct constraint_expr temprhs = rhs;
837 unsigned HOST_WIDE_INT fieldoffset;
838 if (templhs.type == SCALAR)
839 templhs.var = p->id;
840 else
841 templhs.offset = p->offset;
843 q = get_varinfo (temprhs.var);
844 fieldoffset = p->offset - pstart;
845 temprhs.offset += fieldoffset;
846 process_constraint (new_constraint (templhs, temprhs), false);
850 /* Handle the structure copy case where we have a structure copy between a
851 aggregate on the RHS and a dereference of a pointer on the LHS
852 that is of SIZE (in bits)
854 For each field of the rhs variable (rhsfield)
855 lhs.offset = rhsfield->offset
856 add the constraint lhs = rhsfield
858 static void
859 do_lhs_deref_structure_copy (const struct constraint_expr lhs,
860 const struct constraint_expr rhs,
861 const unsigned HOST_WIDE_INT size)
863 varinfo_t p = get_varinfo (rhs.var);
864 unsigned HOST_WIDE_INT pstart,last;
865 pstart = p->offset;
866 last = p->offset + size;
868 for (; p && p->offset < last; p = p->next)
870 varinfo_t q;
871 struct constraint_expr templhs = lhs;
872 struct constraint_expr temprhs = rhs;
873 unsigned HOST_WIDE_INT fieldoffset;
874 if (temprhs.type == SCALAR)
875 temprhs.var = p->id;
876 else
877 temprhs.offset = p->offset;
879 q = get_varinfo (templhs.var);
880 fieldoffset = p->offset - pstart;
881 templhs.offset += fieldoffset;
882 process_constraint (new_constraint (templhs, temprhs), false);
886 /* Handle aggregate copies by expanding into copies of the respective
887 fields of the structures. */
889 static void
890 do_structure_copy (tree lhsop, tree rhsop)
892 struct constraint_expr lhs, rhs, tmp;
893 varinfo_t p;
894 unsigned HOST_WIDE_INT lhssize;
895 unsigned HOST_WIDE_INT rhssize;
897 lhssize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (lhsop)));
898 rhssize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (rhsop)));
899 lhs = get_constraint_for (lhsop);
900 rhs = get_constraint_for (rhsop);
902 /* If we have special var = x, swap it around. */
903 if (lhs.var <= integer_id && rhs.var > integer_id)
905 tmp = lhs;
906 lhs = rhs;
907 rhs = tmp;
910 /* If the RHS is a special var, set all the LHS fields to that special var*/
911 if (rhs.var <= integer_id)
913 for (p = get_varinfo (lhs.var); p; p = p->next)
915 struct constraint_expr templhs = lhs;
916 struct constraint_expr temprhs = rhs;
917 if (templhs.type == SCALAR )
918 templhs.var = p->id;
919 else
920 templhs.offset += p->offset;
921 process_constraint (new_constraint (templhs, temprhs), false);
924 else
927 if (rhs.type == SCALAR && lhs.type == SCALAR)
928 do_simple_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
929 else if (lhs.type != DEREF && rhs.type == DEREF)
930 do_rhs_deref_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
931 else if (lhs.type == DEREF && rhs.type != DEREF)
932 do_lhs_deref_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
933 else
935 tree rhsdecl = get_varinfo (rhs.var)->decl;
936 tree pointertype = TREE_TYPE (rhsdecl);
937 tree pointedtotype = TREE_TYPE (pointertype);
938 tree tmpvar;
939 gcc_assert (rhs.type == DEREF && lhs.type == DEREF);
940 tmpvar = create_tmp_var_raw (pointedtotype, "structcopydereftmp");
942 lhs = get_constraint_for (tmpvar);
943 do_rhs_deref_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
944 rhs = lhs;
945 lhs = get_constraint_for (lhsop);
946 do_lhs_deref_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
951 /* Tree walker that is the heart of the aliasing infrastructure.
952 TP is a pointer to the current tree.
953 WALK_SUBTREES specifies whether to continue traversing subtrees or
954 not.
955 Returns NULL_TREE when we should stop.
957 This function is the main part of the aliasing infrastructure. It
958 walks the trees, calling the appropriate alias analyzer functions to process
959 various statements. */
961 static void
962 find_func_aliases (tree t)
964 struct constraint_expr lhs, rhs;
965 switch (TREE_CODE (t))
967 case PHI_NODE:
969 int i;
970 lhs = get_constraint_for (PHI_RESULT (t));
971 for (i = 0; i < PHI_NUM_ARGS (t); i++)
973 rhs = get_constraint_for (PHI_ARG_DEF (t, i));
974 process_constraint (new_constraint (lhs, rhs), true);
977 break;
978 case MODIFY_EXPR:
980 tree lhsop = TREE_OPERAND (t, 0);
981 tree rhsop = TREE_OPERAND (t, 1);
982 int i;
983 if (AGGREGATE_TYPE_P (TREE_TYPE (lhsop))
984 && AGGREGATE_TYPE_P (TREE_TYPE (rhsop)))
986 do_structure_copy (lhsop, rhsop);
988 else
990 lhs = get_constraint_for (lhsop);
991 switch (TREE_CODE_CLASS (TREE_CODE (rhsop)))
993 /* RHS that consist of unary operations, exceptional types, or
994 bare decls/constants, get handled directly by
995 get_constraint_for. */
996 case tcc_reference:
997 case tcc_declaration:
998 case tcc_constant:
999 case tcc_exceptional:
1000 case tcc_expression:
1001 case tcc_unary:
1003 rhs = get_constraint_for (rhsop);
1004 process_constraint (new_constraint (lhs, rhs), true);
1006 break;
1007 /* other classes, we walk each operator */
1008 default:
1009 for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (rhsop)); i++)
1011 tree op = TREE_OPERAND (rhsop, i);
1012 rhs = get_constraint_for (op);
1013 process_constraint (new_constraint (lhs, rhs), true);
1018 break;
1019 default:
1020 break;
1024 /* Find the first varinfo in the same variable as START that overlaps with
1025 OFFSET.
1026 Effectively, walk the chain of fields for the variable START to find the
1027 first field that overlaps with OFFSET.
1028 Abort if we can't find one. */
1030 static varinfo_t
1031 first_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset)
1033 varinfo_t curr = start->base;
1034 while (curr)
1036 if (offset >= curr->offset && offset < (curr->offset + curr->size))
1037 return curr;
1038 curr = curr->next;
1040 gcc_unreachable ();
1043 /* Starting from the variable START, find the *next* variable info in the *same*
1044 variable that overlaps with OFFSET.
1045 Effectively, walk the chain of fields starting at START to find the next
1046 field with that offset.
1047 Return NULL if we cannot find one. */
1049 static varinfo_t
1050 next_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset)
1052 varinfo_t curr = start->next;
1053 while (curr)
1055 if (offset >= curr->offset && offset < (curr->offset + curr->size))
1056 return curr;
1057 curr = curr->next;
1059 return curr;
1062 /* Insert the varinfo FIELD into the field list for BASE, ordered by offset,
1063 then size.
1065 FIXME: We uh, need to do the size comparison, and don't right now.
1068 static void
1069 insert_into_field_list (varinfo_t base, varinfo_t field)
1071 varinfo_t prev = base;
1072 varinfo_t curr = base->next;
1074 if (curr == NULL)
1076 prev->next = field;
1077 field->next = NULL;
1079 else
1081 while (curr)
1083 if (field->offset < (curr->offset + curr->size))
1084 break;
1085 prev = curr;
1086 curr = curr->next;
1088 field->next = prev->next;
1089 prev->next = field;
1093 /* This structure is simply used during pushing fields onto the fieldstack
1094 to track the offset of the field, since bitpos_of_field gives it relative
1095 to it's immediate containing type, and we want it relative to the ultimate
1096 containing object. */
1097 typedef struct fieldoff
1099 tree field;
1100 unsigned HOST_WIDE_INT offset;
1101 } *fieldoff_t;
1103 DEF_VEC_MALLOC_P(fieldoff_t);
1105 static void
1106 push_fields_onto_fieldstack (tree type, VEC (fieldoff_t) **fieldstack,
1107 unsigned HOST_WIDE_INT offset)
1109 fieldoff_t pair;
1110 tree field = TYPE_FIELDS (type);
1112 if (AGGREGATE_TYPE_P (TREE_TYPE (field))
1113 && TREE_CODE (TREE_TYPE (field)) != ARRAY_TYPE
1114 && TREE_CODE (field) == FIELD_DECL)
1116 size_t before = VEC_length (fieldoff_t, *fieldstack);
1117 /* Empty structures may have actual size, like in C++. So see if we
1118 actually end up pushing a field, and if not, if the size is non-zero,
1119 push the field onto the stack */
1120 push_fields_onto_fieldstack (TREE_TYPE (field), fieldstack, offset);
1121 if (before == VEC_length (fieldoff_t, *fieldstack)
1122 && DECL_SIZE (field)
1123 && !integer_zerop (DECL_SIZE (field)))
1125 pair = xmalloc (sizeof (struct fieldoff));
1126 pair->field = field;
1127 pair->offset = offset;
1128 VEC_safe_push (fieldoff_t, *fieldstack, pair);
1131 if (TREE_CODE (field) == FIELD_DECL)
1133 pair = xmalloc (sizeof (struct fieldoff));
1134 pair->field = field;
1135 pair->offset = offset;
1136 VEC_safe_push (fieldoff_t, *fieldstack, pair);
1138 for (field = TREE_CHAIN (field); field; field = TREE_CHAIN (field))
1140 if (TREE_CODE (field) != FIELD_DECL)
1141 continue;
1142 if (AGGREGATE_TYPE_P (TREE_TYPE (field))
1143 && TREE_CODE (TREE_TYPE (field)) != ARRAY_TYPE)
1145 push_fields_onto_fieldstack (TREE_TYPE (field), fieldstack,
1146 offset + bitpos_of_field (field));
1148 else
1150 pair = xmalloc (sizeof (struct fieldoff));
1151 pair->field = field;
1152 pair->offset = offset + bitpos_of_field (field);
1153 VEC_safe_push (fieldoff_t, *fieldstack, pair);
1158 /* Free the pairs still on the FIELDSTACK, and then free the FIELDSTACK. */
1160 static void
1161 cleanup_fieldstack (VEC (fieldoff_t) *fieldstack)
1163 while (VEC_length (fieldoff_t, fieldstack) != 0)
1165 fieldoff_t pair = VEC_pop (fieldoff_t, fieldstack);
1166 free (pair);
1168 VEC_free (fieldoff_t, fieldstack);
1171 /* Create a varinfo structure for NAME and DECL, and add it to the varmap.
1172 This will also create any variable infos necessary for fields of DECL. */
1174 static unsigned int
1175 create_variable_info_for (tree decl, const char *name)
1177 unsigned int index = VEC_length (varinfo_t, varmap);
1178 varinfo_t vi;
1179 tree decltype = TREE_TYPE (decl);
1180 vi = new_var_info (decl, index, name, index);
1181 vi->decl = decl;
1182 vi->base = vi;
1183 vi->offset = 0;
1184 if (!TYPE_SIZE (decltype)
1185 || TREE_CODE (TYPE_SIZE (decltype)) != INTEGER_CST
1186 || TREE_CODE (decltype) == ARRAY_TYPE)
1188 vi->is_unknown_size_var = true;
1189 vi->fullsize = ~0;
1190 vi->size = ~0;
1192 else
1194 vi->fullsize = TREE_INT_CST_LOW (TYPE_SIZE (decltype));
1195 vi->size = vi->fullsize;
1198 insert_id_for_tree (vi->decl, index);
1199 VEC_safe_push (varinfo_t, varmap, vi);
1201 stats.total_vars++;
1202 if (!vi->is_unknown_size_var && AGGREGATE_TYPE_P (decltype))
1204 unsigned int newindex = VEC_length (varinfo_t, varmap);
1205 fieldoff_t pair;
1206 tree field;
1207 VEC (fieldoff_t) *fieldstack = NULL;
1209 push_fields_onto_fieldstack (decltype, &fieldstack, 0);
1210 /* FIXME: We really want to find the field that would normally go first in
1211 the list here, not just the "first" field. That way, the sorting
1212 always comes out right. */
1213 pair = VEC_index (fieldoff_t, fieldstack, 0);
1214 VEC_replace (fieldoff_t, fieldstack, 0, NULL);
1215 if (pair == NULL)
1217 vi->is_unknown_size_var = 1;
1218 vi->fullsize = ~0;
1219 vi->size = ~0;
1220 cleanup_fieldstack (fieldstack);
1221 return index;
1224 field = pair->field;
1225 gcc_assert (bitpos_of_field (field) == 0);
1226 vi->size = TREE_INT_CST_LOW (DECL_SIZE (field));
1227 while (VEC_length (fieldoff_t, fieldstack) != 0)
1229 varinfo_t newvi;
1230 char *newname;
1231 pair = VEC_pop (fieldoff_t, fieldstack);
1232 if (pair == NULL)
1233 continue;
1234 field = pair->field;
1235 newindex = VEC_length (varinfo_t, varmap);
1236 newname = xcalloc (1, strlen (vi->name) + 2
1237 + strlen (alias_get_name (field)));
1238 /* sprintf (newname, "%s#" HOST_WIDE_INT_PRINT_DEC, name,
1239 pair->offset); */
1240 sprintf (newname, "%s.%s", vi->name, alias_get_name (field));
1241 newvi = new_var_info (decl, newindex, newname, newindex);
1242 newvi->base = vi;
1243 newvi->offset = pair->offset;
1244 newvi->size = TREE_INT_CST_LOW (DECL_SIZE (field));
1245 newvi->fullsize = vi->fullsize;
1246 insert_into_field_list (vi, newvi);
1247 VEC_safe_push (varinfo_t, varmap, newvi);
1248 free (pair);
1249 stats.total_vars++;
1251 VEC_free (fieldoff_t, fieldstack);
1253 return index;
1256 /* Print out the points-to solution for VAR to FILE. */
1258 void
1259 print_solution_for_var (FILE *file, unsigned int var)
1261 varinfo_t vi = get_varinfo (var);
1262 unsigned int i;
1263 bitmap_iterator bi;
1265 fprintf (file, "%s = {", vi->name);
1266 EXECUTE_IF_SET_IN_BITMAP (get_varinfo (vi->node)->solution, 0, i, bi)
1268 fprintf (file, "%s,", get_varinfo (i)->name);
1270 fprintf (file, "}\n");
1273 /* Print the points-to solution for VAR to stdout. */
1275 void
1276 debug_solution_for_var (unsigned int var)
1278 print_solution_for_var (stdout, var);
1281 /* Create varinfo structures for all of the variables in the
1282 function. */
1284 static void
1285 create_variable_infos (void)
1287 tree t;
1288 #if 0
1289 tree tmpvar;
1291 tmpvar = create_tmp_var_raw (ptr_type_node, "OUTSIDEOFFUNC");
1292 i = create_variable_info_for (tmpvar, "OUTSIDEOFFUNC");
1293 get_varinfo (i)->is_artificial_var = 1;
1294 #endif
1295 for (t = DECL_ARGUMENTS (current_function_decl);
1297 t = TREE_CHAIN (t))
1299 struct constraint_expr lhs;
1300 struct constraint_expr rhs;
1301 size_t lhsvar;
1302 varinfo_t p;
1304 lhs.offset = 0;
1305 lhs.type = SCALAR;
1306 lhs.var = create_variable_info_for (t, alias_get_name (t));
1308 get_varinfo (lhs.var)->is_artificial_var = true;
1309 #if 0
1310 rhs.var = lookup_id_for_tree (tmpvar);
1311 #else
1312 rhs.var = anything_id;
1313 #endif
1314 rhs.type = ADDRESSOF;
1315 rhs.offset = 0;
1316 lhsvar = lhs.var;
1318 for (p = get_varinfo (lhsvar)->next; p; p = p->next)
1320 struct constraint_expr temp = lhs;
1321 temp.var = p->id;
1322 process_constraint (new_constraint (temp, rhs), false);
1328 /* Return true if two constraint expressions are equal. */
1330 static bool
1331 constraint_expr_equal (struct constraint_expr a, struct constraint_expr b)
1333 return a.type == b.type
1334 && a.var == b.var
1335 && a.offset == b.offset;
1338 /* Return true if constraint expression a is less than constraint expression
1339 b. This is just arbitrary, but consistent, in order to give them an
1340 ordering. */
1342 static bool
1343 constraint_expr_less (struct constraint_expr a, struct constraint_expr b)
1345 if (a.type == b.type)
1347 if (a.var == b.var)
1348 return a.offset < b.offset;
1349 else
1350 return a.var < b.var;
1352 else
1353 return a.type < b.type;
1356 /* Return true if constraint e is less than constraint b. This is just
1357 arbitrary, but consistent, in order to give them an ordering. */
1359 static bool
1360 constraint_less (const constraint_t a, const constraint_t b)
1362 if (constraint_expr_less (a->lhs, b->lhs))
1363 return true;
1364 else if (constraint_expr_less (b->lhs, a->lhs))
1365 return false;
1366 else
1367 return constraint_expr_less (a->rhs, b->rhs);
1370 /* Return true if two constraints are equal. */
1372 static bool
1373 constraint_equal (struct constraint a, struct constraint b)
1375 return constraint_expr_equal (a.lhs, b.lhs)
1376 && constraint_expr_equal (a.rhs, b.rhs);
1380 /* Find a constraint LOOKFOR in the sorted constraint vector VEC */
1382 static constraint_t
1383 constraint_vec_find (VEC(constraint_t) *vec,
1384 struct constraint lookfor)
1386 unsigned int place;
1387 constraint_t found;
1388 if (vec == NULL)
1389 return NULL;
1391 place = VEC_lower_bound (constraint_t, vec, &lookfor, constraint_less);
1392 if (place >= VEC_length (constraint_t, vec))
1393 return NULL;
1394 found = VEC_index (constraint_t, vec, place);
1395 if (!constraint_equal (*found, lookfor))
1396 return NULL;
1397 return found;
1400 /* Union two constraint vectors, TO and FROM. Put the result in TO. */
1402 static void
1403 constraint_set_union (VEC(constraint_t) **to,
1404 VEC(constraint_t) **from)
1406 int i;
1407 constraint_t c;
1408 for (i = 0; VEC_iterate (constraint_t,*from, i, c); i++)
1410 if (constraint_vec_find (*to, *c) == NULL)
1412 unsigned int place = VEC_lower_bound (constraint_t, *to, c,
1413 constraint_less);
1414 VEC_safe_insert (constraint_t, *to, place, c);
1419 /* Take a solution set SET, add OFFSET to each member of the set,
1420 and return the result. */
1422 static void
1423 solution_set_add (bitmap set, unsigned HOST_WIDE_INT offset)
1425 bitmap result = BITMAP_ALLOC (NULL);
1426 unsigned int i;
1427 bitmap_iterator bi;
1429 EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi)
1431 /* If this is a properly sized variable, only add offset if it's less than
1432 end. Otherwise, it is globbed to a single variable. */
1434 if ((get_varinfo (i)->offset + offset) < get_varinfo (i)->fullsize)
1436 unsigned HOST_WIDE_INT fieldoffset = get_varinfo (i)->offset + offset;
1437 varinfo_t v;
1438 for (v = first_vi_for_offset (get_varinfo (i), fieldoffset);
1440 v = next_vi_for_offset (v, fieldoffset))
1442 bitmap_set_bit (result, v->id);
1445 else if (get_varinfo (i)->is_artificial_var
1446 || get_varinfo (i)->is_unknown_size_var)
1448 bitmap_set_bit (result, i);
1452 bitmap_copy (set, result);
1453 BITMAP_FREE (result);
1456 /* Union solution sets TO and FROM, and add INC to each member of FROM in the
1457 process. */
1459 static bool
1460 set_union_with_increment (bitmap to, bitmap from, unsigned HOST_WIDE_INT inc)
1462 if (inc == 0)
1463 return bitmap_ior_into (to, from);
1464 else
1466 bitmap tmp;
1467 bool res;
1468 tmp = BITMAP_ALLOC (NULL);
1469 bitmap_copy (tmp, from);
1470 solution_set_add (tmp, inc);
1471 res = bitmap_ior_into (to, tmp);
1472 BITMAP_FREE (tmp);
1473 return res;
1477 /* Insert C into the list of complex constraints for VAR. */
1479 static void
1480 insert_into_complicated (unsigned int var, constraint_t c)
1482 varinfo_t vi = get_varinfo (var);
1483 unsigned int place = VEC_lower_bound (constraint_t, vi->complicated, c,
1484 constraint_less);
1485 VEC_safe_insert (constraint_t, vi->complicated, place, c);
1489 /* Compare two constraint edges, return true if they are equal. */
1491 static bool
1492 constraint_edge_equal (struct constraint_edge a, struct constraint_edge b)
1494 return a.src == b.src && a.dest == b.dest;
1497 /* Compare two constraint edges, return true if A is less than B */
1499 static bool
1500 constraint_edge_less (const constraint_edge_t a, const constraint_edge_t b)
1502 if (a->dest < b->dest)
1503 return true;
1504 else if (a->dest == b->dest)
1505 return a->src < b->src;
1506 else
1507 return false;
1510 /* Find the constraint edge that matches LOOKFOR, in VEC.
1511 Return the edge, if found, NULL otherwise. */
1513 static constraint_edge_t
1514 constraint_edge_vec_find (VEC(constraint_edge_t) *vec,
1515 struct constraint_edge lookfor)
1517 unsigned int place;
1518 constraint_edge_t edge;
1519 place = VEC_lower_bound (constraint_edge_t, vec, &lookfor,
1520 constraint_edge_less);
1521 edge = VEC_index (constraint_edge_t, vec, place);
1522 if (!constraint_edge_equal (*edge, lookfor))
1523 return NULL;
1524 return edge;
1527 /* Condense two variable nodes into a single variable node */
1529 static void
1530 condense_varmap_nodes (unsigned int to, unsigned int src)
1532 varinfo_t tovi = get_varinfo (to);
1533 varinfo_t srcvi = get_varinfo (src);
1534 unsigned int i;
1535 constraint_t c;
1536 bitmap_iterator bi;
1538 /* the src node, and all it's variables, are now the to node. */
1539 srcvi->node = to;
1540 EXECUTE_IF_SET_IN_BITMAP (srcvi->variables, 0, i, bi)
1542 get_varinfo (i)->node = to;
1545 /* Merge the src node variables and the to node variables. */
1546 bitmap_set_bit (tovi->variables, src);
1547 bitmap_ior_into (tovi->variables, srcvi->variables);
1548 bitmap_clear (srcvi->variables);
1550 /* Move all complex constraints to the to node */
1551 for (i = 0; VEC_iterate (constraint_t, srcvi->complicated, i, c); i++)
1553 if (c->rhs.type == DEREF)
1555 c->rhs.var = to;
1557 else
1559 c->lhs.var = to;
1562 constraint_set_union (&tovi->complicated, &srcvi->complicated);
1563 srcvi->complicated = NULL;
1566 /* Erase EDGE from the graph. */
1568 static void
1569 erase_graph_edge (constraint_graph_t graph, struct constraint_edge edge)
1571 VEC(constraint_edge_t) *predvec = graph->preds[edge.src];
1572 VEC(constraint_edge_t) *succvec = graph->succs[edge.dest];
1573 struct constraint_edge succe;
1574 unsigned int place;
1576 /* The successor will have the edges reversed. */
1577 succe.dest = edge.src;
1578 succe.src = edge.dest;
1579 /* Remove from the successors. */
1580 place = VEC_lower_bound (constraint_edge_t, succvec, &succe,
1581 constraint_edge_less);
1582 VEC_ordered_remove (constraint_edge_t, succvec, place);
1583 /* Remove from the predecessors. */
1584 place = VEC_lower_bound (constraint_edge_t, predvec, &edge,
1585 constraint_edge_less);
1586 VEC_ordered_remove (constraint_edge_t, predvec, place);
1589 /* Remove edges involving node from graph. */
1591 static void
1592 clear_edges_for_node (constraint_graph_t graph, unsigned int node)
1594 VEC(constraint_edge_t) *succvec = graph->succs[node];
1595 VEC(constraint_edge_t) *predvec = graph->preds[node];
1596 constraint_edge_t c;
1597 int i;
1599 /* Walk the successors, erase the associated preds. */
1600 for (i = 0; VEC_iterate (constraint_edge_t, succvec, i, c); i++)
1601 if (c->dest != node)
1603 unsigned int place;
1604 struct constraint_edge lookfor;
1605 lookfor.src = c->dest;
1606 lookfor.dest = node;
1607 place = VEC_lower_bound (constraint_edge_t, graph->preds[c->dest],
1608 &lookfor, constraint_edge_less);
1609 VEC_ordered_remove (constraint_edge_t, graph->preds[c->dest], place);
1611 /* Walk the preds, erase the associated succs. */
1612 for (i =0; VEC_iterate (constraint_edge_t, predvec, i, c); i++)
1613 if (c->dest != node)
1615 unsigned int place;
1616 struct constraint_edge lookfor;
1617 lookfor.src = c->dest;
1618 lookfor.dest = node;
1619 place = VEC_lower_bound (constraint_edge_t, graph->succs[c->dest],
1620 &lookfor, constraint_edge_less);
1621 VEC_ordered_remove (constraint_edge_t, graph->succs[c->dest], place);
1624 graph->preds[node] = NULL;
1625 graph->succs[node] = NULL;
1627 static bool int_add_graph_edge (constraint_graph_t, unsigned int,
1628 unsigned int, unsigned HOST_WIDE_INT);
1629 static bool add_graph_edge (constraint_graph_t, struct constraint_edge);
1630 static bitmap get_graph_weights (constraint_graph_t, struct constraint_edge);
1633 /* Merge graph nodes w and n into node n. */
1635 static void
1636 merge_graph_nodes (constraint_graph_t graph, unsigned int n, unsigned int w)
1638 VEC(constraint_edge_t) *succvec = graph->succs[w];
1639 VEC(constraint_edge_t) *predvec = graph->preds[w];
1640 int i;
1641 constraint_edge_t c;
1643 for (i = 0; VEC_iterate (constraint_edge_t, predvec, i, c); i++)
1645 unsigned int d = c->dest;
1646 struct constraint_edge olde;
1647 struct constraint_edge newe;
1648 bitmap temp;
1649 bitmap weights;
1650 if (c->dest == w)
1651 d = n;
1652 newe.src = n;
1653 newe.dest = d;
1654 add_graph_edge (graph, newe);
1655 olde.src = w;
1656 olde.dest = c->dest;
1657 temp = get_graph_weights (graph, olde);
1658 weights = get_graph_weights (graph, newe);
1659 bitmap_ior_into (weights, temp);
1662 for (i = 0; VEC_iterate (constraint_edge_t, succvec, i, c); i++)
1664 unsigned int d = c->dest;
1665 struct constraint_edge olde;
1666 struct constraint_edge newe;
1667 bitmap temp;
1668 bitmap weights;
1669 if (c->dest == w)
1670 d = n;
1671 newe.src = d;
1672 newe.dest = n;
1673 add_graph_edge (graph, newe);
1674 olde.src = c->dest;
1675 olde.dest = w;
1676 temp = get_graph_weights (graph, olde);
1677 weights = get_graph_weights (graph, newe);
1678 bitmap_ior_into (weights, temp);
1680 clear_edges_for_node (graph, w);
1683 /* Add a graph edge going from TO to FROM, with WEIGHT. */
1685 static bool
1686 int_add_graph_edge (constraint_graph_t graph, unsigned int to,
1687 unsigned int from, unsigned HOST_WIDE_INT weight)
1689 if (to == from && weight == 0)
1691 return false;
1693 else
1695 bool r;
1696 struct constraint_edge edge;
1697 edge.src = to;
1698 edge.dest = from;
1699 r = add_graph_edge (graph, edge);
1700 r |= !bitmap_bit_p (get_graph_weights (graph, edge), weight);
1701 bitmap_set_bit (get_graph_weights (graph, edge), weight);
1702 return r;
1707 /* Add edge NEWE to the graph. */
1709 static bool
1710 add_graph_edge (constraint_graph_t graph, struct constraint_edge newe)
1712 unsigned int place;
1713 unsigned int src = newe.src;
1714 unsigned int dest = newe.dest;
1715 VEC(constraint_edge_t) *vec;
1716 vec = graph->preds[src];
1717 place = VEC_lower_bound (constraint_edge_t, vec, &newe,
1718 constraint_edge_less);
1719 if (place == VEC_length (constraint_edge_t, vec)
1720 || VEC_index (constraint_edge_t, vec, place)->dest != dest)
1722 constraint_edge_t edge = new_constraint_edge (src, dest);
1723 bitmap weightbitmap;
1724 weightbitmap = BITMAP_GGC_ALLOC ();
1725 edge->weights = weightbitmap;
1726 VEC_safe_insert (constraint_edge_t, graph->preds[edge->src], place, edge);
1727 edge = new_constraint_edge (dest, src);
1728 edge->weights = weightbitmap;
1729 place = VEC_lower_bound (constraint_edge_t, graph->succs[edge->src],
1730 edge, constraint_edge_less);
1731 VEC_safe_insert (constraint_edge_t, graph->succs[edge->src], place, edge);
1732 return true;
1734 else
1735 return false;
1738 /* Return true if LOOKFOR is an existing graph edge. */
1740 static bool
1741 valid_graph_edge (constraint_graph_t graph, struct constraint_edge lookfor)
1743 return constraint_edge_vec_find (graph->preds[lookfor.src], lookfor) != NULL;
1747 /* Return the bitmap representing the weights of edge LOOKFOR */
1749 static bitmap
1750 get_graph_weights (constraint_graph_t graph, struct constraint_edge lookfor)
1752 constraint_edge_t edge;
1753 unsigned int src = lookfor.src;
1754 VEC(constraint_edge_t) *vec;
1755 vec = graph->preds[src];
1756 edge = constraint_edge_vec_find (vec, lookfor);
1757 gcc_assert (edge != NULL);
1758 return edge->weights;
1761 /* Build the constraint graph. */
1763 static void
1764 build_constraint_graph (void)
1766 int i = 0;
1767 constraint_t c;
1768 graph = ggc_alloc (sizeof (struct constraint_graph));
1769 graph->succs = ggc_alloc_cleared (VEC_length (varinfo_t, varmap) * sizeof (*graph->succs));
1770 graph->preds = ggc_alloc_cleared (VEC_length (varinfo_t, varmap) * sizeof (*graph->preds));
1771 for (i = 0; VEC_iterate (constraint_t, constraints, i, c); i++)
1773 struct constraint_expr lhs = c->lhs;
1774 struct constraint_expr rhs = c->rhs;
1775 if (lhs.type == DEREF)
1777 /* *x = y or *x = &y (complex) */
1778 if (rhs.type == ADDRESSOF || rhs.var > anything_id)
1779 insert_into_complicated (lhs.var, c);
1781 else if (rhs.type == DEREF)
1783 /* NOT UNKNOWN = *y */
1784 if (lhs.var > anything_id)
1785 insert_into_complicated (rhs.var, c);
1787 else if (rhs.type == ADDRESSOF)
1789 /* x = &y */
1790 bitmap_set_bit (get_varinfo (lhs.var)->solution, rhs.var);
1792 else if (rhs.var > anything_id && lhs.var > anything_id)
1794 /* Ignore 0 weighted self edges, as they can't possibly contribute
1795 anything */
1796 if (lhs.var != rhs.var || rhs.offset != 0 || lhs.offset != 0)
1799 struct constraint_edge edge;
1800 edge.src = lhs.var;
1801 edge.dest = rhs.var;
1802 /* x = y (simple) */
1803 add_graph_edge (graph, edge);
1804 bitmap_set_bit (get_graph_weights (graph, edge),
1805 rhs.offset);
1811 /* Changed variables on the last iteration. */
1812 static unsigned int changed_count;
1813 static sbitmap changed;
1815 /* Strongly Connected Component visitation info. */
1817 struct scc_info
1819 sbitmap visited;
1820 sbitmap in_component;
1821 int current_index;
1822 unsigned int *visited_index;
1823 varray_type scc_stack;
1824 varray_type unification_queue;
1827 /* Recursive routine to find strongly connected components in GRAPH. */
1829 static void
1830 scc_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
1832 constraint_edge_t c;
1833 int i;
1834 gcc_assert (get_varinfo (n)->node == n);
1835 SET_BIT (si->visited, n);
1836 RESET_BIT (si->in_component, n);
1837 si->visited_index[n] = si->current_index ++;
1839 /* Visit all the successors. */
1840 for (i = 0; VEC_iterate (constraint_edge_t, graph->succs[n], i, c); i++)
1842 /* We only want to collapse the zero weight edges. */
1843 if (bitmap_bit_p (c->weights, 0))
1845 unsigned int w = c->dest;
1846 if (!TEST_BIT (si->visited, w))
1847 scc_visit (graph, si, w);
1848 if (!TEST_BIT (si->in_component, w))
1850 unsigned int t = get_varinfo (w)->node;
1851 unsigned int nnode = get_varinfo (n)->node;
1852 if (si->visited_index[t] < si->visited_index[nnode])
1854 get_varinfo (n)->node = t;
1860 /* See if any components have been identified. */
1861 if (get_varinfo (n)->node == n)
1863 unsigned int t = si->visited_index[n];
1864 SET_BIT (si->in_component, n);
1865 while (VARRAY_ACTIVE_SIZE (si->scc_stack) != 0
1866 && t < si->visited_index[VARRAY_TOP_UINT (si->scc_stack)])
1868 unsigned int w = VARRAY_TOP_UINT (si->scc_stack);
1869 get_varinfo (w)->node = n;
1870 SET_BIT (si->in_component, w);
1871 /* Mark this node for collapsing. */
1872 VARRAY_PUSH_UINT (si->unification_queue, w);
1873 VARRAY_POP (si->scc_stack);
1876 else
1877 VARRAY_PUSH_UINT (si->scc_stack, n);
1880 /* Collapse two variables into one variable. */
1882 static void
1883 collapse_nodes (constraint_graph_t graph, unsigned int to, unsigned int from)
1885 bitmap tosol, fromsol;
1886 struct constraint_edge edge;
1887 condense_varmap_nodes (to, from);
1888 tosol = get_varinfo (to)->solution;
1889 fromsol = get_varinfo (from)->solution;
1890 bitmap_ior_into (tosol, fromsol);
1891 merge_graph_nodes (graph, to, from);
1892 edge.src = to;
1893 edge.dest = to;
1894 if (valid_graph_edge (graph, edge))
1896 bitmap weights = get_graph_weights (graph, edge);
1897 bitmap_clear_bit (weights, 0);
1898 if (bitmap_empty_p (weights))
1899 erase_graph_edge (graph, edge);
1901 bitmap_clear (fromsol);
1902 get_varinfo (to)->address_taken |= get_varinfo (from)->address_taken;
1903 get_varinfo (to)->indirect_target |= get_varinfo (from)->indirect_target;
1907 /* Unify nodes that we have found to be part of a cycle. */
1909 static void
1910 process_unification_queue (constraint_graph_t graph, struct scc_info *si,
1911 bool update_changed)
1913 size_t i = 0;
1914 bitmap tmp = BITMAP_ALLOC (NULL);
1915 bitmap_clear (tmp);
1916 while (i != VARRAY_ACTIVE_SIZE (si->unification_queue))
1918 unsigned int tounify = VARRAY_UINT (si->unification_queue, i);
1919 unsigned int n = get_varinfo (tounify)->node;
1920 bool domore = false;
1921 if (dump_file && (dump_flags & TDF_DETAILS))
1922 fprintf (dump_file, "Unifying %s to %s\n",
1923 get_varinfo (tounify)->name,
1924 get_varinfo (n)->name);
1925 if (update_changed)
1926 stats.unified_vars_dynamic++;
1927 else
1928 stats.unified_vars_static++;
1929 bitmap_ior_into (tmp, get_varinfo (tounify)->solution);
1930 merge_graph_nodes (graph, n, tounify);
1931 condense_varmap_nodes (n, tounify);
1933 if (update_changed && TEST_BIT (changed, tounify))
1935 RESET_BIT (changed, tounify);
1936 if (!TEST_BIT (changed, n))
1937 SET_BIT (changed, n);
1938 else
1940 gcc_assert (changed_count > 0);
1941 changed_count--;
1944 bitmap_clear (get_varinfo (tounify)->solution);
1945 ++i;
1946 if (i == VARRAY_ACTIVE_SIZE (si->unification_queue))
1947 domore = true;
1948 if (!domore)
1950 tounify = VARRAY_UINT (si->unification_queue, i);
1951 if (get_varinfo (tounify)->node != n)
1952 domore = true;
1954 if (domore)
1956 struct constraint_edge edge;
1957 /* If the solution changes because of the merging, we need to mark
1958 the variable as changed. */
1959 if (bitmap_ior_into (get_varinfo (n)->solution, tmp))
1961 if (update_changed && !TEST_BIT (changed, n))
1963 SET_BIT (changed, n);
1964 changed_count++;
1967 bitmap_clear (tmp);
1968 edge.src = n;
1969 edge.dest = n;
1970 if (valid_graph_edge (graph, edge))
1972 bitmap weights = get_graph_weights (graph, edge);
1973 bitmap_clear_bit (weights, 0);
1974 if (bitmap_empty_p (weights))
1975 erase_graph_edge (graph, edge);
1979 BITMAP_FREE (tmp);
1982 /* Information needed to compute the topographic ordering of a graph. */
1984 struct topo_info
1986 /* sbitmap of visited nodes. */
1987 sbitmap visited;
1988 /* Array that stores the topographic order of the graph, *in
1989 reverse*. */
1990 varray_type topo_order;
1993 /* Initialize and return a topograph info structure. */
1995 static struct topo_info *
1996 init_topo_info (void)
1998 size_t size = VEC_length (varinfo_t, varmap);
1999 struct topo_info *ti = xmalloc (sizeof (struct topo_info));
2000 ti->visited = sbitmap_alloc (size);
2001 sbitmap_zero (ti->visited);
2002 VARRAY_UINT_INIT (ti->topo_order, 1, "Topological ordering");
2003 return ti;
2006 /* Free the topographic sort info pointed to by TI. */
2008 static void
2009 free_topo_info (struct topo_info *ti)
2011 sbitmap_free (ti->visited);
2012 VARRAY_CLEAR (ti->topo_order);
2013 free (ti);
2016 /* Visit the graph in topographical order, and store the order in the
2017 topo_info structure. */
2019 static void
2020 topo_visit (constraint_graph_t graph, struct topo_info *ti,
2021 unsigned int n)
2023 VEC(constraint_edge_t) *succs = graph->succs[n];
2024 constraint_edge_t c;
2025 int i;
2026 SET_BIT (ti->visited, n);
2027 for (i = 0; VEC_iterate (constraint_edge_t, succs, i, c); i++)
2029 if (!TEST_BIT (ti->visited, c->dest))
2030 topo_visit (graph, ti, c->dest);
2032 VARRAY_PUSH_UINT (ti->topo_order, n);
2035 /* Return true if variable N + OFFSET is a legal field of N. */
2037 static bool
2038 type_safe (unsigned int n, unsigned HOST_WIDE_INT *offset)
2040 varinfo_t ninfo = get_varinfo (n);
2041 /* For things we've globbed to single variables, any offset into the
2042 variable acts like the entire variable, so that it becomes offset 0. */
2043 if (n == anything_id
2044 || ninfo->is_artificial_var
2045 || ninfo->is_unknown_size_var)
2047 *offset = 0;
2048 return true;
2050 return n > anything_id && (get_varinfo (n)->offset + *offset) < get_varinfo (n)->fullsize;
2053 /* Process a constraint C that represents *x = &y. */
2055 static void
2056 do_da_constraint (constraint_graph_t graph ATTRIBUTE_UNUSED,
2057 constraint_t c, bitmap delta)
2059 unsigned int rhs = c->rhs.var;
2060 unsigned HOST_WIDE_INT offset = c->lhs.offset;
2061 unsigned int j;
2062 bitmap_iterator bi;
2064 EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
2066 if (type_safe (j, &offset))
2068 /* *x != NULL && *x != UNKNOWN */
2069 varinfo_t v;
2070 unsigned HOST_WIDE_INT fieldoffset = get_varinfo (j)->offset + offset;
2071 for (v = first_vi_for_offset (get_varinfo (j), fieldoffset);
2073 v = next_vi_for_offset (v, fieldoffset))
2075 unsigned int t = v->node;
2076 bitmap sol = get_varinfo (t)->solution;
2077 if (!bitmap_bit_p (sol, rhs))
2079 bitmap_set_bit (sol, rhs);
2080 if (!TEST_BIT (changed, t))
2082 SET_BIT (changed, t);
2083 changed_count++;
2088 else if (dump_file)
2089 fprintf (dump_file, "Untypesafe usage in do_da_constraint.\n");
2094 /* Process a constraint C that represents x = *y, using DELTA as the
2095 starting solution. */
2097 static void
2098 do_sd_constraint (constraint_graph_t graph, constraint_t c,
2099 bitmap delta)
2101 unsigned int lhs = get_varinfo (c->lhs.var)->node;
2102 unsigned HOST_WIDE_INT roffset = c->rhs.offset;
2103 bool flag = false;
2104 bitmap sol = get_varinfo (lhs)->solution;
2105 unsigned int j;
2106 bitmap_iterator bi;
2108 /* For each variable j in delta (the starting solution point), we add
2109 an edge in the graph from the LHS to j + RHS offset, and update
2110 the current LHS solution. */
2111 EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
2113 if (type_safe (j, &roffset))
2115 varinfo_t v;
2116 unsigned HOST_WIDE_INT fieldoffset = get_varinfo (j)->offset + roffset;
2117 for (v = first_vi_for_offset (get_varinfo (j), fieldoffset);
2119 v = next_vi_for_offset (v, fieldoffset))
2121 unsigned int t = v->node;
2122 if (int_add_graph_edge (graph, lhs, t, 0))
2123 flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
2127 else if (dump_file)
2128 fprintf (dump_file, "Untypesafe usage in do_sd_constraint\n");
2132 /* If the LHS solution changed, update it. */
2133 if (flag)
2135 get_varinfo (lhs)->solution = sol;
2136 if (!TEST_BIT (changed, lhs))
2138 SET_BIT (changed, lhs);
2139 changed_count++;
2144 /* Process a constraint C that represents *x = y. */
2146 static void
2147 do_ds_constraint (constraint_graph_t graph, constraint_t c, bitmap delta)
2149 unsigned int rhs = get_varinfo (c->rhs.var)->node;
2150 unsigned HOST_WIDE_INT loff = c->lhs.offset;
2151 unsigned HOST_WIDE_INT roff = c->rhs.offset;
2152 bitmap sol = get_varinfo (rhs)->solution;
2153 unsigned int j;
2154 bitmap_iterator bi;
2156 EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
2158 if (type_safe (j, &loff))
2160 varinfo_t v;
2161 unsigned HOST_WIDE_INT fieldoffset = get_varinfo (j)->offset + loff;
2162 for (v = first_vi_for_offset (get_varinfo (j), fieldoffset);
2164 v = next_vi_for_offset (v, fieldoffset))
2166 unsigned int t = v->node;
2168 if (int_add_graph_edge (graph, t, rhs, roff))
2170 bitmap tmp = get_varinfo (t)->solution;
2171 if (set_union_with_increment (tmp, sol, roff))
2173 get_varinfo (t)->solution = tmp;
2174 if (t == rhs)
2176 sol = get_varinfo (rhs)->solution;
2178 if (!TEST_BIT (changed, t))
2180 SET_BIT (changed, t);
2181 changed_count++;
2187 else if (dump_file)
2188 fprintf (dump_file, "Untypesafe usage in do_ds_constraint\n");
2192 /* Handle a non-simple (simple meaning requires no iteration), non-copy
2193 constraint (IE *x = &y, x = *y, and *x = y). */
2195 static void
2196 do_complex_constraint (constraint_graph_t graph, constraint_t c, bitmap delta)
2198 if (c->lhs.type == DEREF)
2200 if (c->rhs.type == ADDRESSOF)
2202 /* *x = &y */
2203 do_da_constraint (graph, c, delta);
2205 else
2207 /* *x = y */
2208 do_ds_constraint (graph, c, delta);
2211 else
2213 /* x = *y */
2214 do_sd_constraint (graph, c, delta);
2218 /* Initialize and return a new SCC info structure. */
2220 static struct scc_info *
2221 init_scc_info (void)
2223 struct scc_info *si = xmalloc (sizeof (struct scc_info));
2224 size_t size = VEC_length (varinfo_t, varmap);
2225 si->current_index = 0;
2226 si->visited = sbitmap_alloc (size);
2227 sbitmap_zero (si->visited);
2228 si->in_component = sbitmap_alloc (size);
2229 sbitmap_ones (si->in_component);
2230 si->visited_index = xcalloc (sizeof (unsigned int), size + 1);
2231 VARRAY_UINT_INIT (si->scc_stack, 1, "SCC stack");
2232 VARRAY_UINT_INIT (si->unification_queue, 1, "Unification queue");
2233 return si;
2236 /* Free an SCC info structure pointed to by SI */
2238 static void
2239 free_scc_info (struct scc_info *si)
2241 sbitmap_free (si->visited);
2242 sbitmap_free (si->in_component);
2243 free (si->visited_index);
2244 VARRAY_CLEAR (si->scc_stack);
2245 VARRAY_CLEAR (si->unification_queue);
2246 free(si);
2250 /* Find cycles in GRAPH that occur, using strongly connected components, and
2251 collapse the cycles into a single representative node. if UPDATE_CHANGED
2252 is true, then update the changed sbitmap to note those nodes whose
2253 solutions have changed as a result of collapsing. */
2255 static void
2256 find_and_collapse_graph_cycles (constraint_graph_t graph, bool update_changed)
2258 unsigned int i;
2259 unsigned int size = VEC_length (varinfo_t, varmap);
2260 struct scc_info *si = init_scc_info ();
2262 for (i = 0; i != size; ++i)
2263 if (!TEST_BIT (si->visited, i) && get_varinfo (i)->node == i)
2264 scc_visit (graph, si, i);
2265 process_unification_queue (graph, si, update_changed);
2266 free_scc_info (si);
2269 /* Compute a topographic order for GRAPH, and store the result in the
2270 topo_info structure TI. */
2272 static void
2273 compute_topo_order (constraint_graph_t graph,
2274 struct topo_info *ti)
2276 unsigned int i;
2277 unsigned int size = VEC_length (varinfo_t, varmap);
2279 for (i = 0; i != size; ++i)
2280 if (!TEST_BIT (ti->visited, i) && get_varinfo (i)->node == i)
2281 topo_visit (graph, ti, i);
2284 /* Return true if bitmap B is empty, or a bitmap other than bit 0 is set. */
2286 static bool
2287 bitmap_other_than_zero_bit_set (bitmap b)
2289 unsigned int i;
2290 bitmap_iterator bi;
2291 if (bitmap_empty_p (b))
2292 return false;
2293 EXECUTE_IF_SET_IN_BITMAP (b, 1, i, bi)
2294 return true;
2295 return false;
2298 /* Perform offline variable substitution, as per Rountev and Chandra.
2299 This is a linear time way of identifying variables that must have
2300 equivalent points-to sets, including those caused by static cycles,
2301 and single entry subgraphs, in the constraint graph. */
2303 static void
2304 perform_rountev_chandra (constraint_graph_t graph)
2306 struct topo_info *ti = init_topo_info ();
2308 /* Compute the topographic ordering of the graph, then visit each
2309 node in topographic order. */
2310 compute_topo_order (graph, ti);
2312 while (VARRAY_ACTIVE_SIZE (ti->topo_order) != 0)
2314 unsigned int i = VARRAY_TOP_UINT (ti->topo_order);
2315 unsigned int pred;
2316 varinfo_t vi = get_varinfo (i);
2317 bool okay_to_elim = false;
2318 unsigned int root = VEC_length (varinfo_t, varmap);
2319 VEC(constraint_edge_t) *predvec = graph->preds[i];
2320 constraint_edge_t ce;
2321 bitmap tmp;
2323 VARRAY_POP (ti->topo_order);
2325 /* We can't eliminate things whose address is taken, or which is
2326 the target of a dereference. */
2327 if (vi->address_taken || vi->indirect_target)
2328 continue;
2329 for (pred = 0; VEC_iterate (constraint_edge_t, predvec, pred, ce); pred++)
2331 bitmap weight;
2332 unsigned int w;
2333 weight = get_graph_weights (graph, *ce);
2335 /* We can't eliminate variables that have non-zero weighted
2336 edges between them. */
2337 if (bitmap_other_than_zero_bit_set (weight))
2339 okay_to_elim = false;
2340 break;
2342 w = get_varinfo (ce->dest)->node;
2343 /* We can't eliminate the node if one of the predecessors is
2344 part of a different strongly connected component. */
2345 if (!okay_to_elim)
2347 root = w;
2348 okay_to_elim = true;
2350 else if (w != root)
2352 okay_to_elim = false;
2353 break;
2355 /* Theorem 4 in Rountev and Chandra: If i is a direct node,
2356 then Solution(i) is a subset of Solution (w), where w is a
2357 predecessor in the graph.
2358 Corrolary: If all predecessors of i have the same
2359 points-to set, then i has that same points-to set as
2360 those predecessors. */
2361 tmp = BITMAP_ALLOC (NULL);
2362 bitmap_and_compl (tmp, get_varinfo (i)->solution,
2363 get_varinfo (w)->solution);
2364 if (!bitmap_empty_p (tmp))
2366 okay_to_elim = false;
2367 BITMAP_FREE (tmp);
2368 break;
2370 BITMAP_FREE (tmp);
2372 /* See if the root is different than the original node.
2373 If so, we've found an equivalence. */
2374 if (root != get_varinfo (i)->node && okay_to_elim)
2376 /* Found an equivalence */
2377 get_varinfo (i)->node = root;
2378 collapse_nodes (graph, root, i);
2379 if (dump_file && (dump_flags & TDF_DETAILS))
2380 fprintf (dump_file, "Collapsing %s into %s\n",
2381 get_varinfo (i)->name,
2382 get_varinfo (root)->name);
2383 stats.collapsed_vars++;
2386 free_topo_info (ti);
2389 /* Solve the constraint graph GRAPH. */
2391 static void
2392 solve_graph (constraint_graph_t graph)
2394 unsigned int size = VEC_length (varinfo_t, varmap);
2395 unsigned int i;
2396 changed_count = size;
2397 changed = sbitmap_alloc (size);
2398 sbitmap_ones (changed);
2400 /* The already collapsed/unreachable nodes will never change, so we
2401 need to account for them in changed_count. */
2402 for (i = 0; i < size; i++)
2403 if (get_varinfo (i)->node != i)
2404 changed_count--;
2406 while (changed_count > 0)
2408 unsigned int i;
2409 struct topo_info *ti = init_topo_info ();
2410 stats.iterations++;
2411 find_and_collapse_graph_cycles (graph, true);
2412 compute_topo_order (graph, ti);
2413 while (VARRAY_ACTIVE_SIZE (ti->topo_order) != 0)
2415 i = VARRAY_TOP_UINT (ti->topo_order);
2416 VARRAY_POP (ti->topo_order);
2417 gcc_assert (get_varinfo (i)->node == i);
2419 if (TEST_BIT (changed, i))
2421 unsigned int j;
2422 constraint_t c;
2423 constraint_edge_t e;
2424 bitmap solution;
2425 VEC(constraint_t) *complicated = get_varinfo (i)->complicated;
2426 VEC(constraint_edge_t) *succs;
2427 RESET_BIT (changed, i);
2428 changed_count--;
2429 solution = get_varinfo (i)->solution;
2430 for (j = 0; VEC_iterate (constraint_t, complicated, j, c); j++)
2432 do_complex_constraint (graph, c, solution);
2434 succs = graph->succs[i];
2435 for (j = 0; VEC_iterate (constraint_edge_t, succs, j, e); j++)
2437 bitmap tmp = get_varinfo (e->dest)->solution;
2438 bool flag = false;
2439 unsigned int k;
2440 /* Process weighted edges */
2441 bitmap weights = e->weights;
2442 bitmap_iterator bi;
2444 gcc_assert (!bitmap_empty_p (weights));
2445 EXECUTE_IF_SET_IN_BITMAP (weights, 0, k, bi)
2447 flag |= set_union_with_increment (tmp, solution, k);
2449 if (flag)
2451 get_varinfo (e->dest)->solution = tmp;
2452 if (!TEST_BIT (changed, e->dest))
2454 SET_BIT (changed, e->dest);
2455 changed_count++;
2461 free_topo_info (ti);
2463 sbitmap_free (changed);
2467 /* Create points-to sets for the current function. */
2469 static void
2470 create_alias_vars (void)
2472 basic_block bb;
2473 struct constraint_expr lhs, rhs;
2475 constraint_pool = create_alloc_pool ("Constraint pool",
2476 sizeof (struct constraint), 30);
2477 variable_info_pool = create_alloc_pool ("Variable info pool",
2478 sizeof (struct variable_info), 30);
2479 constraint_edge_pool = create_alloc_pool ("Constraint edges",
2480 sizeof (struct constraint_edge), 30);
2482 constraints = VEC_alloc (constraint_t, 8);
2483 varmap = VEC_alloc (varinfo_t, 8);
2484 id_for_tree = htab_create (10, tree_id_hash, tree_id_eq, free);
2485 memset (&stats, 0, sizeof (stats));
2487 /* Create the NULL variable, used to represent that a variable points
2488 to NULL. */
2489 nothing_tree = create_tmp_var_raw (void_type_node, "NULL");
2490 var_nothing = new_var_info (nothing_tree, 0, "NULL", 0);
2491 insert_id_for_tree (nothing_tree, 0);
2492 var_nothing->is_artificial_var = 1;
2493 var_nothing->offset = 0;
2494 var_nothing->size = ~0;
2495 var_nothing->fullsize = ~0;
2496 var_nothing->base = var_nothing;
2497 nothing_id = 0;
2498 VEC_safe_push (varinfo_t, varmap, var_nothing);
2500 /* Create the ANYTHING variable, used to represent that a variable
2501 points to some unknown piece of memory. */
2502 anything_tree = create_tmp_var_raw (void_type_node, "ANYTHING");
2503 var_anything = new_var_info (anything_tree, 1, "ANYTHING", 1);
2504 insert_id_for_tree (anything_tree, 1);
2505 var_anything->is_artificial_var = 1;
2506 var_anything->size = ~0;
2507 var_anything->offset = 0;
2508 var_anything->next = NULL;
2509 var_anything->base = var_anything;
2510 var_anything->fullsize = ~0;
2512 anything_id = 1;
2513 VEC_safe_push (varinfo_t, varmap, var_anything);
2514 lhs.type = SCALAR;
2515 lhs.var = anything_id;
2516 lhs.offset = 0;
2517 rhs.type = ADDRESSOF;
2518 rhs.var = anything_id;
2519 rhs.offset = 0;
2520 var_anything->address_taken = true;
2521 VEC_safe_push (constraint_t, constraints,
2522 new_constraint (lhs, rhs));
2524 /* Create the READONLY variable, used to represent that a variable
2525 points to readonly memory. */
2526 readonly_tree = create_tmp_var_raw (void_type_node, "READONLY");
2527 var_readonly = new_var_info (readonly_tree, 2, "READONLY", 2);
2528 var_readonly->is_artificial_var = 1;
2529 var_readonly->offset = 0;
2530 var_readonly->size = ~0;
2531 var_readonly->fullsize = ~0;
2532 var_readonly->next = NULL;
2533 var_readonly->base = var_readonly;
2536 insert_id_for_tree (readonly_tree, 2);
2537 readonly_id = 2;
2538 VEC_safe_push (varinfo_t, varmap, var_readonly);
2539 lhs.type = SCALAR;
2540 lhs.var = readonly_id;
2541 lhs.offset = 0;
2542 rhs.type = ADDRESSOF;
2543 rhs.var = readonly_id;
2544 rhs.offset = 0;
2545 var_readonly->address_taken = true;
2547 VEC_safe_push (constraint_t, constraints,
2548 new_constraint (lhs, rhs));
2550 /* Create the INTEGER variable, used to represent that a variable points
2551 to an INTEGER. */
2552 integer_tree = create_tmp_var_raw (void_type_node, "INTEGER");
2553 var_integer = new_var_info (integer_tree, 3, "INTEGER", 3);
2554 insert_id_for_tree (integer_tree, 3);
2555 var_integer->is_artificial_var = 1;
2556 var_integer->size = ~0;
2557 var_integer->fullsize = ~0;
2558 var_integer->offset = 0;
2559 var_integer->next = NULL;
2560 var_integer->base = var_integer;
2561 integer_id = 3;
2562 VEC_safe_push (varinfo_t, varmap, var_integer);
2564 create_variable_infos ();
2565 /* Now walk all statements and derive aliases. */
2566 FOR_EACH_BB (bb)
2568 block_stmt_iterator bsi;
2569 tree phi;
2570 for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
2571 if (is_gimple_reg (PHI_RESULT (phi)))
2572 find_func_aliases (phi);
2573 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2574 find_func_aliases (bsi_stmt (bsi));
2577 build_constraint_graph ();
2578 if (dump_file)
2580 fprintf (dump_file, "Constraints:\n");
2581 print_constraints (dump_file);
2583 if (dump_file)
2584 fprintf (dump_file, "Collapsing static cycles and doing variable substitution:\n");
2585 find_and_collapse_graph_cycles (graph, false);
2586 perform_rountev_chandra (graph);
2587 if (dump_file)
2588 fprintf (dump_file, "Solving graph:\n");
2589 solve_graph (graph);
2590 if (dump_file)
2592 unsigned int i;
2593 if (dump_flags & TDF_STATS)
2595 fprintf (dump_file, "Stats:\n");
2596 fprintf (dump_file, "Total vars:%d\n", stats.total_vars);
2597 fprintf (dump_file, "Statically unified vars:%d\n", stats.unified_vars_static);
2598 fprintf (dump_file, "Collapsed vars:%d\n", stats.collapsed_vars);
2599 fprintf (dump_file, "Dynamically unified vars:%d\n", stats.unified_vars_dynamic);
2600 fprintf (dump_file, "Iterations:%d\n", stats.iterations);
2602 for (i = 0; i < VEC_length (varinfo_t, varmap); i++)
2603 print_solution_for_var (dump_file, i);
2610 struct tree_opt_pass pass_build_pta =
2612 "pta", /* name */
2613 NULL, /* gate */
2614 create_alias_vars, /* execute */
2615 NULL, /* sub */
2616 NULL, /* next */
2617 0, /* static_pass_number */
2618 TV_TREE_PTA, /* tv_id */
2619 PROP_cfg, /* properties_required */
2620 PROP_pta, /* properties_provided */
2621 0, /* properties_destroyed */
2622 0, /* todo_flags_start */
2623 0, /* todo_flags_finish */
2624 0 /* letter */
2628 /* Delete created points-to sets. */
2630 static void
2631 delete_alias_vars (void)
2633 htab_delete (id_for_tree);
2634 free_alloc_pool (variable_info_pool);
2635 free_alloc_pool (constraint_pool);
2636 free_alloc_pool (constraint_edge_pool);
2639 struct tree_opt_pass pass_del_pta =
2641 NULL, /* name */
2642 NULL, /* gate */
2643 delete_alias_vars, /* execute */
2644 NULL, /* sub */
2645 NULL, /* next */
2646 0, /* static_pass_number */
2647 TV_TREE_PTA, /* tv_id */
2648 PROP_pta, /* properties_required */
2649 0, /* properties_provided */
2650 PROP_pta, /* properties_destroyed */
2651 0, /* todo_flags_start */
2652 0, /* todo_flags_finish */
2653 0 /* letter */
2657 #define MASK_POINTER(P) ((unsigned)((unsigned long)(P) & 0xffff))
2659 const char *
2660 alias_get_name (tree t)
2662 const char *name;
2664 if (TREE_CODE (t) == FUNCTION_DECL)
2665 name = IDENTIFIER_POINTER (DECL_NAME (t));
2666 else if (TREE_CODE (t) == FIELD_DECL)
2668 tree context = DECL_FIELD_CONTEXT (t);
2669 tree typename = TYPE_NAME (context);
2670 const char *structname;
2671 char *result = alloca (512);
2672 char *newname;
2673 if (typename && TREE_CODE (typename) == TYPE_DECL)
2674 typename = DECL_NAME (typename);
2676 if (!typename)
2678 char *namep;
2679 /* 2 = UF
2680 4 = the masked pointer
2681 2 = the <> around it
2682 1 = the terminator. */
2683 namep = ggc_alloc (2 + 4 + 2 + 1);
2684 sprintf (namep, "<UV%x>", MASK_POINTER (t));
2685 structname = namep;
2687 else
2688 structname = IDENTIFIER_POINTER (typename);
2690 sprintf (result, "%s.%s", structname, get_name (t));
2691 newname = ggc_alloc (strlen (result) + 1);
2692 strcpy (newname, result);
2693 name = newname;
2695 else if (TREE_CODE (t) == RESULT_DECL)
2696 name = "<return value>";
2697 else if (TREE_CODE (t) == SSA_NAME)
2699 char *result = alloca (128);
2700 char *newname;
2701 sprintf (result, "%s_%d", alias_get_name (SSA_NAME_VAR (t)),
2702 SSA_NAME_VERSION (t));
2703 newname = ggc_alloc (strlen (result) + 1);
2704 strcpy (newname, result);
2705 name = newname;
2707 else if (TREE_CODE (t) == RESULT_DECL)
2708 name = "<return value>";
2709 else
2710 name = get_name (t);
2712 if (!name)
2714 char *namep;
2715 /* 2 = UF
2716 4 = the masked pointer
2717 2 = the <> around it
2718 1 = the terminator. */
2719 namep = ggc_alloc (2 + 4 + 2 + 1);
2720 sprintf (namep, "<UV%x>", MASK_POINTER (t));
2721 return namep;
2723 return name;