]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-ssa-structalias.c
* tree-ssa.h: Don't include gimple-low.h, tree-ssa-address.h, sbitmap.h,
[thirdparty/gcc.git] / gcc / tree-ssa-structalias.c
CommitLineData
29fd4364 1/* Tree based points-to analysis
711789cc 2 Copyright (C) 2005-2013 Free Software Foundation, Inc.
29fd4364 3 Contributed by Daniel Berlin <dberlin@dberlin.org>
4
8c4c00c1 5 This file is part of GCC.
29fd4364 6
8c4c00c1 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 3 of the License, or
10 (at your option) any later version.
29fd4364 11
8c4c00c1 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.
29fd4364 16
8c4c00c1 17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
29fd4364 20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "tm.h"
25#include "ggc.h"
26#include "obstack.h"
27#include "bitmap.h"
424a4a92 28#include "sbitmap.h"
29fd4364 29#include "flags.h"
29fd4364 30#include "basic-block.h"
29fd4364 31#include "tree.h"
69ee5dbb 32#include "tree-ssa.h"
29fd4364 33#include "tree-inline.h"
0b205f4c 34#include "diagnostic-core.h"
75a70cf9 35#include "gimple.h"
3e871d4d 36#include "hash-table.h"
29fd4364 37#include "function.h"
38#include "cgraph.h"
39#include "tree-pass.h"
29fd4364 40#include "alloc-pool.h"
41#include "splay-tree.h"
03c253f3 42#include "params.h"
db026f5c 43#include "cgraph.h"
7d1f52b2 44#include "alias.h"
4fb5e5ca 45#include "pointer-set.h"
29fd4364 46
47/* The idea behind this analyzer is to generate set constraints from the
48 program, then solve the resulting constraints in order to generate the
7d1f52b2 49 points-to sets.
29fd4364 50
51 Set constraints are a way of modeling program analysis problems that
52 involve sets. They consist of an inclusion constraint language,
53 describing the variables (each variable is a set) and operations that
54 are involved on the variables, and a set of rules that derive facts
55 from these operations. To solve a system of set constraints, you derive
56 all possible facts under the rules, which gives you the correct sets
57 as a consequence.
58
59 See "Efficient Field-sensitive pointer analysis for C" by "David
60 J. Pearce and Paul H. J. Kelly and Chris Hankin, at
61 http://citeseer.ist.psu.edu/pearce04efficient.html
62
63 Also see "Ultra-fast Aliasing Analysis using CLA: A Million Lines
64 of C Code in a Second" by ""Nevin Heintze and Olivier Tardieu" at
7d1f52b2 65 http://citeseer.ist.psu.edu/heintze01ultrafast.html
66
67 There are three types of real constraint expressions, DEREF,
8a3fd8a7 68 ADDRESSOF, and SCALAR. Each constraint expression consists
7d1f52b2 69 of a constraint type, a variable, and an offset.
29fd4364 70
29fd4364 71 SCALAR is a constraint expression type used to represent x, whether
72 it appears on the LHS or the RHS of a statement.
73 DEREF is a constraint expression type used to represent *x, whether
7d1f52b2 74 it appears on the LHS or the RHS of a statement.
29fd4364 75 ADDRESSOF is a constraint expression used to represent &x, whether
ce10738f 76 it appears on the LHS or the RHS of a statement.
7d1f52b2 77
29fd4364 78 Each pointer variable in the program is assigned an integer id, and
79 each field of a structure variable is assigned an integer id as well.
7d1f52b2 80
29fd4364 81 Structure variables are linked to their list of fields through a "next
82 field" in each variable that points to the next field in offset
7d1f52b2 83 order.
84 Each variable for a structure field has
29fd4364 85
86 1. "size", that tells the size in bits of that field.
87 2. "fullsize, that tells the size in bits of the entire structure.
88 3. "offset", that tells the offset in bits from the beginning of the
89 structure to this field.
90
7d1f52b2 91 Thus,
29fd4364 92 struct f
93 {
94 int a;
95 int b;
96 } foo;
97 int *bar;
98
99 looks like
100
101 foo.a -> id 1, size 32, offset 0, fullsize 64, next foo.b
102 foo.b -> id 2, size 32, offset 32, fullsize 64, next NULL
103 bar -> id 3, size 32, offset 0, fullsize 32, next NULL
104
7d1f52b2 105
29fd4364 106 In order to solve the system of set constraints, the following is
107 done:
108
109 1. Each constraint variable x has a solution set associated with it,
110 Sol(x).
7d1f52b2 111
29fd4364 112 2. Constraints are separated into direct, copy, and complex.
113 Direct constraints are ADDRESSOF constraints that require no extra
114 processing, such as P = &Q
115 Copy constraints are those of the form P = Q.
44a2bb4a 116 Complex constraints are all the constraints involving dereferences
117 and offsets (including offsetted copies).
7d1f52b2 118
29fd4364 119 3. All direct constraints of the form P = &Q are processed, such
7d1f52b2 120 that Q is added to Sol(P)
29fd4364 121
122 4. All complex constraints for a given constraint variable are stored in a
7d1f52b2 123 linked list attached to that variable's node.
29fd4364 124
125 5. A directed graph is built out of the copy constraints. Each
7d1f52b2 126 constraint variable is a node in the graph, and an edge from
29fd4364 127 Q to P is added for each copy constraint of the form P = Q
7d1f52b2 128
29fd4364 129 6. The graph is then walked, and solution sets are
130 propagated along the copy edges, such that an edge from Q to P
131 causes Sol(P) <- Sol(P) union Sol(Q).
7d1f52b2 132
29fd4364 133 7. As we visit each node, all complex constraints associated with
ce10738f 134 that node are processed by adding appropriate copy edges to the graph, or the
7d1f52b2 135 appropriate variables to the solution set.
29fd4364 136
137 8. The process of walking the graph is iterated until no solution
138 sets change.
139
140 Prior to walking the graph in steps 6 and 7, We perform static
7d1f52b2 141 cycle elimination on the constraint graph, as well
29fd4364 142 as off-line variable substitution.
7d1f52b2 143
29fd4364 144 TODO: Adding offsets to pointer-to-structures can be handled (IE not punted
145 on and turned into anything), but isn't. You can just see what offset
146 inside the pointed-to struct it's going to access.
7d1f52b2 147
29fd4364 148 TODO: Constant bounded arrays can be handled as if they were structs of the
7d1f52b2 149 same number of elements.
29fd4364 150
151 TODO: Modeling heap and incoming pointers becomes much better if we
152 add fields to them as we discover them, which we could do.
153
154 TODO: We could handle unions, but to be honest, it's probably not
155 worth the pain or slowdown. */
156
1a981e1a 157/* IPA-PTA optimizations possible.
158
159 When the indirect function called is ANYTHING we can add disambiguation
160 based on the function signatures (or simply the parameter count which
161 is the varinfo size). We also do not need to consider functions that
162 do not have their address taken.
163
164 The is_global_var bit which marks escape points is overly conservative
165 in IPA mode. Split it to is_escape_point and is_global_var - only
166 externally visible globals are escape points in IPA mode. This is
167 also needed to fix the pt_solution_includes_global predicate
168 (and thus ptr_deref_may_alias_global_p).
169
170 The way we introduce DECL_PT_UID to avoid fixing up all points-to
171 sets in the translation unit when we copy a DECL during inlining
172 pessimizes precision. The advantage is that the DECL_PT_UID keeps
173 compile-time and memory usage overhead low - the points-to sets
174 do not grow or get unshared as they would during a fixup phase.
175 An alternative solution is to delay IPA PTA until after all
176 inlining transformations have been applied.
177
178 The way we propagate clobber/use information isn't optimized.
179 It should use a new complex constraint that properly filters
180 out local variables of the callee (though that would make
181 the sets invalid after inlining). OTOH we might as well
182 admit defeat to WHOPR and simply do all the clobber/use analysis
183 and propagation after PTA finished but before we threw away
184 points-to information for memory variables. WHOPR and PTA
185 do not play along well anyway - the whole constraint solving
186 would need to be done in WPA phase and it will be very interesting
187 to apply the results to local SSA names during LTRANS phase.
188
189 We probably should compute a per-function unit-ESCAPE solution
190 propagating it simply like the clobber / uses solutions. The
191 solution can go alongside the non-IPA espaced solution and be
192 used to query which vars escape the unit through a function.
193
194 We never put function decls in points-to sets so we do not
195 keep the set of called functions for indirect calls.
196
197 And probably more. */
499be8ef 198
29fd4364 199static bool use_field_sensitive = true;
db026f5c 200static int in_ipa_mode = 0;
8a3fd8a7 201
202/* Used for predecessor bitmaps. */
db026f5c 203static bitmap_obstack predbitmap_obstack;
8a3fd8a7 204
205/* Used for points-to sets. */
206static bitmap_obstack pta_obstack;
207
208/* Used for oldsolution members of variables. */
209static bitmap_obstack oldpta_obstack;
210
211/* Used for per-solver-iteration bitmaps. */
db026f5c 212static bitmap_obstack iteration_obstack;
213
29fd4364 214static unsigned int create_variable_info_for (tree, const char *);
8a3fd8a7 215typedef struct constraint_graph *constraint_graph_t;
216static void unify_nodes (constraint_graph_t, unsigned int, unsigned int, bool);
29fd4364 217
dd277d48 218struct constraint;
219typedef struct constraint *constraint_t;
220
29fd4364 221
db026f5c 222#define EXECUTE_IF_IN_NONNULL_BITMAP(a, b, c, d) \
223 if (a) \
224 EXECUTE_IF_SET_IN_BITMAP (a, b, c, d)
225
29fd4364 226static struct constraint_stats
227{
228 unsigned int total_vars;
8a3fd8a7 229 unsigned int nonpointer_vars;
29fd4364 230 unsigned int unified_vars_static;
231 unsigned int unified_vars_dynamic;
232 unsigned int iterations;
db026f5c 233 unsigned int num_edges;
8a3fd8a7 234 unsigned int num_implicit_edges;
235 unsigned int points_to_sets_created;
29fd4364 236} stats;
237
238struct variable_info
239{
240 /* ID of this variable */
241 unsigned int id;
242
29fd4364 243 /* True if this is a variable created by the constraint analysis, such as
244 heap variables and constraints we had to break up. */
1c1f1bc0 245 unsigned int is_artificial_var : 1;
7d1f52b2 246
300b54b8 247 /* True if this is a special variable whose solution set should not be
248 changed. */
1c1f1bc0 249 unsigned int is_special_var : 1;
29fd4364 250
251 /* True for variables whose size is not known or variable. */
1c1f1bc0 252 unsigned int is_unknown_size_var : 1;
29fd4364 253
57e6b870 254 /* True for (sub-)fields that represent a whole variable. */
255 unsigned int is_full_var : 1;
256
260e7e11 257 /* True if this is a heap variable. */
1c1f1bc0 258 unsigned int is_heap_var : 1;
259
c5168a9e 260 /* True if this field may contain pointers. */
261 unsigned int may_have_pointers : 1;
262
d812977b 263 /* True if this field has only restrict qualified pointers. */
264 unsigned int only_restrict_pointers : 1;
265
97709d23 266 /* True if this represents a global variable. */
267 unsigned int is_global_var : 1;
268
1a981e1a 269 /* True if this represents a IPA function info. */
270 unsigned int is_fn_info : 1;
271
5a950977 272 /* The ID of the variable for the next field in this structure
273 or zero for the last field in this structure. */
274 unsigned next;
275
276 /* The ID of the variable for the first field in this structure. */
277 unsigned head;
7b879cb3 278
279 /* Offset of this variable, in bits, from the base variable */
280 unsigned HOST_WIDE_INT offset;
281
282 /* Size of the variable, in bits. */
283 unsigned HOST_WIDE_INT size;
284
285 /* Full size of the base variable, in bits. */
286 unsigned HOST_WIDE_INT fullsize;
287
288 /* Name of this variable */
289 const char *name;
290
291 /* Tree that this variable is associated with. */
292 tree decl;
293
29fd4364 294 /* Points-to set for this variable. */
295 bitmap solution;
296
8a3fd8a7 297 /* Old points-to set for this variable. */
298 bitmap oldsolution;
29fd4364 299};
300typedef struct variable_info *varinfo_t;
301
302static varinfo_t first_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT);
dd277d48 303static varinfo_t first_or_preceding_vi_for_offset (varinfo_t,
304 unsigned HOST_WIDE_INT);
fc733d7a 305static varinfo_t lookup_vi_for_tree (tree);
b4c39a37 306static inline bool type_can_have_subvars (const_tree);
29fd4364 307
308/* Pool of variable info structures. */
309static alloc_pool variable_info_pool;
310
dd6f8b2c 311/* Map varinfo to final pt_solution. */
312static pointer_map_t *final_solutions;
313struct obstack final_solutions_obstack;
29fd4364 314
4fb5e5ca 315/* Table of variable info structures for constraint variables.
316 Indexed directly by variable info id. */
f1f41a6c 317static vec<varinfo_t> varmap;
300b54b8 318
319/* Return the varmap element N */
320
321static inline varinfo_t
5472b425 322get_varinfo (unsigned int n)
300b54b8 323{
f1f41a6c 324 return varmap[n];
300b54b8 325}
29fd4364 326
5a950977 327/* Return the next variable in the list of sub-variables of VI
328 or NULL if VI is the last sub-variable. */
329
330static inline varinfo_t
331vi_next (varinfo_t vi)
332{
333 return get_varinfo (vi->next);
334}
335
336/* Static IDs for the special variables. Variable ID zero is unused
337 and used as terminator for the sub-variable chain. */
338enum { nothing_id = 1, anything_id = 2, readonly_id = 3,
339 escaped_id = 4, nonlocal_id = 5,
340 storedanything_id = 6, integer_id = 7 };
0b3bf4d6 341
29fd4364 342/* Return a new variable info structure consisting for a variable
97709d23 343 named NAME, and using constraint graph node NODE. Append it
344 to the vector of variable info structures. */
29fd4364 345
346static varinfo_t
97709d23 347new_var_info (tree t, const char *name)
29fd4364 348{
f1f41a6c 349 unsigned index = varmap.length ();
f0d6e81c 350 varinfo_t ret = (varinfo_t) pool_alloc (variable_info_pool);
29fd4364 351
97709d23 352 ret->id = index;
29fd4364 353 ret->name = name;
354 ret->decl = t;
97709d23 355 /* Vars without decl are artificial and do not have sub-variables. */
356 ret->is_artificial_var = (t == NULL_TREE);
300b54b8 357 ret->is_special_var = false;
29fd4364 358 ret->is_unknown_size_var = false;
86fd2723 359 ret->is_full_var = (t == NULL_TREE);
360 ret->is_heap_var = false;
c5168a9e 361 ret->may_have_pointers = true;
d812977b 362 ret->only_restrict_pointers = false;
1c1f1bc0 363 ret->is_global_var = (t == NULL_TREE);
1a981e1a 364 ret->is_fn_info = false;
97709d23 365 if (t && DECL_P (t))
72210aa1 366 ret->is_global_var = (is_global_var (t)
367 /* We have to treat even local register variables
368 as escape points. */
8de57388 369 || (TREE_CODE (t) == VAR_DECL
370 && DECL_HARD_REGISTER (t)));
8a3fd8a7 371 ret->solution = BITMAP_ALLOC (&pta_obstack);
8b3ad377 372 ret->oldsolution = NULL;
5a950977 373 ret->next = 0;
374 ret->head = ret->id;
97709d23 375
d812977b 376 stats.total_vars++;
377
f1f41a6c 378 varmap.safe_push (ret);
97709d23 379
29fd4364 380 return ret;
381}
382
c4ec6aca 383
384/* A map mapping call statements to per-stmt variables for uses
385 and clobbers specific to the call. */
94771494 386static struct pointer_map_t *call_stmt_vars;
c4ec6aca 387
388/* Lookup or create the variable for the call statement CALL. */
389
390static varinfo_t
391get_call_vi (gimple call)
392{
393 void **slot_p;
394 varinfo_t vi, vi2;
395
396 slot_p = pointer_map_insert (call_stmt_vars, call);
397 if (*slot_p)
398 return (varinfo_t) *slot_p;
399
400 vi = new_var_info (NULL_TREE, "CALLUSED");
401 vi->offset = 0;
402 vi->size = 1;
403 vi->fullsize = 2;
404 vi->is_full_var = true;
405
5a950977 406 vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED");
c4ec6aca 407 vi2->offset = 1;
408 vi2->size = 1;
409 vi2->fullsize = 2;
410 vi2->is_full_var = true;
411
5a950977 412 vi->next = vi2->id;
413
c4ec6aca 414 *slot_p = (void *) vi;
415 return vi;
416}
417
418/* Lookup the variable for the call statement CALL representing
419 the uses. Returns NULL if there is nothing special about this call. */
420
421static varinfo_t
422lookup_call_use_vi (gimple call)
423{
424 void **slot_p;
425
426 slot_p = pointer_map_contains (call_stmt_vars, call);
427 if (slot_p)
428 return (varinfo_t) *slot_p;
429
430 return NULL;
431}
432
433/* Lookup the variable for the call statement CALL representing
434 the clobbers. Returns NULL if there is nothing special about this call. */
435
436static varinfo_t
437lookup_call_clobber_vi (gimple call)
438{
439 varinfo_t uses = lookup_call_use_vi (call);
440 if (!uses)
441 return NULL;
442
5a950977 443 return vi_next (uses);
c4ec6aca 444}
445
446/* Lookup or create the variable for the call statement CALL representing
447 the uses. */
448
449static varinfo_t
450get_call_use_vi (gimple call)
451{
452 return get_call_vi (call);
453}
454
455/* Lookup or create the variable for the call statement CALL representing
456 the clobbers. */
457
458static varinfo_t ATTRIBUTE_UNUSED
459get_call_clobber_vi (gimple call)
460{
5a950977 461 return vi_next (get_call_vi (call));
c4ec6aca 462}
463
464
8a3fd8a7 465typedef enum {SCALAR, DEREF, ADDRESSOF} constraint_expr_type;
29fd4364 466
467/* An expression that appears in a constraint. */
468
7d1f52b2 469struct constraint_expr
29fd4364 470{
471 /* Constraint type. */
472 constraint_expr_type type;
473
474 /* Variable we are referring to in the constraint. */
475 unsigned int var;
476
477 /* Offset, in bits, of this constraint from the beginning of
478 variables it ends up referring to.
479
480 IOW, in a deref constraint, we would deref, get the result set,
481 then add OFFSET to each member. */
dd277d48 482 HOST_WIDE_INT offset;
29fd4364 483};
484
dd277d48 485/* Use 0x8000... as special unknown offset. */
561f0ec8 486#define UNKNOWN_OFFSET HOST_WIDE_INT_MIN
dd277d48 487
db026f5c 488typedef struct constraint_expr ce_s;
f1f41a6c 489static void get_constraint_for_1 (tree, vec<ce_s> *, bool, bool);
490static void get_constraint_for (tree, vec<ce_s> *);
491static void get_constraint_for_rhs (tree, vec<ce_s> *);
492static void do_deref (vec<ce_s> *);
29fd4364 493
494/* Our set constraints are made up of two constraint expressions, one
7d1f52b2 495 LHS, and one RHS.
29fd4364 496
497 As described in the introduction, our set constraints each represent an
498 operation between set valued variables.
499*/
500struct constraint
501{
502 struct constraint_expr lhs;
503 struct constraint_expr rhs;
504};
505
506/* List of constraints that we use to build the constraint graph from. */
507
f1f41a6c 508static vec<constraint_t> constraints;
29fd4364 509static alloc_pool constraint_pool;
510
eb68f239 511/* The constraint graph is represented as an array of bitmaps
512 containing successor nodes. */
29fd4364 513
514struct constraint_graph
515{
8a3fd8a7 516 /* Size of this graph, which may be different than the number of
517 nodes in the variable map. */
518 unsigned int size;
519
520 /* Explicit successors of each node. */
eb68f239 521 bitmap *succs;
8a3fd8a7 522
523 /* Implicit predecessors of each node (Used for variable
524 substitution). */
525 bitmap *implicit_preds;
526
527 /* Explicit predecessors of each node (Used for variable substitution). */
eb68f239 528 bitmap *preds;
29fd4364 529
8a3fd8a7 530 /* Indirect cycle representatives, or -1 if the node has no indirect
531 cycles. */
532 int *indirect_cycles;
533
534 /* Representative node for a node. rep[a] == a unless the node has
535 been unified. */
536 unsigned int *rep;
537
a6db8f14 538 /* Equivalence class representative for a label. This is used for
8a3fd8a7 539 variable substitution. */
540 int *eq_rep;
541
765b6c4f 542 /* Pointer equivalence label for a node. All nodes with the same
543 pointer equivalence label can be unified together at some point
544 (either during constraint optimization or after the constraint
545 graph is built). */
a6db8f14 546 unsigned int *pe;
547
548 /* Pointer equivalence representative for a label. This is used to
549 handle nodes that are pointer equivalent but not location
550 equivalent. We can unite these once the addressof constraints
551 are transformed into initial points-to sets. */
552 int *pe_rep;
553
554 /* Pointer equivalence label for each node, used during variable
555 substitution. */
556 unsigned int *pointer_label;
557
558 /* Location equivalence label for each node, used during location
559 equivalence finding. */
560 unsigned int *loc_label;
561
562 /* Pointed-by set for each node, used during location equivalence
563 finding. This is pointed-by rather than pointed-to, because it
564 is constructed using the predecessor graph. */
565 bitmap *pointed_by;
566
567 /* Points to sets for pointer equivalence. This is *not* the actual
568 points-to sets for nodes. */
569 bitmap *points_to;
8a3fd8a7 570
571 /* Bitmap of nodes where the bit is set if the node is a direct
572 node. Used for variable substitution. */
573 sbitmap direct_nodes;
574
a6db8f14 575 /* Bitmap of nodes where the bit is set if the node is address
576 taken. Used for variable substitution. */
577 bitmap address_taken;
578
8a3fd8a7 579 /* Vector of complex constraints for each graph node. Complex
580 constraints are those involving dereferences or offsets that are
581 not 0. */
f1f41a6c 582 vec<constraint_t> *complex;
8a3fd8a7 583};
29fd4364 584
585static constraint_graph_t graph;
586
8a3fd8a7 587/* During variable substitution and the offline version of indirect
588 cycle finding, we create nodes to represent dereferences and
589 address taken constraints. These represent where these start and
590 end. */
f1f41a6c 591#define FIRST_REF_NODE (varmap).length ()
8a3fd8a7 592#define LAST_REF_NODE (FIRST_REF_NODE + (FIRST_REF_NODE - 1))
8a3fd8a7 593
594/* Return the representative node for NODE, if NODE has been unioned
595 with another NODE.
596 This function performs path compression along the way to finding
597 the representative. */
598
599static unsigned int
600find (unsigned int node)
601{
6a5ca1fc 602 gcc_checking_assert (node < graph->size);
8a3fd8a7 603 if (graph->rep[node] != node)
604 return graph->rep[node] = find (graph->rep[node]);
605 return node;
606}
607
608/* Union the TO and FROM nodes to the TO nodes.
609 Note that at some point in the future, we may want to do
610 union-by-rank, in which case we are going to have to return the
611 node we unified to. */
612
613static bool
614unite (unsigned int to, unsigned int from)
615{
6a5ca1fc 616 gcc_checking_assert (to < graph->size && from < graph->size);
8a3fd8a7 617 if (to != from && graph->rep[from] != to)
618 {
619 graph->rep[from] = to;
620 return true;
621 }
622 return false;
623}
624
29fd4364 625/* Create a new constraint consisting of LHS and RHS expressions. */
626
7d1f52b2 627static constraint_t
29fd4364 628new_constraint (const struct constraint_expr lhs,
629 const struct constraint_expr rhs)
630{
f0d6e81c 631 constraint_t ret = (constraint_t) pool_alloc (constraint_pool);
29fd4364 632 ret->lhs = lhs;
633 ret->rhs = rhs;
634 return ret;
635}
636
637/* Print out constraint C to FILE. */
638
dd277d48 639static void
29fd4364 640dump_constraint (FILE *file, constraint_t c)
641{
642 if (c->lhs.type == ADDRESSOF)
643 fprintf (file, "&");
644 else if (c->lhs.type == DEREF)
7d1f52b2 645 fprintf (file, "*");
dd277d48 646 fprintf (file, "%s", get_varinfo (c->lhs.var)->name);
647 if (c->lhs.offset == UNKNOWN_OFFSET)
648 fprintf (file, " + UNKNOWN");
649 else if (c->lhs.offset != 0)
29fd4364 650 fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->lhs.offset);
651 fprintf (file, " = ");
652 if (c->rhs.type == ADDRESSOF)
653 fprintf (file, "&");
654 else if (c->rhs.type == DEREF)
655 fprintf (file, "*");
dd277d48 656 fprintf (file, "%s", get_varinfo (c->rhs.var)->name);
657 if (c->rhs.offset == UNKNOWN_OFFSET)
658 fprintf (file, " + UNKNOWN");
659 else if (c->rhs.offset != 0)
29fd4364 660 fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->rhs.offset);
29fd4364 661}
662
dd277d48 663
664void debug_constraint (constraint_t);
665void debug_constraints (void);
666void debug_constraint_graph (void);
667void debug_solution_for_var (unsigned int);
668void debug_sa_points_to_info (void);
669
29fd4364 670/* Print out constraint C to stderr. */
671
4b987fac 672DEBUG_FUNCTION void
29fd4364 673debug_constraint (constraint_t c)
674{
675 dump_constraint (stderr, c);
bbe0034f 676 fprintf (stderr, "\n");
29fd4364 677}
678
679/* Print out all constraints to FILE */
680
dd277d48 681static void
1a981e1a 682dump_constraints (FILE *file, int from)
29fd4364 683{
684 int i;
685 constraint_t c;
f1f41a6c 686 for (i = from; constraints.iterate (i, &c); i++)
bbe0034f 687 if (c)
688 {
689 dump_constraint (file, c);
690 fprintf (file, "\n");
691 }
29fd4364 692}
693
694/* Print out all constraints to stderr. */
695
4b987fac 696DEBUG_FUNCTION void
29fd4364 697debug_constraints (void)
698{
1a981e1a 699 dump_constraints (stderr, 0);
29fd4364 700}
701
48926532 702/* Print the constraint graph in dot format. */
703
dd277d48 704static void
48926532 705dump_constraint_graph (FILE *file)
706{
bbe0034f 707 unsigned int i;
48926532 708
709 /* Only print the graph if it has already been initialized: */
710 if (!graph)
711 return;
712
48926532 713 /* Prints the header of the dot file: */
48926532 714 fprintf (file, "strict digraph {\n");
715 fprintf (file, " node [\n shape = box\n ]\n");
716 fprintf (file, " edge [\n fontsize = \"12\"\n ]\n");
bbe0034f 717 fprintf (file, "\n // List of nodes and complex constraints in "
718 "the constraint graph:\n");
719
720 /* The next lines print the nodes in the graph together with the
721 complex constraints attached to them. */
5a950977 722 for (i = 1; i < graph->size; i++)
48926532 723 {
5a950977 724 if (i == FIRST_REF_NODE)
725 continue;
bbe0034f 726 if (find (i) != i)
727 continue;
728 if (i < FIRST_REF_NODE)
729 fprintf (file, "\"%s\"", get_varinfo (i)->name);
730 else
731 fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
f1f41a6c 732 if (graph->complex[i].exists ())
bbe0034f 733 {
734 unsigned j;
735 constraint_t c;
736 fprintf (file, " [label=\"\\N\\n");
f1f41a6c 737 for (j = 0; graph->complex[i].iterate (j, &c); ++j)
bbe0034f 738 {
739 dump_constraint (file, c);
740 fprintf (file, "\\l");
741 }
742 fprintf (file, "\"]");
743 }
744 fprintf (file, ";\n");
48926532 745 }
746
bbe0034f 747 /* Go over the edges. */
748 fprintf (file, "\n // Edges in the constraint graph:\n");
5a950977 749 for (i = 1; i < graph->size; i++)
bbe0034f 750 {
751 unsigned j;
752 bitmap_iterator bi;
753 if (find (i) != i)
754 continue;
755 EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i], 0, j, bi)
756 {
757 unsigned to = find (j);
758 if (i == to)
759 continue;
760 if (i < FIRST_REF_NODE)
761 fprintf (file, "\"%s\"", get_varinfo (i)->name);
762 else
763 fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
764 fprintf (file, " -> ");
765 if (to < FIRST_REF_NODE)
766 fprintf (file, "\"%s\"", get_varinfo (to)->name);
767 else
768 fprintf (file, "\"*%s\"", get_varinfo (to - FIRST_REF_NODE)->name);
769 fprintf (file, ";\n");
770 }
771 }
48926532 772
bbe0034f 773 /* Prints the tail of the dot file. */
774 fprintf (file, "}\n");
48926532 775}
776
777/* Print out the constraint graph to stderr. */
778
4b987fac 779DEBUG_FUNCTION void
48926532 780debug_constraint_graph (void)
781{
782 dump_constraint_graph (stderr);
783}
784
7d1f52b2 785/* SOLVER FUNCTIONS
29fd4364 786
787 The solver is a simple worklist solver, that works on the following
788 algorithm:
7d1f52b2 789
8a3fd8a7 790 sbitmap changed_nodes = all zeroes;
791 changed_count = 0;
792 For each node that is not already collapsed:
793 changed_count++;
794 set bit in changed nodes
29fd4364 795
29fd4364 796 while (changed_count > 0)
797 {
798 compute topological ordering for constraint graph
7d1f52b2 799
29fd4364 800 find and collapse cycles in the constraint graph (updating
801 changed if necessary)
7d1f52b2 802
29fd4364 803 for each node (n) in the graph in topological order:
804 changed_count--;
805
806 Process each complex constraint associated with the node,
807 updating changed if necessary.
808
809 For each outgoing edge from n, propagate the solution from n to
810 the destination of the edge, updating changed as necessary.
811
812 } */
813
814/* Return true if two constraint expressions A and B are equal. */
815
816static bool
817constraint_expr_equal (struct constraint_expr a, struct constraint_expr b)
818{
db026f5c 819 return a.type == b.type && a.var == b.var && a.offset == b.offset;
29fd4364 820}
821
822/* Return true if constraint expression A is less than constraint expression
823 B. This is just arbitrary, but consistent, in order to give them an
824 ordering. */
825
826static bool
827constraint_expr_less (struct constraint_expr a, struct constraint_expr b)
828{
829 if (a.type == b.type)
830 {
831 if (a.var == b.var)
832 return a.offset < b.offset;
833 else
834 return a.var < b.var;
835 }
836 else
837 return a.type < b.type;
838}
839
840/* Return true if constraint A is less than constraint B. This is just
841 arbitrary, but consistent, in order to give them an ordering. */
842
843static bool
e82e4eb5 844constraint_less (const constraint_t &a, const constraint_t &b)
29fd4364 845{
846 if (constraint_expr_less (a->lhs, b->lhs))
847 return true;
848 else if (constraint_expr_less (b->lhs, a->lhs))
849 return false;
850 else
851 return constraint_expr_less (a->rhs, b->rhs);
852}
853
854/* Return true if two constraints A and B are equal. */
7d1f52b2 855
29fd4364 856static bool
857constraint_equal (struct constraint a, struct constraint b)
858{
7d1f52b2 859 return constraint_expr_equal (a.lhs, b.lhs)
29fd4364 860 && constraint_expr_equal (a.rhs, b.rhs);
861}
862
863
864/* Find a constraint LOOKFOR in the sorted constraint vector VEC */
865
866static constraint_t
f1f41a6c 867constraint_vec_find (vec<constraint_t> vec,
29fd4364 868 struct constraint lookfor)
869{
7d1f52b2 870 unsigned int place;
29fd4364 871 constraint_t found;
872
f1f41a6c 873 if (!vec.exists ())
29fd4364 874 return NULL;
875
f1f41a6c 876 place = vec.lower_bound (&lookfor, constraint_less);
877 if (place >= vec.length ())
29fd4364 878 return NULL;
f1f41a6c 879 found = vec[place];
29fd4364 880 if (!constraint_equal (*found, lookfor))
881 return NULL;
882 return found;
883}
884
885/* Union two constraint vectors, TO and FROM. Put the result in TO. */
886
887static void
f1f41a6c 888constraint_set_union (vec<constraint_t> *to,
889 vec<constraint_t> *from)
29fd4364 890{
891 int i;
892 constraint_t c;
893
f1f41a6c 894 FOR_EACH_VEC_ELT (*from, i, c)
29fd4364 895 {
896 if (constraint_vec_find (*to, *c) == NULL)
897 {
f1f41a6c 898 unsigned int place = to->lower_bound (c, constraint_less);
899 to->safe_insert (place, c);
29fd4364 900 }
901 }
902}
903
5a950977 904/* Expands the solution in SET to all sub-fields of variables included. */
dd277d48 905
906static void
5a950977 907solution_set_expand (bitmap set)
dd277d48 908{
909 bitmap_iterator bi;
dd277d48 910 unsigned j;
911
5a950977 912 /* In a first pass expand to the head of the variables we need to
913 add all sub-fields off. This avoids quadratic behavior. */
dd277d48 914 EXECUTE_IF_SET_IN_BITMAP (set, 0, j, bi)
915 {
916 varinfo_t v = get_varinfo (j);
917 if (v->is_artificial_var
918 || v->is_full_var)
919 continue;
5a950977 920 bitmap_set_bit (set, v->head);
dd277d48 921 }
922
5a950977 923 /* In the second pass now expand all head variables with subfields. */
924 EXECUTE_IF_SET_IN_BITMAP (set, 0, j, bi)
dd277d48 925 {
5a950977 926 varinfo_t v = get_varinfo (j);
927 if (v->is_artificial_var
928 || v->is_full_var
929 || v->head != j)
930 continue;
931 for (v = vi_next (v); v != NULL; v = vi_next (v))
932 bitmap_set_bit (set, v->id);
dd277d48 933 }
934}
935
5a950977 936/* Union solution sets TO and FROM, and add INC to each member of FROM in the
937 process. */
29fd4364 938
5a950977 939static bool
940set_union_with_increment (bitmap to, bitmap from, HOST_WIDE_INT inc)
29fd4364 941{
5a950977 942 bool changed = false;
29fd4364 943 bitmap_iterator bi;
5a950977 944 unsigned int i;
945
946 /* If the solution of FROM contains anything it is good enough to transfer
947 this to TO. */
948 if (bitmap_bit_p (from, anything_id))
949 return bitmap_set_bit (to, anything_id);
950
951 /* For zero offset simply union the solution into the destination. */
952 if (inc == 0)
953 return bitmap_ior_into (to, from);
29fd4364 954
dd277d48 955 /* If the offset is unknown we have to expand the solution to
956 all subfields. */
5a950977 957 if (inc == UNKNOWN_OFFSET)
dd277d48 958 {
5a950977 959 bitmap tmp = BITMAP_ALLOC (&iteration_obstack);
960 bitmap_copy (tmp, from);
961 solution_set_expand (tmp);
962 changed |= bitmap_ior_into (to, tmp);
963 BITMAP_FREE (tmp);
964 return changed;
dd277d48 965 }
966
5a950977 967 /* For non-zero offset union the offsetted solution into the destination. */
968 EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
29fd4364 969 {
57e6b870 970 varinfo_t vi = get_varinfo (i);
7d1f52b2 971
57e6b870 972 /* If this is a variable with just one field just set its bit
973 in the result. */
974 if (vi->is_artificial_var
975 || vi->is_unknown_size_var
976 || vi->is_full_var)
5a950977 977 changed |= bitmap_set_bit (to, i);
57e6b870 978 else
29fd4364 979 {
5a950977 980 unsigned HOST_WIDE_INT fieldoffset = vi->offset + inc;
dd277d48 981
982 /* If the offset makes the pointer point to before the
983 variable use offset zero for the field lookup. */
5a950977 984 if (inc < 0
dd277d48 985 && fieldoffset > vi->offset)
986 fieldoffset = 0;
987
5a950977 988 vi = first_or_preceding_vi_for_offset (vi, fieldoffset);
dd277d48 989
5a950977 990 changed |= bitmap_set_bit (to, vi->id);
57e6b870 991 /* If the result is not exactly at fieldoffset include the next
992 field as well. See get_constraint_for_ptr_offset for more
993 rationale. */
dd277d48 994 if (vi->offset != fieldoffset
5a950977 995 && vi->next != 0)
996 changed |= bitmap_set_bit (to, vi->next);
29fd4364 997 }
998 }
7d1f52b2 999
5a950977 1000 return changed;
29fd4364 1001}
1002
8a3fd8a7 1003/* Insert constraint C into the list of complex constraints for graph
1004 node VAR. */
29fd4364 1005
1006static void
8a3fd8a7 1007insert_into_complex (constraint_graph_t graph,
1008 unsigned int var, constraint_t c)
29fd4364 1009{
f1f41a6c 1010 vec<constraint_t> complex = graph->complex[var];
1011 unsigned int place = complex.lower_bound (c, constraint_less);
8a3fd8a7 1012
1013 /* Only insert constraints that do not already exist. */
f1f41a6c 1014 if (place >= complex.length ()
1015 || !constraint_equal (*c, *complex[place]))
1016 graph->complex[var].safe_insert (place, c);
29fd4364 1017}
1018
1019
29fd4364 1020/* Condense two variable nodes into a single variable node, by moving
1021 all associated info from SRC to TO. */
1022
7d1f52b2 1023static void
8a3fd8a7 1024merge_node_constraints (constraint_graph_t graph, unsigned int to,
1025 unsigned int from)
29fd4364 1026{
29fd4364 1027 unsigned int i;
1028 constraint_t c;
7d1f52b2 1029
6a5ca1fc 1030 gcc_checking_assert (find (from) == to);
7d1f52b2 1031
29fd4364 1032 /* Move all complex constraints from src node into to node */
f1f41a6c 1033 FOR_EACH_VEC_ELT (graph->complex[from], i, c)
29fd4364 1034 {
1035 /* In complex constraints for node src, we may have either
8a3fd8a7 1036 a = *src, and *src = a, or an offseted constraint which are
1037 always added to the rhs node's constraints. */
7d1f52b2 1038
29fd4364 1039 if (c->rhs.type == DEREF)
1040 c->rhs.var = to;
8a3fd8a7 1041 else if (c->lhs.type == DEREF)
29fd4364 1042 c->lhs.var = to;
8a3fd8a7 1043 else
1044 c->rhs.var = to;
29fd4364 1045 }
8a3fd8a7 1046 constraint_set_union (&graph->complex[to], &graph->complex[from]);
f1f41a6c 1047 graph->complex[from].release ();
29fd4364 1048}
1049
29fd4364 1050
1051/* Remove edges involving NODE from GRAPH. */
1052
1053static void
1054clear_edges_for_node (constraint_graph_t graph, unsigned int node)
1055{
eb68f239 1056 if (graph->succs[node])
8a3fd8a7 1057 BITMAP_FREE (graph->succs[node]);
6395bf5b 1058}
1059
29fd4364 1060/* Merge GRAPH nodes FROM and TO into node TO. */
1061
1062static void
7d1f52b2 1063merge_graph_nodes (constraint_graph_t graph, unsigned int to,
29fd4364 1064 unsigned int from)
1065{
8a3fd8a7 1066 if (graph->indirect_cycles[from] != -1)
db026f5c 1067 {
8a3fd8a7 1068 /* If we have indirect cycles with the from node, and we have
1069 none on the to node, the to node has indirect cycles from the
1070 from node now that they are unified.
1071 If indirect cycles exist on both, unify the nodes that they
1072 are in a cycle with, since we know they are in a cycle with
1073 each other. */
1074 if (graph->indirect_cycles[to] == -1)
a6db8f14 1075 graph->indirect_cycles[to] = graph->indirect_cycles[from];
db026f5c 1076 }
29fd4364 1077
eb68f239 1078 /* Merge all the successor edges. */
1079 if (graph->succs[from])
db026f5c 1080 {
eb68f239 1081 if (!graph->succs[to])
8a3fd8a7 1082 graph->succs[to] = BITMAP_ALLOC (&pta_obstack);
7d1f52b2 1083 bitmap_ior_into (graph->succs[to],
eb68f239 1084 graph->succs[from]);
db026f5c 1085 }
db026f5c 1086
29fd4364 1087 clear_edges_for_node (graph, from);
1088}
1089
8a3fd8a7 1090
1091/* Add an indirect graph edge to GRAPH, going from TO to FROM if
1092 it doesn't exist in the graph already. */
1093
1094static void
1095add_implicit_graph_edge (constraint_graph_t graph, unsigned int to,
1096 unsigned int from)
1097{
1098 if (to == from)
1099 return;
1100
1101 if (!graph->implicit_preds[to])
1102 graph->implicit_preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
1103
b64035d2 1104 if (bitmap_set_bit (graph->implicit_preds[to], from))
1105 stats.num_implicit_edges++;
8a3fd8a7 1106}
1107
1108/* Add a predecessor graph edge to GRAPH, going from TO to FROM if
1109 it doesn't exist in the graph already.
1110 Return false if the edge already existed, true otherwise. */
1111
1112static void
1113add_pred_graph_edge (constraint_graph_t graph, unsigned int to,
1114 unsigned int from)
1115{
1116 if (!graph->preds[to])
1117 graph->preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
b64035d2 1118 bitmap_set_bit (graph->preds[to], from);
8a3fd8a7 1119}
1120
1121/* Add a graph edge to GRAPH, going from FROM to TO if
29fd4364 1122 it doesn't exist in the graph already.
1123 Return false if the edge already existed, true otherwise. */
1124
1125static bool
eb68f239 1126add_graph_edge (constraint_graph_t graph, unsigned int to,
1127 unsigned int from)
29fd4364 1128{
eb68f239 1129 if (to == from)
29fd4364 1130 {
1131 return false;
1132 }
1133 else
1134 {
db026f5c 1135 bool r = false;
7d1f52b2 1136
eb68f239 1137 if (!graph->succs[from])
8a3fd8a7 1138 graph->succs[from] = BITMAP_ALLOC (&pta_obstack);
b64035d2 1139 if (bitmap_set_bit (graph->succs[from], to))
6395bf5b 1140 {
eb68f239 1141 r = true;
8a3fd8a7 1142 if (to < FIRST_REF_NODE && from < FIRST_REF_NODE)
1143 stats.num_edges++;
6395bf5b 1144 }
29fd4364 1145 return r;
1146 }
1147}
1148
1149
a6db8f14 1150/* Initialize the constraint graph structure to contain SIZE nodes. */
1151
1152static void
1153init_graph (unsigned int size)
1154{
1155 unsigned int j;
1156
1157 graph = XCNEW (struct constraint_graph);
1158 graph->size = size;
1159 graph->succs = XCNEWVEC (bitmap, graph->size);
1160 graph->indirect_cycles = XNEWVEC (int, graph->size);
1161 graph->rep = XNEWVEC (unsigned int, graph->size);
f1f41a6c 1162 /* ??? Macros do not support template types with multiple arguments,
1163 so we use a typedef to work around it. */
1164 typedef vec<constraint_t> vec_constraint_t_heap;
1165 graph->complex = XCNEWVEC (vec_constraint_t_heap, size);
765b6c4f 1166 graph->pe = XCNEWVEC (unsigned int, graph->size);
a6db8f14 1167 graph->pe_rep = XNEWVEC (int, graph->size);
1168
1169 for (j = 0; j < graph->size; j++)
1170 {
1171 graph->rep[j] = j;
a6db8f14 1172 graph->pe_rep[j] = -1;
1173 graph->indirect_cycles[j] = -1;
1174 }
1175}
1176
8a3fd8a7 1177/* Build the constraint graph, adding only predecessor edges right now. */
29fd4364 1178
1179static void
8a3fd8a7 1180build_pred_graph (void)
29fd4364 1181{
8a3fd8a7 1182 int i;
29fd4364 1183 constraint_t c;
8a3fd8a7 1184 unsigned int j;
29fd4364 1185
8a3fd8a7 1186 graph->implicit_preds = XCNEWVEC (bitmap, graph->size);
1187 graph->preds = XCNEWVEC (bitmap, graph->size);
a6db8f14 1188 graph->pointer_label = XCNEWVEC (unsigned int, graph->size);
1189 graph->loc_label = XCNEWVEC (unsigned int, graph->size);
1190 graph->pointed_by = XCNEWVEC (bitmap, graph->size);
1191 graph->points_to = XCNEWVEC (bitmap, graph->size);
8a3fd8a7 1192 graph->eq_rep = XNEWVEC (int, graph->size);
8a3fd8a7 1193 graph->direct_nodes = sbitmap_alloc (graph->size);
a6db8f14 1194 graph->address_taken = BITMAP_ALLOC (&predbitmap_obstack);
53c5d9d4 1195 bitmap_clear (graph->direct_nodes);
8a3fd8a7 1196
5a950977 1197 for (j = 1; j < FIRST_REF_NODE; j++)
8a3fd8a7 1198 {
1199 if (!get_varinfo (j)->is_special_var)
08b7917c 1200 bitmap_set_bit (graph->direct_nodes, j);
8a3fd8a7 1201 }
1202
1203 for (j = 0; j < graph->size; j++)
a6db8f14 1204 graph->eq_rep[j] = -1;
8a3fd8a7 1205
f1f41a6c 1206 for (j = 0; j < varmap.length (); j++)
8a3fd8a7 1207 graph->indirect_cycles[j] = -1;
260e7e11 1208
f1f41a6c 1209 FOR_EACH_VEC_ELT (constraints, i, c)
29fd4364 1210 {
1211 struct constraint_expr lhs = c->lhs;
1212 struct constraint_expr rhs = c->rhs;
dd277d48 1213 unsigned int lhsvar = lhs.var;
1214 unsigned int rhsvar = rhs.var;
5472b425 1215
29fd4364 1216 if (lhs.type == DEREF)
1217 {
8a3fd8a7 1218 /* *x = y. */
1219 if (rhs.offset == 0 && lhs.offset == 0 && rhs.type == SCALAR)
1220 add_pred_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
29fd4364 1221 }
1222 else if (rhs.type == DEREF)
1223 {
8a3fd8a7 1224 /* x = *y */
1225 if (rhs.offset == 0 && lhs.offset == 0 && lhs.type == SCALAR)
1226 add_pred_graph_edge (graph, lhsvar, FIRST_REF_NODE + rhsvar);
1227 else
08b7917c 1228 bitmap_clear_bit (graph->direct_nodes, lhsvar);
29fd4364 1229 }
8a3fd8a7 1230 else if (rhs.type == ADDRESSOF)
29fd4364 1231 {
48d49ced 1232 varinfo_t v;
1233
29fd4364 1234 /* x = &y */
a6db8f14 1235 if (graph->points_to[lhsvar] == NULL)
1236 graph->points_to[lhsvar] = BITMAP_ALLOC (&predbitmap_obstack);
1237 bitmap_set_bit (graph->points_to[lhsvar], rhsvar);
1238
1239 if (graph->pointed_by[rhsvar] == NULL)
1240 graph->pointed_by[rhsvar] = BITMAP_ALLOC (&predbitmap_obstack);
1241 bitmap_set_bit (graph->pointed_by[rhsvar], lhsvar);
1242
8a3fd8a7 1243 /* Implicitly, *x = y */
1244 add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
1245
48d49ced 1246 /* All related variables are no longer direct nodes. */
08b7917c 1247 bitmap_clear_bit (graph->direct_nodes, rhsvar);
dd277d48 1248 v = get_varinfo (rhsvar);
1249 if (!v->is_full_var)
1250 {
5a950977 1251 v = get_varinfo (v->head);
dd277d48 1252 do
1253 {
08b7917c 1254 bitmap_clear_bit (graph->direct_nodes, v->id);
5a950977 1255 v = vi_next (v);
dd277d48 1256 }
1257 while (v != NULL);
1258 }
a6db8f14 1259 bitmap_set_bit (graph->address_taken, rhsvar);
29fd4364 1260 }
8a3fd8a7 1261 else if (lhsvar > anything_id
1262 && lhsvar != rhsvar && lhs.offset == 0 && rhs.offset == 0)
29fd4364 1263 {
8a3fd8a7 1264 /* x = y */
1265 add_pred_graph_edge (graph, lhsvar, rhsvar);
1266 /* Implicitly, *x = *y */
1267 add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar,
1268 FIRST_REF_NODE + rhsvar);
1269 }
1270 else if (lhs.offset != 0 || rhs.offset != 0)
1271 {
1272 if (rhs.offset != 0)
08b7917c 1273 bitmap_clear_bit (graph->direct_nodes, lhs.var);
a6db8f14 1274 else if (lhs.offset != 0)
08b7917c 1275 bitmap_clear_bit (graph->direct_nodes, rhs.var);
8a3fd8a7 1276 }
1277 }
1278}
1279
1280/* Build the constraint graph, adding successor edges. */
1281
1282static void
1283build_succ_graph (void)
1284{
c5168a9e 1285 unsigned i, t;
8a3fd8a7 1286 constraint_t c;
1287
f1f41a6c 1288 FOR_EACH_VEC_ELT (constraints, i, c)
8a3fd8a7 1289 {
1290 struct constraint_expr lhs;
1291 struct constraint_expr rhs;
1292 unsigned int lhsvar;
1293 unsigned int rhsvar;
1294
1295 if (!c)
1296 continue;
7d1f52b2 1297
8a3fd8a7 1298 lhs = c->lhs;
1299 rhs = c->rhs;
dd277d48 1300 lhsvar = find (lhs.var);
1301 rhsvar = find (rhs.var);
8a3fd8a7 1302
1303 if (lhs.type == DEREF)
1304 {
1305 if (rhs.offset == 0 && lhs.offset == 0 && rhs.type == SCALAR)
1306 add_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
1307 }
1308 else if (rhs.type == DEREF)
1309 {
1310 if (rhs.offset == 0 && lhs.offset == 0 && lhs.type == SCALAR)
1311 add_graph_edge (graph, lhsvar, FIRST_REF_NODE + rhsvar);
1312 }
1313 else if (rhs.type == ADDRESSOF)
1314 {
1315 /* x = &y */
6a5ca1fc 1316 gcc_checking_assert (find (rhs.var) == rhs.var);
8a3fd8a7 1317 bitmap_set_bit (get_varinfo (lhsvar)->solution, rhsvar);
1318 }
1319 else if (lhsvar > anything_id
1320 && lhsvar != rhsvar && lhs.offset == 0 && rhs.offset == 0)
1321 {
1322 add_graph_edge (graph, lhsvar, rhsvar);
29fd4364 1323 }
1324 }
c5168a9e 1325
4bfcb72d 1326 /* Add edges from STOREDANYTHING to all non-direct nodes that can
1327 receive pointers. */
c5168a9e 1328 t = find (storedanything_id);
1329 for (i = integer_id + 1; i < FIRST_REF_NODE; ++i)
1330 {
08b7917c 1331 if (!bitmap_bit_p (graph->direct_nodes, i)
4bfcb72d 1332 && get_varinfo (i)->may_have_pointers)
c5168a9e 1333 add_graph_edge (graph, find (i), t);
1334 }
44e93845 1335
1336 /* Everything stored to ANYTHING also potentially escapes. */
1337 add_graph_edge (graph, find (escaped_id), t);
29fd4364 1338}
260e7e11 1339
1340
29fd4364 1341/* Changed variables on the last iteration. */
b392ee8b 1342static bitmap changed;
29fd4364 1343
29fd4364 1344/* Strongly Connected Component visitation info. */
1345
1346struct scc_info
1347{
1348 sbitmap visited;
a6db8f14 1349 sbitmap deleted;
8a3fd8a7 1350 unsigned int *dfs;
1351 unsigned int *node_mapping;
29fd4364 1352 int current_index;
f1f41a6c 1353 vec<unsigned> scc_stack;
29fd4364 1354};
1355
1356
1357/* Recursive routine to find strongly connected components in GRAPH.
1358 SI is the SCC info to store the information in, and N is the id of current
1359 graph node we are processing.
7d1f52b2 1360
29fd4364 1361 This is Tarjan's strongly connected component finding algorithm, as
7d1f52b2 1362 modified by Nuutila to keep only non-root nodes on the stack.
29fd4364 1363 The algorithm can be found in "On finding the strongly connected
1364 connected components in a directed graph" by Esko Nuutila and Eljas
1365 Soisalon-Soininen, in Information Processing Letters volume 49,
1366 number 1, pages 9-14. */
1367
1368static void
1369scc_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
1370{
db026f5c 1371 unsigned int i;
1372 bitmap_iterator bi;
8a3fd8a7 1373 unsigned int my_dfs;
29fd4364 1374
08b7917c 1375 bitmap_set_bit (si->visited, n);
8a3fd8a7 1376 si->dfs[n] = si->current_index ++;
1377 my_dfs = si->dfs[n];
7d1f52b2 1378
29fd4364 1379 /* Visit all the successors. */
eb68f239 1380 EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[n], 0, i, bi)
29fd4364 1381 {
8a3fd8a7 1382 unsigned int w;
1383
1384 if (i > LAST_REF_NODE)
1385 break;
1386
1387 w = find (i);
08b7917c 1388 if (bitmap_bit_p (si->deleted, w))
8a3fd8a7 1389 continue;
1390
08b7917c 1391 if (!bitmap_bit_p (si->visited, w))
db026f5c 1392 scc_visit (graph, si, w);
8a3fd8a7 1393
6a5ca1fc 1394 unsigned int t = find (w);
1395 gcc_checking_assert (find (n) == n);
1396 if (si->dfs[t] < si->dfs[n])
1397 si->dfs[n] = si->dfs[t];
29fd4364 1398 }
7d1f52b2 1399
29fd4364 1400 /* See if any components have been identified. */
8a3fd8a7 1401 if (si->dfs[n] == my_dfs)
29fd4364 1402 {
f1f41a6c 1403 if (si->scc_stack.length () > 0
1404 && si->dfs[si->scc_stack.last ()] >= my_dfs)
29fd4364 1405 {
8a3fd8a7 1406 bitmap scc = BITMAP_ALLOC (NULL);
8a3fd8a7 1407 unsigned int lowest_node;
1408 bitmap_iterator bi;
29fd4364 1409
8a3fd8a7 1410 bitmap_set_bit (scc, n);
29fd4364 1411
f1f41a6c 1412 while (si->scc_stack.length () != 0
1413 && si->dfs[si->scc_stack.last ()] >= my_dfs)
8a3fd8a7 1414 {
f1f41a6c 1415 unsigned int w = si->scc_stack.pop ();
29fd4364 1416
8a3fd8a7 1417 bitmap_set_bit (scc, w);
8a3fd8a7 1418 }
db026f5c 1419
8a3fd8a7 1420 lowest_node = bitmap_first_set_bit (scc);
1421 gcc_assert (lowest_node < FIRST_REF_NODE);
a6db8f14 1422
1423 /* Collapse the SCC nodes into a single node, and mark the
1424 indirect cycles. */
8a3fd8a7 1425 EXECUTE_IF_SET_IN_BITMAP (scc, 0, i, bi)
1426 {
1427 if (i < FIRST_REF_NODE)
1428 {
8a3fd8a7 1429 if (unite (lowest_node, i))
1430 unify_nodes (graph, lowest_node, i, false);
1431 }
1432 else
1433 {
1434 unite (lowest_node, i);
1435 graph->indirect_cycles[i - FIRST_REF_NODE] = lowest_node;
1436 }
1437 }
db026f5c 1438 }
08b7917c 1439 bitmap_set_bit (si->deleted, n);
29fd4364 1440 }
8a3fd8a7 1441 else
f1f41a6c 1442 si->scc_stack.safe_push (n);
29fd4364 1443}
1444
8a3fd8a7 1445/* Unify node FROM into node TO, updating the changed count if
1446 necessary when UPDATE_CHANGED is true. */
29fd4364 1447
1448static void
8a3fd8a7 1449unify_nodes (constraint_graph_t graph, unsigned int to, unsigned int from,
1450 bool update_changed)
29fd4364 1451{
6a5ca1fc 1452 gcc_checking_assert (to != from && find (to) == to);
29fd4364 1453
8a3fd8a7 1454 if (dump_file && (dump_flags & TDF_DETAILS))
1455 fprintf (dump_file, "Unifying %s to %s\n",
1456 get_varinfo (from)->name,
1457 get_varinfo (to)->name);
29fd4364 1458
8a3fd8a7 1459 if (update_changed)
1460 stats.unified_vars_dynamic++;
1461 else
1462 stats.unified_vars_static++;
29fd4364 1463
8a3fd8a7 1464 merge_graph_nodes (graph, to, from);
1465 merge_node_constraints (graph, to, from);
7d1f52b2 1466
a6db8f14 1467 /* Mark TO as changed if FROM was changed. If TO was already marked
1468 as changed, decrease the changed count. */
1469
b392ee8b 1470 if (update_changed
6a5ca1fc 1471 && bitmap_clear_bit (changed, from))
1472 bitmap_set_bit (changed, to);
1473 varinfo_t fromvi = get_varinfo (from);
1474 if (fromvi->solution)
8a3fd8a7 1475 {
765b6c4f 1476 /* If the solution changes because of the merging, we need to mark
1477 the variable as changed. */
6a5ca1fc 1478 varinfo_t tovi = get_varinfo (to);
1479 if (bitmap_ior_into (tovi->solution, fromvi->solution))
29fd4364 1480 {
b392ee8b 1481 if (update_changed)
1482 bitmap_set_bit (changed, to);
765b6c4f 1483 }
48e1416a 1484
6a5ca1fc 1485 BITMAP_FREE (fromvi->solution);
1486 if (fromvi->oldsolution)
1487 BITMAP_FREE (fromvi->oldsolution);
48e1416a 1488
8b3ad377 1489 if (stats.iterations > 0
6a5ca1fc 1490 && tovi->oldsolution)
1491 BITMAP_FREE (tovi->oldsolution);
29fd4364 1492 }
6a5ca1fc 1493 if (graph->succs[to])
1494 bitmap_clear_bit (graph->succs[to], to);
29fd4364 1495}
1496
29fd4364 1497/* Information needed to compute the topological ordering of a graph. */
1498
1499struct topo_info
1500{
1501 /* sbitmap of visited nodes. */
1502 sbitmap visited;
1503 /* Array that stores the topological order of the graph, *in
1504 reverse*. */
f1f41a6c 1505 vec<unsigned> topo_order;
29fd4364 1506};
1507
1508
1509/* Initialize and return a topological info structure. */
1510
1511static struct topo_info *
1512init_topo_info (void)
1513{
a6db8f14 1514 size_t size = graph->size;
4c36ffe6 1515 struct topo_info *ti = XNEW (struct topo_info);
29fd4364 1516 ti->visited = sbitmap_alloc (size);
53c5d9d4 1517 bitmap_clear (ti->visited);
f1f41a6c 1518 ti->topo_order.create (1);
29fd4364 1519 return ti;
1520}
1521
1522
1523/* Free the topological sort info pointed to by TI. */
1524
1525static void
1526free_topo_info (struct topo_info *ti)
1527{
1528 sbitmap_free (ti->visited);
f1f41a6c 1529 ti->topo_order.release ();
29fd4364 1530 free (ti);
1531}
1532
1533/* Visit the graph in topological order, and store the order in the
1534 topo_info structure. */
1535
1536static void
1537topo_visit (constraint_graph_t graph, struct topo_info *ti,
1538 unsigned int n)
1539{
db026f5c 1540 bitmap_iterator bi;
db026f5c 1541 unsigned int j;
1542
08b7917c 1543 bitmap_set_bit (ti->visited, n);
db026f5c 1544
8a3fd8a7 1545 if (graph->succs[n])
1546 EXECUTE_IF_SET_IN_BITMAP (graph->succs[n], 0, j, bi)
db026f5c 1547 {
08b7917c 1548 if (!bitmap_bit_p (ti->visited, j))
db026f5c 1549 topo_visit (graph, ti, j);
1550 }
8a3fd8a7 1551
f1f41a6c 1552 ti->topo_order.safe_push (n);
29fd4364 1553}
1554
dd277d48 1555/* Process a constraint C that represents x = *(y + off), using DELTA as the
1556 starting solution for y. */
29fd4364 1557
1558static void
1559do_sd_constraint (constraint_graph_t graph, constraint_t c,
1560 bitmap delta)
1561{
a6db8f14 1562 unsigned int lhs = c->lhs.var;
29fd4364 1563 bool flag = false;
1564 bitmap sol = get_varinfo (lhs)->solution;
1565 unsigned int j;
1566 bitmap_iterator bi;
dd277d48 1567 HOST_WIDE_INT roffset = c->rhs.offset;
db026f5c 1568
dd277d48 1569 /* Our IL does not allow this. */
6a5ca1fc 1570 gcc_checking_assert (c->lhs.offset == 0);
fc733d7a 1571
dd277d48 1572 /* If the solution of Y contains anything it is good enough to transfer
1573 this to the LHS. */
98de8b69 1574 if (bitmap_bit_p (delta, anything_id))
1575 {
1576 flag |= bitmap_set_bit (sol, anything_id);
1577 goto done;
1578 }
1579
dd277d48 1580 /* If we do not know at with offset the rhs is dereferenced compute
1581 the reachability set of DELTA, conservatively assuming it is
1582 dereferenced at all valid offsets. */
1583 if (roffset == UNKNOWN_OFFSET)
1584 {
5a950977 1585 solution_set_expand (delta);
dd277d48 1586 /* No further offset processing is necessary. */
1587 roffset = 0;
1588 }
1589
7d1f52b2 1590 /* For each variable j in delta (Sol(y)), add
29fd4364 1591 an edge in the graph from j to x, and union Sol(j) into Sol(x). */
1592 EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
1593 {
dd277d48 1594 varinfo_t v = get_varinfo (j);
1595 HOST_WIDE_INT fieldoffset = v->offset + roffset;
1596 unsigned int t;
1597
1598 if (v->is_full_var)
1599 fieldoffset = v->offset;
1600 else if (roffset != 0)
1601 v = first_vi_for_offset (v, fieldoffset);
1602 /* If the access is outside of the variable we can ignore it. */
1603 if (!v)
1604 continue;
29fd4364 1605
dd277d48 1606 do
1607 {
8a3fd8a7 1608 t = find (v->id);
db026f5c 1609
1610 /* Adding edges from the special vars is pointless.
1611 They don't have sets that can change. */
0b3bf4d6 1612 if (get_varinfo (t)->is_special_var)
db026f5c 1613 flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
0b3bf4d6 1614 /* Merging the solution from ESCAPED needlessly increases
9d1d1fab 1615 the set. Use ESCAPED as representative instead. */
dd277d48 1616 else if (v->id == escaped_id)
f13e5f6d 1617 flag |= bitmap_set_bit (sol, escaped_id);
e1148535 1618 else if (v->may_have_pointers
1619 && add_graph_edge (graph, lhs, t))
db026f5c 1620 flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
dd277d48 1621
1622 /* If the variable is not exactly at the requested offset
1623 we have to include the next one. */
1624 if (v->offset == (unsigned HOST_WIDE_INT)fieldoffset
5a950977 1625 || v->next == 0)
dd277d48 1626 break;
1627
5a950977 1628 v = vi_next (v);
dd277d48 1629 fieldoffset = v->offset;
29fd4364 1630 }
dd277d48 1631 while (1);
29fd4364 1632 }
bdf4f142 1633
db026f5c 1634done:
29fd4364 1635 /* If the LHS solution changed, mark the var as changed. */
1636 if (flag)
1637 {
1638 get_varinfo (lhs)->solution = sol;
b392ee8b 1639 bitmap_set_bit (changed, lhs);
7d1f52b2 1640 }
29fd4364 1641}
1642
dd277d48 1643/* Process a constraint C that represents *(x + off) = y using DELTA
1644 as the starting solution for x. */
29fd4364 1645
1646static void
eb68f239 1647do_ds_constraint (constraint_t c, bitmap delta)
29fd4364 1648{
a6db8f14 1649 unsigned int rhs = c->rhs.var;
29fd4364 1650 bitmap sol = get_varinfo (rhs)->solution;
1651 unsigned int j;
1652 bitmap_iterator bi;
dd277d48 1653 HOST_WIDE_INT loff = c->lhs.offset;
b2c2343f 1654 bool escaped_p = false;
29fd4364 1655
c5168a9e 1656 /* Our IL does not allow this. */
6a5ca1fc 1657 gcc_checking_assert (c->rhs.offset == 0);
c5168a9e 1658
1659 /* If the solution of y contains ANYTHING simply use the ANYTHING
1660 solution. This avoids needlessly increasing the points-to sets. */
1661 if (bitmap_bit_p (sol, anything_id))
1662 sol = get_varinfo (find (anything_id))->solution;
1663
1664 /* If the solution for x contains ANYTHING we have to merge the
1665 solution of y into all pointer variables which we do via
1666 STOREDANYTHING. */
1667 if (bitmap_bit_p (delta, anything_id))
1668 {
1669 unsigned t = find (storedanything_id);
1670 if (add_graph_edge (graph, t, rhs))
1671 {
1672 if (bitmap_ior_into (get_varinfo (t)->solution, sol))
b392ee8b 1673 bitmap_set_bit (changed, t);
c5168a9e 1674 }
1675 return;
1676 }
db026f5c 1677
dd277d48 1678 /* If we do not know at with offset the rhs is dereferenced compute
1679 the reachability set of DELTA, conservatively assuming it is
1680 dereferenced at all valid offsets. */
1681 if (loff == UNKNOWN_OFFSET)
1682 {
5a950977 1683 solution_set_expand (delta);
dd277d48 1684 loff = 0;
1685 }
1686
29fd4364 1687 /* For each member j of delta (Sol(x)), add an edge from y to j and
1688 union Sol(y) into Sol(j) */
1689 EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
1690 {
dd277d48 1691 varinfo_t v = get_varinfo (j);
1692 unsigned int t;
1693 HOST_WIDE_INT fieldoffset = v->offset + loff;
7d1f52b2 1694
dd277d48 1695 if (v->is_full_var)
1696 fieldoffset = v->offset;
1697 else if (loff != 0)
1698 v = first_vi_for_offset (v, fieldoffset);
1699 /* If the access is outside of the variable we can ignore it. */
1700 if (!v)
1701 continue;
eb68f239 1702
dd277d48 1703 do
1704 {
c5168a9e 1705 if (v->may_have_pointers)
29fd4364 1706 {
b2c2343f 1707 /* If v is a global variable then this is an escape point. */
1708 if (v->is_global_var
1709 && !escaped_p)
1710 {
1711 t = find (escaped_id);
1712 if (add_graph_edge (graph, t, rhs)
b392ee8b 1713 && bitmap_ior_into (get_varinfo (t)->solution, sol))
1714 bitmap_set_bit (changed, t);
b2c2343f 1715 /* Enough to let rhs escape once. */
1716 escaped_p = true;
1717 }
1718
1719 if (v->is_special_var)
1720 break;
1721
c5168a9e 1722 t = find (v->id);
c174c650 1723 if (add_graph_edge (graph, t, rhs)
b392ee8b 1724 && bitmap_ior_into (get_varinfo (t)->solution, sol))
1725 bitmap_set_bit (changed, t);
c174c650 1726 }
dd277d48 1727
1728 /* If the variable is not exactly at the requested offset
1729 we have to include the next one. */
1730 if (v->offset == (unsigned HOST_WIDE_INT)fieldoffset
5a950977 1731 || v->next == 0)
dd277d48 1732 break;
1733
5a950977 1734 v = vi_next (v);
dd277d48 1735 fieldoffset = v->offset;
eb68f239 1736 }
dd277d48 1737 while (1);
29fd4364 1738 }
1739}
1740
8a3fd8a7 1741/* Handle a non-simple (simple meaning requires no iteration),
1742 constraint (IE *x = &y, x = *y, *x = y, and x = y with offsets involved). */
7d1f52b2 1743
29fd4364 1744static void
1745do_complex_constraint (constraint_graph_t graph, constraint_t c, bitmap delta)
1746{
1747 if (c->lhs.type == DEREF)
1748 {
1749 if (c->rhs.type == ADDRESSOF)
1750 {
9af5ce0c 1751 gcc_unreachable ();
29fd4364 1752 }
1753 else
1754 {
1755 /* *x = y */
eb68f239 1756 do_ds_constraint (c, delta);
29fd4364 1757 }
1758 }
eb68f239 1759 else if (c->rhs.type == DEREF)
29fd4364 1760 {
1761 /* x = *y */
300b54b8 1762 if (!(get_varinfo (c->lhs.var)->is_special_var))
1763 do_sd_constraint (graph, c, delta);
29fd4364 1764 }
7d1f52b2 1765 else
eb68f239 1766 {
7d1f52b2 1767 bitmap tmp;
eb68f239 1768 bitmap solution;
1769 bool flag = false;
eb68f239 1770
6a5ca1fc 1771 gcc_checking_assert (c->rhs.type == SCALAR && c->lhs.type == SCALAR);
a6db8f14 1772 solution = get_varinfo (c->rhs.var)->solution;
1773 tmp = get_varinfo (c->lhs.var)->solution;
eb68f239 1774
1775 flag = set_union_with_increment (tmp, solution, c->rhs.offset);
7d1f52b2 1776
eb68f239 1777 if (flag)
5a950977 1778 bitmap_set_bit (changed, c->lhs.var);
eb68f239 1779 }
29fd4364 1780}
1781
1782/* Initialize and return a new SCC info structure. */
1783
1784static struct scc_info *
8a3fd8a7 1785init_scc_info (size_t size)
29fd4364 1786{
4c36ffe6 1787 struct scc_info *si = XNEW (struct scc_info);
8a3fd8a7 1788 size_t i;
29fd4364 1789
1790 si->current_index = 0;
1791 si->visited = sbitmap_alloc (size);
53c5d9d4 1792 bitmap_clear (si->visited);
a6db8f14 1793 si->deleted = sbitmap_alloc (size);
53c5d9d4 1794 bitmap_clear (si->deleted);
8a3fd8a7 1795 si->node_mapping = XNEWVEC (unsigned int, size);
1796 si->dfs = XCNEWVEC (unsigned int, size);
1797
1798 for (i = 0; i < size; i++)
1799 si->node_mapping[i] = i;
1800
f1f41a6c 1801 si->scc_stack.create (1);
29fd4364 1802 return si;
1803}
1804
1805/* Free an SCC info structure pointed to by SI */
1806
1807static void
1808free_scc_info (struct scc_info *si)
7d1f52b2 1809{
29fd4364 1810 sbitmap_free (si->visited);
a6db8f14 1811 sbitmap_free (si->deleted);
8a3fd8a7 1812 free (si->node_mapping);
1813 free (si->dfs);
f1f41a6c 1814 si->scc_stack.release ();
8a3fd8a7 1815 free (si);
29fd4364 1816}
1817
1818
8a3fd8a7 1819/* Find indirect cycles in GRAPH that occur, using strongly connected
1820 components, and note them in the indirect cycles map.
1821
1822 This technique comes from Ben Hardekopf and Calvin Lin,
1823 "It Pays to be Lazy: Fast and Accurate Pointer Analysis for Millions of
1824 Lines of Code", submitted to PLDI 2007. */
29fd4364 1825
1826static void
8a3fd8a7 1827find_indirect_cycles (constraint_graph_t graph)
29fd4364 1828{
1829 unsigned int i;
8a3fd8a7 1830 unsigned int size = graph->size;
1831 struct scc_info *si = init_scc_info (size);
29fd4364 1832
8a3fd8a7 1833 for (i = 0; i < MIN (LAST_REF_NODE, size); i ++ )
08b7917c 1834 if (!bitmap_bit_p (si->visited, i) && find (i) == i)
29fd4364 1835 scc_visit (graph, si, i);
7d1f52b2 1836
29fd4364 1837 free_scc_info (si);
1838}
1839
1840/* Compute a topological ordering for GRAPH, and store the result in the
1841 topo_info structure TI. */
1842
7d1f52b2 1843static void
29fd4364 1844compute_topo_order (constraint_graph_t graph,
1845 struct topo_info *ti)
1846{
1847 unsigned int i;
a6db8f14 1848 unsigned int size = graph->size;
7d1f52b2 1849
29fd4364 1850 for (i = 0; i != size; ++i)
08b7917c 1851 if (!bitmap_bit_p (ti->visited, i) && find (i) == i)
29fd4364 1852 topo_visit (graph, ti, i);
1853}
1854
a6db8f14 1855/* Structure used to for hash value numbering of pointer equivalence
1856 classes. */
1857
1858typedef struct equiv_class_label
1859{
9fac1c66 1860 hashval_t hashcode;
a6db8f14 1861 unsigned int equivalence_class;
1862 bitmap labels;
a6db8f14 1863} *equiv_class_label_t;
fb80456a 1864typedef const struct equiv_class_label *const_equiv_class_label_t;
a6db8f14 1865
3e871d4d 1866/* Equiv_class_label hashtable helpers. */
a6db8f14 1867
3e871d4d 1868struct equiv_class_hasher : typed_free_remove <equiv_class_label>
1869{
1870 typedef equiv_class_label value_type;
1871 typedef equiv_class_label compare_type;
1872 static inline hashval_t hash (const value_type *);
1873 static inline bool equal (const value_type *, const compare_type *);
1874};
a6db8f14 1875
1876/* Hash function for a equiv_class_label_t */
1877
3e871d4d 1878inline hashval_t
1879equiv_class_hasher::hash (const value_type *ecl)
a6db8f14 1880{
a6db8f14 1881 return ecl->hashcode;
1882}
1883
1884/* Equality function for two equiv_class_label_t's. */
1885
3e871d4d 1886inline bool
1887equiv_class_hasher::equal (const value_type *eql1, const compare_type *eql2)
a6db8f14 1888{
2adb8813 1889 return (eql1->hashcode == eql2->hashcode
1890 && bitmap_equal_p (eql1->labels, eql2->labels));
a6db8f14 1891}
1892
3e871d4d 1893/* A hashtable for mapping a bitmap of labels->pointer equivalence
1894 classes. */
1895static hash_table <equiv_class_hasher> pointer_equiv_class_table;
1896
1897/* A hashtable for mapping a bitmap of labels->location equivalence
1898 classes. */
1899static hash_table <equiv_class_hasher> location_equiv_class_table;
1900
98102711 1901/* Lookup a equivalence class in TABLE by the bitmap of LABELS with
1902 hash HAS it contains. Sets *REF_LABELS to the bitmap LABELS
1903 is equivalent to. */
a6db8f14 1904
98102711 1905static equiv_class_label *
3e871d4d 1906equiv_class_lookup_or_add (hash_table <equiv_class_hasher> table, bitmap labels)
a6db8f14 1907{
98102711 1908 equiv_class_label **slot;
1909 equiv_class_label ecl;
a6db8f14 1910
1911 ecl.labels = labels;
1912 ecl.hashcode = bitmap_hash (labels);
3e871d4d 1913 slot = table.find_slot_with_hash (&ecl, ecl.hashcode, INSERT);
98102711 1914 if (!*slot)
783d1e89 1915 {
98102711 1916 *slot = XNEW (struct equiv_class_label);
1917 (*slot)->labels = labels;
1918 (*slot)->hashcode = ecl.hashcode;
1919 (*slot)->equivalence_class = 0;
783d1e89 1920 }
a6db8f14 1921
98102711 1922 return *slot;
a6db8f14 1923}
1924
1925/* Perform offline variable substitution.
29fd4364 1926
a6db8f14 1927 This is a worst case quadratic time way of identifying variables
1928 that must have equivalent points-to sets, including those caused by
1929 static cycles, and single entry subgraphs, in the constraint graph.
8a3fd8a7 1930
a6db8f14 1931 The technique is described in "Exploiting Pointer and Location
1932 Equivalence to Optimize Pointer Analysis. In the 14th International
1933 Static Analysis Symposium (SAS), August 2007." It is known as the
1934 "HU" algorithm, and is equivalent to value numbering the collapsed
1935 constraint graph including evaluating unions.
8a3fd8a7 1936
1937 The general method of finding equivalence classes is as follows:
1938 Add fake nodes (REF nodes) and edges for *a = b and a = *b constraints.
a6db8f14 1939 Initialize all non-REF nodes to be direct nodes.
1940 For each constraint a = a U {b}, we set pts(a) = pts(a) u {fresh
1941 variable}
1942 For each constraint containing the dereference, we also do the same
1943 thing.
1944
1945 We then compute SCC's in the graph and unify nodes in the same SCC,
1946 including pts sets.
1947
1948 For each non-collapsed node x:
1949 Visit all unvisited explicit incoming edges.
1950 Ignoring all non-pointers, set pts(x) = Union of pts(a) for y
1951 where y->x.
1952 Lookup the equivalence class for pts(x).
1953 If we found one, equivalence_class(x) = found class.
1954 Otherwise, equivalence_class(x) = new class, and new_class is
1955 added to the lookup table.
8a3fd8a7 1956
1957 All direct nodes with the same equivalence class can be replaced
1958 with a single representative node.
1959 All unlabeled nodes (label == 0) are not pointers and all edges
1960 involving them can be eliminated.
a6db8f14 1961 We perform these optimizations during rewrite_constraints
1962
1963 In addition to pointer equivalence class finding, we also perform
1964 location equivalence class finding. This is the set of variables
1965 that always appear together in points-to sets. We use this to
1966 compress the size of the points-to sets. */
1967
1968/* Current maximum pointer equivalence class id. */
1969static int pointer_equiv_class;
8a3fd8a7 1970
a6db8f14 1971/* Current maximum location equivalence class id. */
1972static int location_equiv_class;
8a3fd8a7 1973
1974/* Recursive routine to find strongly connected components in GRAPH,
a6db8f14 1975 and label it's nodes with DFS numbers. */
29fd4364 1976
1977static void
a6db8f14 1978condense_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
29fd4364 1979{
8a3fd8a7 1980 unsigned int i;
1981 bitmap_iterator bi;
1982 unsigned int my_dfs;
7d1f52b2 1983
6a5ca1fc 1984 gcc_checking_assert (si->node_mapping[n] == n);
08b7917c 1985 bitmap_set_bit (si->visited, n);
8a3fd8a7 1986 si->dfs[n] = si->current_index ++;
1987 my_dfs = si->dfs[n];
7d1f52b2 1988
8a3fd8a7 1989 /* Visit all the successors. */
1990 EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[n], 0, i, bi)
29fd4364 1991 {
8a3fd8a7 1992 unsigned int w = si->node_mapping[i];
29fd4364 1993
08b7917c 1994 if (bitmap_bit_p (si->deleted, w))
29fd4364 1995 continue;
1996
08b7917c 1997 if (!bitmap_bit_p (si->visited, w))
a6db8f14 1998 condense_visit (graph, si, w);
29fd4364 1999
6a5ca1fc 2000 unsigned int t = si->node_mapping[w];
2001 gcc_checking_assert (si->node_mapping[n] == n);
2002 if (si->dfs[t] < si->dfs[n])
2003 si->dfs[n] = si->dfs[t];
8a3fd8a7 2004 }
29fd4364 2005
8a3fd8a7 2006 /* Visit all the implicit predecessors. */
2007 EXECUTE_IF_IN_NONNULL_BITMAP (graph->implicit_preds[n], 0, i, bi)
2008 {
2009 unsigned int w = si->node_mapping[i];
2010
08b7917c 2011 if (bitmap_bit_p (si->deleted, w))
8a3fd8a7 2012 continue;
2013
08b7917c 2014 if (!bitmap_bit_p (si->visited, w))
a6db8f14 2015 condense_visit (graph, si, w);
8a3fd8a7 2016
6a5ca1fc 2017 unsigned int t = si->node_mapping[w];
2018 gcc_assert (si->node_mapping[n] == n);
2019 if (si->dfs[t] < si->dfs[n])
2020 si->dfs[n] = si->dfs[t];
8a3fd8a7 2021 }
db026f5c 2022
8a3fd8a7 2023 /* See if any components have been identified. */
2024 if (si->dfs[n] == my_dfs)
2025 {
f1f41a6c 2026 while (si->scc_stack.length () != 0
2027 && si->dfs[si->scc_stack.last ()] >= my_dfs)
29fd4364 2028 {
f1f41a6c 2029 unsigned int w = si->scc_stack.pop ();
8a3fd8a7 2030 si->node_mapping[w] = n;
2031
08b7917c 2032 if (!bitmap_bit_p (graph->direct_nodes, w))
2033 bitmap_clear_bit (graph->direct_nodes, n);
8a3fd8a7 2034
a6db8f14 2035 /* Unify our nodes. */
2036 if (graph->preds[w])
2037 {
2038 if (!graph->preds[n])
2039 graph->preds[n] = BITMAP_ALLOC (&predbitmap_obstack);
2040 bitmap_ior_into (graph->preds[n], graph->preds[w]);
2041 }
2042 if (graph->implicit_preds[w])
2043 {
2044 if (!graph->implicit_preds[n])
2045 graph->implicit_preds[n] = BITMAP_ALLOC (&predbitmap_obstack);
2046 bitmap_ior_into (graph->implicit_preds[n],
2047 graph->implicit_preds[w]);
2048 }
2049 if (graph->points_to[w])
2050 {
2051 if (!graph->points_to[n])
2052 graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack);
2053 bitmap_ior_into (graph->points_to[n],
2054 graph->points_to[w]);
2055 }
8a3fd8a7 2056 }
08b7917c 2057 bitmap_set_bit (si->deleted, n);
8a3fd8a7 2058 }
2059 else
f1f41a6c 2060 si->scc_stack.safe_push (n);
8a3fd8a7 2061}
2062
a6db8f14 2063/* Label pointer equivalences. */
2064
2065static void
2066label_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
2067{
c74cfdaf 2068 unsigned int i, first_pred;
a6db8f14 2069 bitmap_iterator bi;
a6db8f14 2070
c74cfdaf 2071 bitmap_set_bit (si->visited, n);
a6db8f14 2072
2073 /* Label and union our incoming edges's points to sets. */
c74cfdaf 2074 first_pred = -1U;
a6db8f14 2075 EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[n], 0, i, bi)
2076 {
2077 unsigned int w = si->node_mapping[i];
08b7917c 2078 if (!bitmap_bit_p (si->visited, w))
a6db8f14 2079 label_visit (graph, si, w);
2080
2081 /* Skip unused edges */
2082 if (w == n || graph->pointer_label[w] == 0)
1cec0392 2083 continue;
2084
a6db8f14 2085 if (graph->points_to[w])
c74cfdaf 2086 {
5342937d 2087 if (!graph->points_to[n])
c74cfdaf 2088 {
5342937d 2089 if (first_pred == -1U)
2090 first_pred = w;
2091 else
2092 {
2093 graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack);
2094 bitmap_ior (graph->points_to[n],
2095 graph->points_to[first_pred],
2096 graph->points_to[w]);
2097 }
c74cfdaf 2098 }
2099 else
9af5ce0c 2100 bitmap_ior_into (graph->points_to[n], graph->points_to[w]);
c74cfdaf 2101 }
a6db8f14 2102 }
c74cfdaf 2103
2104 /* Indirect nodes get fresh variables and a new pointer equiv class. */
08b7917c 2105 if (!bitmap_bit_p (graph->direct_nodes, n))
c74cfdaf 2106 {
2107 if (!graph->points_to[n])
2108 {
2109 graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack);
2110 if (first_pred != -1U)
2111 bitmap_copy (graph->points_to[n], graph->points_to[first_pred]);
2112 }
2113 bitmap_set_bit (graph->points_to[n], FIRST_REF_NODE + n);
2114 graph->pointer_label[n] = pointer_equiv_class++;
98102711 2115 equiv_class_label_t ecl;
2116 ecl = equiv_class_lookup_or_add (pointer_equiv_class_table,
2117 graph->points_to[n]);
2118 ecl->equivalence_class = graph->pointer_label[n];
c74cfdaf 2119 return;
2120 }
2121
2122 /* If there was only a single non-empty predecessor the pointer equiv
2123 class is the same. */
2124 if (!graph->points_to[n])
2125 {
2126 if (first_pred != -1U)
2127 {
2128 graph->pointer_label[n] = graph->pointer_label[first_pred];
2129 graph->points_to[n] = graph->points_to[first_pred];
2130 }
2131 return;
2132 }
a6db8f14 2133
2134 if (!bitmap_empty_p (graph->points_to[n]))
2135 {
98102711 2136 equiv_class_label_t ecl;
2137 ecl = equiv_class_lookup_or_add (pointer_equiv_class_table,
2138 graph->points_to[n]);
2139 if (ecl->equivalence_class == 0)
2140 ecl->equivalence_class = pointer_equiv_class++;
783d1e89 2141 else
2142 {
2143 BITMAP_FREE (graph->points_to[n]);
98102711 2144 graph->points_to[n] = ecl->labels;
783d1e89 2145 }
98102711 2146 graph->pointer_label[n] = ecl->equivalence_class;
a6db8f14 2147 }
2148}
2149
6a5ca1fc 2150/* Print the pred graph in dot format. */
2151
2152static void
2153dump_pred_graph (struct scc_info *si, FILE *file)
2154{
2155 unsigned int i;
2156
2157 /* Only print the graph if it has already been initialized: */
2158 if (!graph)
2159 return;
2160
2161 /* Prints the header of the dot file: */
2162 fprintf (file, "strict digraph {\n");
2163 fprintf (file, " node [\n shape = box\n ]\n");
2164 fprintf (file, " edge [\n fontsize = \"12\"\n ]\n");
2165 fprintf (file, "\n // List of nodes and complex constraints in "
2166 "the constraint graph:\n");
2167
2168 /* The next lines print the nodes in the graph together with the
2169 complex constraints attached to them. */
5a950977 2170 for (i = 1; i < graph->size; i++)
6a5ca1fc 2171 {
5a950977 2172 if (i == FIRST_REF_NODE)
2173 continue;
6a5ca1fc 2174 if (si->node_mapping[i] != i)
2175 continue;
2176 if (i < FIRST_REF_NODE)
2177 fprintf (file, "\"%s\"", get_varinfo (i)->name);
2178 else
2179 fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
2180 if (graph->points_to[i]
2181 && !bitmap_empty_p (graph->points_to[i]))
2182 {
2183 fprintf (file, "[label=\"%s = {", get_varinfo (i)->name);
2184 unsigned j;
2185 bitmap_iterator bi;
2186 EXECUTE_IF_SET_IN_BITMAP (graph->points_to[i], 0, j, bi)
2187 fprintf (file, " %d", j);
2188 fprintf (file, " }\"]");
2189 }
2190 fprintf (file, ";\n");
2191 }
2192
2193 /* Go over the edges. */
2194 fprintf (file, "\n // Edges in the constraint graph:\n");
5a950977 2195 for (i = 1; i < graph->size; i++)
6a5ca1fc 2196 {
2197 unsigned j;
2198 bitmap_iterator bi;
2199 if (si->node_mapping[i] != i)
2200 continue;
2201 EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[i], 0, j, bi)
2202 {
2203 unsigned from = si->node_mapping[j];
2204 if (from < FIRST_REF_NODE)
2205 fprintf (file, "\"%s\"", get_varinfo (from)->name);
2206 else
2207 fprintf (file, "\"*%s\"", get_varinfo (from - FIRST_REF_NODE)->name);
2208 fprintf (file, " -> ");
2209 if (i < FIRST_REF_NODE)
2210 fprintf (file, "\"%s\"", get_varinfo (i)->name);
2211 else
2212 fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
2213 fprintf (file, ";\n");
2214 }
2215 }
2216
2217 /* Prints the tail of the dot file. */
2218 fprintf (file, "}\n");
2219}
2220
8a3fd8a7 2221/* Perform offline variable substitution, discovering equivalence
2222 classes, and eliminating non-pointer variables. */
2223
2224static struct scc_info *
2225perform_var_substitution (constraint_graph_t graph)
2226{
2227 unsigned int i;
2228 unsigned int size = graph->size;
2229 struct scc_info *si = init_scc_info (size);
2230
2231 bitmap_obstack_initialize (&iteration_obstack);
3e871d4d 2232 pointer_equiv_class_table.create (511);
2233 location_equiv_class_table.create (511);
a6db8f14 2234 pointer_equiv_class = 1;
2235 location_equiv_class = 1;
2236
2237 /* Condense the nodes, which means to find SCC's, count incoming
2238 predecessors, and unite nodes in SCC's. */
5a950977 2239 for (i = 1; i < FIRST_REF_NODE; i++)
08b7917c 2240 if (!bitmap_bit_p (si->visited, si->node_mapping[i]))
a6db8f14 2241 condense_visit (graph, si, si->node_mapping[i]);
8a3fd8a7 2242
6a5ca1fc 2243 if (dump_file && (dump_flags & TDF_GRAPH))
2244 {
2245 fprintf (dump_file, "\n\n// The constraint graph before var-substitution "
2246 "in dot format:\n");
2247 dump_pred_graph (si, dump_file);
2248 fprintf (dump_file, "\n\n");
2249 }
2250
53c5d9d4 2251 bitmap_clear (si->visited);
a6db8f14 2252 /* Actually the label the nodes for pointer equivalences */
5a950977 2253 for (i = 1; i < FIRST_REF_NODE; i++)
08b7917c 2254 if (!bitmap_bit_p (si->visited, si->node_mapping[i]))
8a3fd8a7 2255 label_visit (graph, si, si->node_mapping[i]);
2256
a6db8f14 2257 /* Calculate location equivalence labels. */
5a950977 2258 for (i = 1; i < FIRST_REF_NODE; i++)
a6db8f14 2259 {
2260 bitmap pointed_by;
2261 bitmap_iterator bi;
2262 unsigned int j;
a6db8f14 2263
2264 if (!graph->pointed_by[i])
2265 continue;
2266 pointed_by = BITMAP_ALLOC (&iteration_obstack);
2267
2268 /* Translate the pointed-by mapping for pointer equivalence
2269 labels. */
2270 EXECUTE_IF_SET_IN_BITMAP (graph->pointed_by[i], 0, j, bi)
2271 {
2272 bitmap_set_bit (pointed_by,
2273 graph->pointer_label[si->node_mapping[j]]);
2274 }
2275 /* The original pointed_by is now dead. */
2276 BITMAP_FREE (graph->pointed_by[i]);
2277
2278 /* Look up the location equivalence label if one exists, or make
2279 one otherwise. */
98102711 2280 equiv_class_label_t ecl;
2281 ecl = equiv_class_lookup_or_add (location_equiv_class_table, pointed_by);
2282 if (ecl->equivalence_class == 0)
2283 ecl->equivalence_class = location_equiv_class++;
a6db8f14 2284 else
2285 {
2286 if (dump_file && (dump_flags & TDF_DETAILS))
2287 fprintf (dump_file, "Found location equivalence for node %s\n",
2288 get_varinfo (i)->name);
2289 BITMAP_FREE (pointed_by);
2290 }
98102711 2291 graph->loc_label[i] = ecl->equivalence_class;
a6db8f14 2292
2293 }
2294
8a3fd8a7 2295 if (dump_file && (dump_flags & TDF_DETAILS))
5a950977 2296 for (i = 1; i < FIRST_REF_NODE; i++)
8a3fd8a7 2297 {
5342937d 2298 unsigned j = si->node_mapping[i];
2299 if (j != i)
6c9b05aa 2300 {
2301 fprintf (dump_file, "%s node id %d ",
2302 bitmap_bit_p (graph->direct_nodes, i)
2303 ? "Direct" : "Indirect", i);
2304 if (i < FIRST_REF_NODE)
2305 fprintf (dump_file, "\"%s\"", get_varinfo (i)->name);
2306 else
2307 fprintf (dump_file, "\"*%s\"",
2308 get_varinfo (i - FIRST_REF_NODE)->name);
2309 fprintf (dump_file, " mapped to SCC leader node id %d ", j);
2310 if (j < FIRST_REF_NODE)
2311 fprintf (dump_file, "\"%s\"\n", get_varinfo (j)->name);
2312 else
2313 fprintf (dump_file, "\"*%s\"\n",
2314 get_varinfo (j - FIRST_REF_NODE)->name);
2315 }
5342937d 2316 else
6c9b05aa 2317 {
2318 fprintf (dump_file,
2319 "Equivalence classes for %s node id %d ",
2320 bitmap_bit_p (graph->direct_nodes, i)
2321 ? "direct" : "indirect", i);
2322 if (i < FIRST_REF_NODE)
2323 fprintf (dump_file, "\"%s\"", get_varinfo (i)->name);
2324 else
2325 fprintf (dump_file, "\"*%s\"",
2326 get_varinfo (i - FIRST_REF_NODE)->name);
2327 fprintf (dump_file,
2328 ": pointer %d, location %d\n",
2329 graph->pointer_label[i], graph->loc_label[i]);
2330 }
8a3fd8a7 2331 }
2332
2333 /* Quickly eliminate our non-pointer variables. */
2334
5a950977 2335 for (i = 1; i < FIRST_REF_NODE; i++)
8a3fd8a7 2336 {
2337 unsigned int node = si->node_mapping[i];
2338
765b6c4f 2339 if (graph->pointer_label[node] == 0)
8a3fd8a7 2340 {
0868ec7d 2341 if (dump_file && (dump_flags & TDF_DETAILS))
8a3fd8a7 2342 fprintf (dump_file,
2343 "%s is a non-pointer variable, eliminating edges.\n",
2344 get_varinfo (node)->name);
2345 stats.nonpointer_vars++;
2346 clear_edges_for_node (graph, node);
29fd4364 2347 }
2348 }
a6db8f14 2349
8a3fd8a7 2350 return si;
2351}
2352
2353/* Free information that was only necessary for variable
2354 substitution. */
29fd4364 2355
8a3fd8a7 2356static void
2357free_var_substitution_info (struct scc_info *si)
2358{
2359 free_scc_info (si);
a6db8f14 2360 free (graph->pointer_label);
2361 free (graph->loc_label);
2362 free (graph->pointed_by);
2363 free (graph->points_to);
8a3fd8a7 2364 free (graph->eq_rep);
2365 sbitmap_free (graph->direct_nodes);
3e871d4d 2366 pointer_equiv_class_table.dispose ();
2367 location_equiv_class_table.dispose ();
db026f5c 2368 bitmap_obstack_release (&iteration_obstack);
8a3fd8a7 2369}
2370
2371/* Return an existing node that is equivalent to NODE, which has
2372 equivalence class LABEL, if one exists. Return NODE otherwise. */
2373
2374static unsigned int
2375find_equivalent_node (constraint_graph_t graph,
2376 unsigned int node, unsigned int label)
2377{
2378 /* If the address version of this variable is unused, we can
2379 substitute it for anything else with the same label.
2380 Otherwise, we know the pointers are equivalent, but not the
a6db8f14 2381 locations, and we can unite them later. */
8a3fd8a7 2382
a6db8f14 2383 if (!bitmap_bit_p (graph->address_taken, node))
8a3fd8a7 2384 {
6a5ca1fc 2385 gcc_checking_assert (label < graph->size);
8a3fd8a7 2386
2387 if (graph->eq_rep[label] != -1)
2388 {
2389 /* Unify the two variables since we know they are equivalent. */
2390 if (unite (graph->eq_rep[label], node))
2391 unify_nodes (graph, graph->eq_rep[label], node, false);
2392 return graph->eq_rep[label];
2393 }
2394 else
2395 {
2396 graph->eq_rep[label] = node;
a6db8f14 2397 graph->pe_rep[label] = node;
8a3fd8a7 2398 }
2399 }
a6db8f14 2400 else
2401 {
6a5ca1fc 2402 gcc_checking_assert (label < graph->size);
a6db8f14 2403 graph->pe[node] = label;
2404 if (graph->pe_rep[label] == -1)
2405 graph->pe_rep[label] = node;
2406 }
2407
8a3fd8a7 2408 return node;
2409}
2410
a6db8f14 2411/* Unite pointer equivalent but not location equivalent nodes in
2412 GRAPH. This may only be performed once variable substitution is
2413 finished. */
2414
2415static void
2416unite_pointer_equivalences (constraint_graph_t graph)
2417{
2418 unsigned int i;
2419
2420 /* Go through the pointer equivalences and unite them to their
2421 representative, if they aren't already. */
5a950977 2422 for (i = 1; i < FIRST_REF_NODE; i++)
a6db8f14 2423 {
2424 unsigned int label = graph->pe[i];
765b6c4f 2425 if (label)
2426 {
2427 int label_rep = graph->pe_rep[label];
48e1416a 2428
765b6c4f 2429 if (label_rep == -1)
2430 continue;
48e1416a 2431
765b6c4f 2432 label_rep = find (label_rep);
2433 if (label_rep >= 0 && unite (label_rep, find (i)))
2434 unify_nodes (graph, label_rep, i, false);
2435 }
a6db8f14 2436 }
2437}
2438
2439/* Move complex constraints to the GRAPH nodes they belong to. */
8a3fd8a7 2440
2441static void
a6db8f14 2442move_complex_constraints (constraint_graph_t graph)
2443{
2444 int i;
2445 constraint_t c;
2446
f1f41a6c 2447 FOR_EACH_VEC_ELT (constraints, i, c)
a6db8f14 2448 {
2449 if (c)
2450 {
2451 struct constraint_expr lhs = c->lhs;
2452 struct constraint_expr rhs = c->rhs;
2453
2454 if (lhs.type == DEREF)
2455 {
2456 insert_into_complex (graph, lhs.var, c);
2457 }
2458 else if (rhs.type == DEREF)
2459 {
2460 if (!(get_varinfo (lhs.var)->is_special_var))
2461 insert_into_complex (graph, rhs.var, c);
2462 }
2463 else if (rhs.type != ADDRESSOF && lhs.var > anything_id
2464 && (lhs.offset != 0 || rhs.offset != 0))
2465 {
2466 insert_into_complex (graph, rhs.var, c);
2467 }
2468 }
2469 }
2470}
2471
2472
2473/* Optimize and rewrite complex constraints while performing
2474 collapsing of equivalent nodes. SI is the SCC_INFO that is the
2475 result of perform_variable_substitution. */
2476
2477static void
2478rewrite_constraints (constraint_graph_t graph,
2479 struct scc_info *si)
8a3fd8a7 2480{
2481 int i;
8a3fd8a7 2482 constraint_t c;
2483
6a5ca1fc 2484#ifdef ENABLE_CHECKING
2485 for (unsigned int j = 0; j < graph->size; j++)
8a3fd8a7 2486 gcc_assert (find (j) == j);
6a5ca1fc 2487#endif
8a3fd8a7 2488
f1f41a6c 2489 FOR_EACH_VEC_ELT (constraints, i, c)
8a3fd8a7 2490 {
2491 struct constraint_expr lhs = c->lhs;
2492 struct constraint_expr rhs = c->rhs;
dd277d48 2493 unsigned int lhsvar = find (lhs.var);
2494 unsigned int rhsvar = find (rhs.var);
8a3fd8a7 2495 unsigned int lhsnode, rhsnode;
2496 unsigned int lhslabel, rhslabel;
2497
2498 lhsnode = si->node_mapping[lhsvar];
2499 rhsnode = si->node_mapping[rhsvar];
a6db8f14 2500 lhslabel = graph->pointer_label[lhsnode];
2501 rhslabel = graph->pointer_label[rhsnode];
8a3fd8a7 2502
2503 /* See if it is really a non-pointer variable, and if so, ignore
2504 the constraint. */
2505 if (lhslabel == 0)
2506 {
765b6c4f 2507 if (dump_file && (dump_flags & TDF_DETAILS))
8a3fd8a7 2508 {
48e1416a 2509
765b6c4f 2510 fprintf (dump_file, "%s is a non-pointer variable,"
2511 "ignoring constraint:",
2512 get_varinfo (lhs.var)->name);
2513 dump_constraint (dump_file, c);
bbe0034f 2514 fprintf (dump_file, "\n");
8a3fd8a7 2515 }
f1f41a6c 2516 constraints[i] = NULL;
765b6c4f 2517 continue;
8a3fd8a7 2518 }
2519
2520 if (rhslabel == 0)
2521 {
765b6c4f 2522 if (dump_file && (dump_flags & TDF_DETAILS))
8a3fd8a7 2523 {
48e1416a 2524
765b6c4f 2525 fprintf (dump_file, "%s is a non-pointer variable,"
2526 "ignoring constraint:",
2527 get_varinfo (rhs.var)->name);
2528 dump_constraint (dump_file, c);
bbe0034f 2529 fprintf (dump_file, "\n");
8a3fd8a7 2530 }
f1f41a6c 2531 constraints[i] = NULL;
765b6c4f 2532 continue;
8a3fd8a7 2533 }
2534
2535 lhsvar = find_equivalent_node (graph, lhsvar, lhslabel);
2536 rhsvar = find_equivalent_node (graph, rhsvar, rhslabel);
2537 c->lhs.var = lhsvar;
2538 c->rhs.var = rhsvar;
8a3fd8a7 2539 }
2540}
2541
2542/* Eliminate indirect cycles involving NODE. Return true if NODE was
2543 part of an SCC, false otherwise. */
2544
2545static bool
2546eliminate_indirect_cycles (unsigned int node)
2547{
2548 if (graph->indirect_cycles[node] != -1
2549 && !bitmap_empty_p (get_varinfo (node)->solution))
2550 {
2551 unsigned int i;
1e094109 2552 vec<unsigned> queue = vNULL;
8a3fd8a7 2553 int queuepos;
2554 unsigned int to = find (graph->indirect_cycles[node]);
2555 bitmap_iterator bi;
2556
2557 /* We can't touch the solution set and call unify_nodes
2558 at the same time, because unify_nodes is going to do
2559 bitmap unions into it. */
2560
2561 EXECUTE_IF_SET_IN_BITMAP (get_varinfo (node)->solution, 0, i, bi)
2562 {
2563 if (find (i) == i && i != to)
2564 {
2565 if (unite (to, i))
f1f41a6c 2566 queue.safe_push (i);
8a3fd8a7 2567 }
2568 }
2569
2570 for (queuepos = 0;
f1f41a6c 2571 queue.iterate (queuepos, &i);
8a3fd8a7 2572 queuepos++)
2573 {
2574 unify_nodes (graph, to, i, true);
2575 }
f1f41a6c 2576 queue.release ();
8a3fd8a7 2577 return true;
2578 }
2579 return false;
29fd4364 2580}
2581
29fd4364 2582/* Solve the constraint graph GRAPH using our worklist solver.
2583 This is based on the PW* family of solvers from the "Efficient Field
2584 Sensitive Pointer Analysis for C" paper.
2585 It works by iterating over all the graph nodes, processing the complex
2586 constraints and propagating the copy constraints, until everything stops
2587 changed. This corresponds to steps 6-8 in the solving list given above. */
2588
2589static void
2590solve_graph (constraint_graph_t graph)
2591{
a6db8f14 2592 unsigned int size = graph->size;
29fd4364 2593 unsigned int i;
8a3fd8a7 2594 bitmap pts;
29fd4364 2595
b392ee8b 2596 changed = BITMAP_ALLOC (NULL);
7d1f52b2 2597
8a3fd8a7 2598 /* Mark all initial non-collapsed nodes as changed. */
5a950977 2599 for (i = 1; i < size; i++)
8a3fd8a7 2600 {
2601 varinfo_t ivi = get_varinfo (i);
2602 if (find (i) == i && !bitmap_empty_p (ivi->solution)
2603 && ((graph->succs[i] && !bitmap_empty_p (graph->succs[i]))
f1f41a6c 2604 || graph->complex[i].length () > 0))
b392ee8b 2605 bitmap_set_bit (changed, i);
8a3fd8a7 2606 }
2607
2608 /* Allocate a bitmap to be used to store the changed bits. */
2609 pts = BITMAP_ALLOC (&pta_obstack);
7d1f52b2 2610
b392ee8b 2611 while (!bitmap_empty_p (changed))
29fd4364 2612 {
2613 unsigned int i;
2614 struct topo_info *ti = init_topo_info ();
2615 stats.iterations++;
db026f5c 2616
29fd4364 2617 bitmap_obstack_initialize (&iteration_obstack);
7d1f52b2 2618
29fd4364 2619 compute_topo_order (graph, ti);
2620
f1f41a6c 2621 while (ti->topo_order.length () != 0)
29fd4364 2622 {
8a3fd8a7 2623
f1f41a6c 2624 i = ti->topo_order.pop ();
8a3fd8a7 2625
2626 /* If this variable is not a representative, skip it. */
2627 if (find (i) != i)
2628 continue;
2629
07cd0533 2630 /* In certain indirect cycle cases, we may merge this
2631 variable to another. */
d4473c84 2632 if (eliminate_indirect_cycles (i) && find (i) != i)
07cd0533 2633 continue;
29fd4364 2634
2635 /* If the node has changed, we need to process the
2636 complex constraints and outgoing edges again. */
b392ee8b 2637 if (bitmap_clear_bit (changed, i))
29fd4364 2638 {
2639 unsigned int j;
2640 constraint_t c;
29fd4364 2641 bitmap solution;
f1f41a6c 2642 vec<constraint_t> complex = graph->complex[i];
8b3ad377 2643 varinfo_t vi = get_varinfo (i);
499be8ef 2644 bool solution_empty;
c2bed432 2645
5a950977 2646 /* Compute the changed set of solution bits. If anything
2647 is in the solution just propagate that. */
2648 if (bitmap_bit_p (vi->solution, anything_id))
2649 {
2650 /* If anything is also in the old solution there is
2651 nothing to do.
2652 ??? But we shouldn't ended up with "changed" set ... */
2653 if (vi->oldsolution
2654 && bitmap_bit_p (vi->oldsolution, anything_id))
2655 continue;
2656 bitmap_copy (pts, get_varinfo (find (anything_id))->solution);
2657 }
2658 else if (vi->oldsolution)
8b3ad377 2659 bitmap_and_compl (pts, vi->solution, vi->oldsolution);
2660 else
2661 bitmap_copy (pts, vi->solution);
8a3fd8a7 2662
2663 if (bitmap_empty_p (pts))
2664 continue;
2665
8b3ad377 2666 if (vi->oldsolution)
2667 bitmap_ior_into (vi->oldsolution, pts);
2668 else
2669 {
2670 vi->oldsolution = BITMAP_ALLOC (&oldpta_obstack);
2671 bitmap_copy (vi->oldsolution, pts);
2672 }
8a3fd8a7 2673
8b3ad377 2674 solution = vi->solution;
499be8ef 2675 solution_empty = bitmap_empty_p (solution);
2676
2677 /* Process the complex constraints */
f1f41a6c 2678 FOR_EACH_VEC_ELT (complex, j, c)
499be8ef 2679 {
a6db8f14 2680 /* XXX: This is going to unsort the constraints in
2681 some cases, which will occasionally add duplicate
2682 constraints during unification. This does not
2683 affect correctness. */
2684 c->lhs.var = find (c->lhs.var);
2685 c->rhs.var = find (c->rhs.var);
2686
499be8ef 2687 /* The only complex constraint that can change our
2688 solution to non-empty, given an empty solution,
2689 is a constraint where the lhs side is receiving
2690 some set from elsewhere. */
2691 if (!solution_empty || c->lhs.type != DEREF)
8a3fd8a7 2692 do_complex_constraint (graph, c, pts);
499be8ef 2693 }
29fd4364 2694
499be8ef 2695 solution_empty = bitmap_empty_p (solution);
2696
dd277d48 2697 if (!solution_empty)
db026f5c 2698 {
8a3fd8a7 2699 bitmap_iterator bi;
dd277d48 2700 unsigned eff_escaped_id = find (escaped_id);
8a3fd8a7 2701
499be8ef 2702 /* Propagate solution to all successors. */
7d1f52b2 2703 EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i],
499be8ef 2704 0, j, bi)
db026f5c 2705 {
8a3fd8a7 2706 bitmap tmp;
2707 bool flag;
2708
2709 unsigned int to = find (j);
2710 tmp = get_varinfo (to)->solution;
2711 flag = false;
7d1f52b2 2712
8a3fd8a7 2713 /* Don't try to propagate to ourselves. */
2714 if (to == i)
2715 continue;
7d1f52b2 2716
dd277d48 2717 /* If we propagate from ESCAPED use ESCAPED as
2718 placeholder. */
2719 if (i == eff_escaped_id)
2720 flag = bitmap_set_bit (tmp, escaped_id);
2721 else
5a950977 2722 flag = bitmap_ior_into (tmp, pts);
7d1f52b2 2723
499be8ef 2724 if (flag)
5a950977 2725 bitmap_set_bit (changed, to);
db026f5c 2726 }
29fd4364 2727 }
2728 }
2729 }
2730 free_topo_info (ti);
2731 bitmap_obstack_release (&iteration_obstack);
2732 }
7d1f52b2 2733
8a3fd8a7 2734 BITMAP_FREE (pts);
b392ee8b 2735 BITMAP_FREE (changed);
8a3fd8a7 2736 bitmap_obstack_release (&oldpta_obstack);
29fd4364 2737}
2738
8a3fd8a7 2739/* Map from trees to variable infos. */
b30a8715 2740static struct pointer_map_t *vi_for_tree;
29fd4364 2741
29fd4364 2742
b30a8715 2743/* Insert ID as the variable id for tree T in the vi_for_tree map. */
29fd4364 2744
7d1f52b2 2745static void
8a3fd8a7 2746insert_vi_for_tree (tree t, varinfo_t vi)
29fd4364 2747{
b30a8715 2748 void **slot = pointer_map_insert (vi_for_tree, t);
2749 gcc_assert (vi);
29fd4364 2750 gcc_assert (*slot == NULL);
b30a8715 2751 *slot = vi;
29fd4364 2752}
2753
8a3fd8a7 2754/* Find the variable info for tree T in VI_FOR_TREE. If T does not
b30a8715 2755 exist in the map, return NULL, otherwise, return the varinfo we found. */
29fd4364 2756
b30a8715 2757static varinfo_t
2758lookup_vi_for_tree (tree t)
29fd4364 2759{
b30a8715 2760 void **slot = pointer_map_contains (vi_for_tree, t);
2761 if (slot == NULL)
2762 return NULL;
29fd4364 2763
b30a8715 2764 return (varinfo_t) *slot;
29fd4364 2765}
2766
2767/* Return a printable name for DECL */
2768
2769static const char *
2770alias_get_name (tree decl)
2771{
ec11736b 2772 const char *res = NULL;
29fd4364 2773 char *temp;
2774 int num_printed = 0;
2775
a04b3e37 2776 if (!dump_file)
ec11736b 2777 return "NULL";
a04b3e37 2778
29fd4364 2779 if (TREE_CODE (decl) == SSA_NAME)
2780 {
ec11736b 2781 res = get_name (decl);
2782 if (res)
2783 num_printed = asprintf (&temp, "%s_%u", res, SSA_NAME_VERSION (decl));
2784 else
2785 num_printed = asprintf (&temp, "_%u", SSA_NAME_VERSION (decl));
2786 if (num_printed > 0)
2787 {
2788 res = ggc_strdup (temp);
2789 free (temp);
2790 }
29fd4364 2791 }
2792 else if (DECL_P (decl))
2793 {
ec11736b 2794 if (DECL_ASSEMBLER_NAME_SET_P (decl))
2795 res = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
2796 else
2797 {
2798 res = get_name (decl);
2799 if (!res)
2800 {
2801 num_printed = asprintf (&temp, "D.%u", DECL_UID (decl));
2802 if (num_printed > 0)
2803 {
2804 res = ggc_strdup (temp);
2805 free (temp);
2806 }
2807 }
2808 }
29fd4364 2809 }
ec11736b 2810 if (res != NULL)
2811 return res;
2812
2813 return "NULL";
29fd4364 2814}
2815
b30a8715 2816/* Find the variable id for tree T in the map.
2817 If T doesn't exist in the map, create an entry for it and return it. */
29fd4364 2818
8a3fd8a7 2819static varinfo_t
2820get_vi_for_tree (tree t)
29fd4364 2821{
b30a8715 2822 void **slot = pointer_map_contains (vi_for_tree, t);
2823 if (slot == NULL)
8a3fd8a7 2824 return get_varinfo (create_variable_info_for (t, alias_get_name (t)));
7d1f52b2 2825
b30a8715 2826 return (varinfo_t) *slot;
29fd4364 2827}
2828
c2abd8e4 2829/* Get a scalar constraint expression for a new temporary variable. */
29fd4364 2830
2831static struct constraint_expr
c2abd8e4 2832new_scalar_tmp_constraint_exp (const char *name)
29fd4364 2833{
c2abd8e4 2834 struct constraint_expr tmp;
c2abd8e4 2835 varinfo_t vi;
29fd4364 2836
97709d23 2837 vi = new_var_info (NULL_TREE, name);
c2abd8e4 2838 vi->offset = 0;
2839 vi->size = -1;
2840 vi->fullsize = -1;
2841 vi->is_full_var = 1;
79520942 2842
c2abd8e4 2843 tmp.var = vi->id;
2844 tmp.type = SCALAR;
2845 tmp.offset = 0;
79520942 2846
c2abd8e4 2847 return tmp;
79520942 2848}
2849
2850/* Get a constraint expression vector from an SSA_VAR_P node.
2851 If address_p is true, the result will be taken its address of. */
2852
2853static void
f1f41a6c 2854get_constraint_for_ssa_var (tree t, vec<ce_s> *results, bool address_p)
79520942 2855{
2856 struct constraint_expr cexpr;
2857 varinfo_t vi;
2858
2859 /* We allow FUNCTION_DECLs here even though it doesn't make much sense. */
3b652cc1 2860 gcc_assert (TREE_CODE (t) == SSA_NAME || DECL_P (t));
29fd4364 2861
2862 /* For parameters, get at the points-to set for the actual parm
2863 decl. */
7d1f52b2 2864 if (TREE_CODE (t) == SSA_NAME
3b652cc1 2865 && SSA_NAME_IS_DEFAULT_DEF (t)
524a0531 2866 && (TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL
3b652cc1 2867 || TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL))
79520942 2868 {
2869 get_constraint_for_ssa_var (SSA_NAME_VAR (t), results, address_p);
2870 return;
2871 }
29fd4364 2872
8c4a7fb7 2873 /* For global variables resort to the alias target. */
2874 if (TREE_CODE (t) == VAR_DECL
2875 && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
2876 {
2877 struct varpool_node *node = varpool_get_node (t);
15ca8f90 2878 if (node && node->symbol.alias && node->symbol.analyzed)
8c4a7fb7 2879 {
2880 node = varpool_variable_node (node, NULL);
7d0d0ce1 2881 t = node->symbol.decl;
8c4a7fb7 2882 }
2883 }
2884
79520942 2885 vi = get_vi_for_tree (t);
2886 cexpr.var = vi->id;
29fd4364 2887 cexpr.type = SCALAR;
79520942 2888 cexpr.offset = 0;
232a3153 2889 /* If we determine the result is "anything", and we know this is readonly,
2890 say it points to readonly memory instead. */
2891 if (cexpr.var == anything_id && TREE_READONLY (t))
29fd4364 2892 {
79520942 2893 gcc_unreachable ();
8a3fd8a7 2894 cexpr.type = ADDRESSOF;
29fd4364 2895 cexpr.var = readonly_id;
2896 }
7d1f52b2 2897
79520942 2898 /* If we are not taking the address of the constraint expr, add all
2899 sub-fiels of the variable as well. */
4bfcb72d 2900 if (!address_p
2901 && !vi->is_full_var)
79520942 2902 {
5a950977 2903 for (; vi; vi = vi_next (vi))
79520942 2904 {
2905 cexpr.var = vi->id;
f1f41a6c 2906 results->safe_push (cexpr);
79520942 2907 }
2908 return;
2909 }
2910
f1f41a6c 2911 results->safe_push (cexpr);
29fd4364 2912}
2913
339d7079 2914/* Process constraint T, performing various simplifications and then
2915 adding it to our list of overall constraints. */
29fd4364 2916
2917static void
339d7079 2918process_constraint (constraint_t t)
29fd4364 2919{
2920 struct constraint_expr rhs = t->rhs;
2921 struct constraint_expr lhs = t->lhs;
7d1f52b2 2922
f1f41a6c 2923 gcc_assert (rhs.var < varmap.length ());
2924 gcc_assert (lhs.var < varmap.length ());
29fd4364 2925
dd277d48 2926 /* If we didn't get any useful constraint from the lhs we get
2927 &ANYTHING as fallback from get_constraint_for. Deal with
2928 it here by turning it into *ANYTHING. */
2929 if (lhs.type == ADDRESSOF
2930 && lhs.var == anything_id)
2931 lhs.type = DEREF;
2932
2933 /* ADDRESSOF on the lhs is invalid. */
2934 gcc_assert (lhs.type != ADDRESSOF);
29fd4364 2935
e1148535 2936 /* We shouldn't add constraints from things that cannot have pointers.
2937 It's not completely trivial to avoid in the callers, so do it here. */
2938 if (rhs.type != ADDRESSOF
2939 && !get_varinfo (rhs.var)->may_have_pointers)
2940 return;
2941
2942 /* Likewise adding to the solution of a non-pointer var isn't useful. */
2943 if (!get_varinfo (lhs.var)->may_have_pointers)
2944 return;
2945
29fd4364 2946 /* This can happen in our IR with things like n->a = *p */
dd277d48 2947 if (rhs.type == DEREF && lhs.type == DEREF && rhs.var != anything_id)
29fd4364 2948 {
2949 /* Split into tmp = *rhs, *lhs = tmp */
c2abd8e4 2950 struct constraint_expr tmplhs;
2951 tmplhs = new_scalar_tmp_constraint_exp ("doubledereftmp");
339d7079 2952 process_constraint (new_constraint (tmplhs, rhs));
2953 process_constraint (new_constraint (lhs, tmplhs));
a6db8f14 2954 }
2955 else if (rhs.type == ADDRESSOF && lhs.type == DEREF)
2956 {
2957 /* Split into tmp = &rhs, *lhs = tmp */
c2abd8e4 2958 struct constraint_expr tmplhs;
2959 tmplhs = new_scalar_tmp_constraint_exp ("derefaddrtmp");
339d7079 2960 process_constraint (new_constraint (tmplhs, rhs));
2961 process_constraint (new_constraint (lhs, tmplhs));
29fd4364 2962 }
29fd4364 2963 else
2964 {
8a3fd8a7 2965 gcc_assert (rhs.type != ADDRESSOF || rhs.offset == 0);
f1f41a6c 2966 constraints.safe_push (t);
29fd4364 2967 }
2968}
2969
2970
2971/* Return the position, in bits, of FIELD_DECL from the beginning of its
2972 structure. */
2973
9bdfd02b 2974static HOST_WIDE_INT
29fd4364 2975bitpos_of_field (const tree fdecl)
2976{
9bdfd02b 2977 if (!host_integerp (DECL_FIELD_OFFSET (fdecl), 0)
2978 || !host_integerp (DECL_FIELD_BIT_OFFSET (fdecl), 0))
29fd4364 2979 return -1;
7d1f52b2 2980
02b63808 2981 return (TREE_INT_CST_LOW (DECL_FIELD_OFFSET (fdecl)) * BITS_PER_UNIT
9bdfd02b 2982 + TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fdecl)));
29fd4364 2983}
2984
2985
57e6b870 2986/* Get constraint expressions for offsetting PTR by OFFSET. Stores the
2987 resulting constraint expressions in *RESULTS. */
2988
2989static void
2990get_constraint_for_ptr_offset (tree ptr, tree offset,
f1f41a6c 2991 vec<ce_s> *results)
57e6b870 2992{
543681ac 2993 struct constraint_expr c;
57e6b870 2994 unsigned int j, n;
2ad5f5fc 2995 HOST_WIDE_INT rhsoffset;
57e6b870 2996
2997 /* If we do not do field-sensitive PTA adding offsets to pointers
2998 does not change the points-to solution. */
2999 if (!use_field_sensitive)
3000 {
59b12eb5 3001 get_constraint_for_rhs (ptr, results);
57e6b870 3002 return;
3003 }
3004
3005 /* If the offset is not a non-negative integer constant that fits
3006 in a HOST_WIDE_INT, we have to fall back to a conservative
3007 solution which includes all sub-fields of all pointed-to
dd277d48 3008 variables of ptr. */
047fdd47 3009 if (offset == NULL_TREE
2ad5f5fc 3010 || TREE_CODE (offset) != INTEGER_CST)
dd277d48 3011 rhsoffset = UNKNOWN_OFFSET;
3012 else
57e6b870 3013 {
2ad5f5fc 3014 /* Sign-extend the offset. */
cf8f0e63 3015 double_int soffset = tree_to_double_int (offset)
3016 .sext (TYPE_PRECISION (TREE_TYPE (offset)));
3017 if (!soffset.fits_shwi ())
dd277d48 3018 rhsoffset = UNKNOWN_OFFSET;
2ad5f5fc 3019 else
3020 {
3021 /* Make sure the bit-offset also fits. */
3022 HOST_WIDE_INT rhsunitoffset = soffset.low;
3023 rhsoffset = rhsunitoffset * BITS_PER_UNIT;
3024 if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
3025 rhsoffset = UNKNOWN_OFFSET;
3026 }
57e6b870 3027 }
3028
59b12eb5 3029 get_constraint_for_rhs (ptr, results);
57e6b870 3030 if (rhsoffset == 0)
3031 return;
3032
3033 /* As we are eventually appending to the solution do not use
f1f41a6c 3034 vec::iterate here. */
3035 n = results->length ();
57e6b870 3036 for (j = 0; j < n; j++)
3037 {
3038 varinfo_t curr;
f1f41a6c 3039 c = (*results)[j];
543681ac 3040 curr = get_varinfo (c.var);
57e6b870 3041
543681ac 3042 if (c.type == ADDRESSOF
dd277d48 3043 /* If this varinfo represents a full variable just use it. */
3044 && curr->is_full_var)
543681ac 3045 c.offset = 0;
3046 else if (c.type == ADDRESSOF
dd277d48 3047 /* If we do not know the offset add all subfields. */
3048 && rhsoffset == UNKNOWN_OFFSET)
3049 {
5a950977 3050 varinfo_t temp = get_varinfo (curr->head);
dd277d48 3051 do
3052 {
3053 struct constraint_expr c2;
3054 c2.var = temp->id;
3055 c2.type = ADDRESSOF;
3056 c2.offset = 0;
543681ac 3057 if (c2.var != c.var)
f1f41a6c 3058 results->safe_push (c2);
5a950977 3059 temp = vi_next (temp);
dd277d48 3060 }
3061 while (temp);
3062 }
543681ac 3063 else if (c.type == ADDRESSOF)
57e6b870 3064 {
dd277d48 3065 varinfo_t temp;
3066 unsigned HOST_WIDE_INT offset = curr->offset + rhsoffset;
57e6b870 3067
3068 /* Search the sub-field which overlaps with the
dd277d48 3069 pointed-to offset. If the result is outside of the variable
3070 we have to provide a conservative result, as the variable is
3071 still reachable from the resulting pointer (even though it
3072 technically cannot point to anything). The last and first
3073 sub-fields are such conservative results.
57e6b870 3074 ??? If we always had a sub-field for &object + 1 then
3075 we could represent this in a more precise way. */
dd277d48 3076 if (rhsoffset < 0
3077 && curr->offset < offset)
3078 offset = 0;
3079 temp = first_or_preceding_vi_for_offset (curr, offset);
57e6b870 3080
3081 /* If the found variable is not exactly at the pointed to
3082 result, we have to include the next variable in the
3083 solution as well. Otherwise two increments by offset / 2
3084 do not result in the same or a conservative superset
3085 solution. */
dd277d48 3086 if (temp->offset != offset
5a950977 3087 && temp->next != 0)
57e6b870 3088 {
3089 struct constraint_expr c2;
5a950977 3090 c2.var = temp->next;
57e6b870 3091 c2.type = ADDRESSOF;
3092 c2.offset = 0;
f1f41a6c 3093 results->safe_push (c2);
57e6b870 3094 }
543681ac 3095 c.var = temp->id;
3096 c.offset = 0;
57e6b870 3097 }
57e6b870 3098 else
543681ac 3099 c.offset = rhsoffset;
3100
f1f41a6c 3101 (*results)[j] = c;
57e6b870 3102 }
3103}
3104
3105
79520942 3106/* Given a COMPONENT_REF T, return the constraint_expr vector for it.
59b12eb5 3107 If address_p is true the result will be taken its address of.
3108 If lhs_p is true then the constraint expression is assumed to be used
3109 as the lhs. */
29fd4364 3110
db026f5c 3111static void
f1f41a6c 3112get_constraint_for_component_ref (tree t, vec<ce_s> *results,
59b12eb5 3113 bool address_p, bool lhs_p)
29fd4364 3114{
db026f5c 3115 tree orig_t = t;
d0186307 3116 HOST_WIDE_INT bitsize = -1;
3fefae7a 3117 HOST_WIDE_INT bitmaxsize = -1;
29fd4364 3118 HOST_WIDE_INT bitpos;
29fd4364 3119 tree forzero;
29fd4364 3120
3121 /* Some people like to do cute things like take the address of
3122 &0->a.b */
3123 forzero = t;
7f2d9047 3124 while (handled_component_p (forzero)
182cf5a9 3125 || INDIRECT_REF_P (forzero)
3126 || TREE_CODE (forzero) == MEM_REF)
db026f5c 3127 forzero = TREE_OPERAND (forzero, 0);
29fd4364 3128
7d1f52b2 3129 if (CONSTANT_CLASS_P (forzero) && integer_zerop (forzero))
29fd4364 3130 {
db026f5c 3131 struct constraint_expr temp;
7d1f52b2 3132
db026f5c 3133 temp.offset = 0;
3134 temp.var = integer_id;
3135 temp.type = SCALAR;
f1f41a6c 3136 results->safe_push (temp);
db026f5c 3137 return;
29fd4364 3138 }
7d1f52b2 3139
59b12eb5 3140 /* Handle type-punning through unions. If we are extracting a pointer
3141 from a union via a possibly type-punning access that pointer
3142 points to anything, similar to a conversion of an integer to
3143 a pointer. */
3144 if (!lhs_p)
3145 {
3146 tree u;
3147 for (u = t;
3148 TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF;
3149 u = TREE_OPERAND (u, 0))
3150 if (TREE_CODE (u) == COMPONENT_REF
3151 && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
3152 {
3153 struct constraint_expr temp;
3154
3155 temp.offset = 0;
3156 temp.var = anything_id;
3157 temp.type = ADDRESSOF;
f1f41a6c 3158 results->safe_push (temp);
59b12eb5 3159 return;
3160 }
3161 }
3162
3fefae7a 3163 t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize);
499be8ef 3164
79520942 3165 /* Pretend to take the address of the base, we'll take care of
3166 adding the required subset of sub-fields below. */
59b12eb5 3167 get_constraint_for_1 (t, results, true, lhs_p);
f1f41a6c 3168 gcc_assert (results->length () == 1);
3169 struct constraint_expr &result = results->last ();
29fd4364 3170
f1f41a6c 3171 if (result.type == SCALAR
3172 && get_varinfo (result.var)->is_full_var)
57e6b870 3173 /* For single-field vars do not bother about the offset. */
f1f41a6c 3174 result.offset = 0;
3175 else if (result.type == SCALAR)
29fd4364 3176 {
3177 /* In languages like C, you can access one past the end of an
3178 array. You aren't allowed to dereference it, so we can
3179 ignore this constraint. When we handle pointer subtraction,
3180 we may have to do something cute here. */
7d1f52b2 3181
f1f41a6c 3182 if ((unsigned HOST_WIDE_INT)bitpos < get_varinfo (result.var)->fullsize
1b2f34a9 3183 && bitmaxsize != 0)
fa39d520 3184 {
3185 /* It's also not true that the constraint will actually start at the
3186 right offset, it may start in some padding. We only care about
3187 setting the constraint to the first actual field it touches, so
7d1f52b2 3188 walk to find it. */
f1f41a6c 3189 struct constraint_expr cexpr = result;
fa39d520 3190 varinfo_t curr;
f1f41a6c 3191 results->pop ();
79520942 3192 cexpr.offset = 0;
5a950977 3193 for (curr = get_varinfo (cexpr.var); curr; curr = vi_next (curr))
fa39d520 3194 {
a306ee43 3195 if (ranges_overlap_p (curr->offset, curr->size,
79520942 3196 bitpos, bitmaxsize))
fa39d520 3197 {
79520942 3198 cexpr.var = curr->id;
f1f41a6c 3199 results->safe_push (cexpr);
79520942 3200 if (address_p)
3201 break;
fa39d520 3202 }
3203 }
57e6b870 3204 /* If we are going to take the address of this field then
3205 to be able to compute reachability correctly add at least
3206 the last field of the variable. */
f1f41a6c 3207 if (address_p && results->length () == 0)
57e6b870 3208 {
3209 curr = get_varinfo (cexpr.var);
5a950977 3210 while (curr->next != 0)
3211 curr = vi_next (curr);
57e6b870 3212 cexpr.var = curr->id;
f1f41a6c 3213 results->safe_push (cexpr);
57e6b870 3214 }
f1f41a6c 3215 else if (results->length () == 0)
57e6b870 3216 /* Assert that we found *some* field there. The user couldn't be
3217 accessing *only* padding. */
3218 /* Still the user could access one past the end of an array
3219 embedded in a struct resulting in accessing *only* padding. */
0b37d5ec 3220 /* Or accessing only padding via type-punning to a type
3221 that has a filed just in padding space. */
3222 {
3223 cexpr.type = SCALAR;
3224 cexpr.var = anything_id;
3225 cexpr.offset = 0;
f1f41a6c 3226 results->safe_push (cexpr);
0b37d5ec 3227 }
fa39d520 3228 }
1b2f34a9 3229 else if (bitmaxsize == 0)
3230 {
3231 if (dump_file && (dump_flags & TDF_DETAILS))
3232 fprintf (dump_file, "Access to zero-sized part of variable,"
3233 "ignoring\n");
3234 }
29fd4364 3235 else
3236 if (dump_file && (dump_flags & TDF_DETAILS))
3237 fprintf (dump_file, "Access to past the end of variable, ignoring\n");
29fd4364 3238 }
f1f41a6c 3239 else if (result.type == DEREF)
a6db8f14 3240 {
dd277d48 3241 /* If we do not know exactly where the access goes say so. Note
3242 that only for non-structure accesses we know that we access
3243 at most one subfiled of any variable. */
3244 if (bitpos == -1
3245 || bitsize != bitmaxsize
726c2801 3246 || AGGREGATE_TYPE_P (TREE_TYPE (orig_t))
f1f41a6c 3247 || result.offset == UNKNOWN_OFFSET)
3248 result.offset = UNKNOWN_OFFSET;
dd277d48 3249 else
f1f41a6c 3250 result.offset += bitpos;
a6db8f14 3251 }
f1f41a6c 3252 else if (result.type == ADDRESSOF)
af4c7413 3253 {
3254 /* We can end up here for component references on a
3255 VIEW_CONVERT_EXPR <>(&foobar). */
f1f41a6c 3256 result.type = SCALAR;
3257 result.var = anything_id;
3258 result.offset = 0;
af4c7413 3259 }
79520942 3260 else
dd277d48 3261 gcc_unreachable ();
29fd4364 3262}
3263
3264
3265/* Dereference the constraint expression CONS, and return the result.
3266 DEREF (ADDRESSOF) = SCALAR
3267 DEREF (SCALAR) = DEREF
3268 DEREF (DEREF) = (temp = DEREF1; result = DEREF(temp))
3269 This is needed so that we can handle dereferencing DEREF constraints. */
3270
db026f5c 3271static void
f1f41a6c 3272do_deref (vec<ce_s> *constraints)
29fd4364 3273{
db026f5c 3274 struct constraint_expr *c;
3275 unsigned int i = 0;
7d1f52b2 3276
f1f41a6c 3277 FOR_EACH_VEC_ELT (*constraints, i, c)
29fd4364 3278 {
db026f5c 3279 if (c->type == SCALAR)
3280 c->type = DEREF;
3281 else if (c->type == ADDRESSOF)
3282 c->type = SCALAR;
3283 else if (c->type == DEREF)
3284 {
c2abd8e4 3285 struct constraint_expr tmplhs;
3286 tmplhs = new_scalar_tmp_constraint_exp ("dereftmp");
db026f5c 3287 process_constraint (new_constraint (tmplhs, *c));
3288 c->var = tmplhs.var;
3289 }
3290 else
3291 gcc_unreachable ();
29fd4364 3292 }
29fd4364 3293}
3294
60b9b3ae 3295/* Given a tree T, return the constraint expression for taking the
3296 address of it. */
3297
3298static void
f1f41a6c 3299get_constraint_for_address_of (tree t, vec<ce_s> *results)
60b9b3ae 3300{
3301 struct constraint_expr *c;
3302 unsigned int i;
3303
59b12eb5 3304 get_constraint_for_1 (t, results, true, true);
60b9b3ae 3305
f1f41a6c 3306 FOR_EACH_VEC_ELT (*results, i, c)
60b9b3ae 3307 {
3308 if (c->type == DEREF)
3309 c->type = SCALAR;
3310 else
3311 c->type = ADDRESSOF;
3312 }
3313}
3314
29fd4364 3315/* Given a tree T, return the constraint expression for it. */
3316
db026f5c 3317static void
f1f41a6c 3318get_constraint_for_1 (tree t, vec<ce_s> *results, bool address_p,
59b12eb5 3319 bool lhs_p)
29fd4364 3320{
3321 struct constraint_expr temp;
3322
3323 /* x = integer is all glommed to a single variable, which doesn't
3324 point to anything by itself. That is, of course, unless it is an
3325 integer constant being treated as a pointer, in which case, we
3326 will return that this is really the addressof anything. This
3327 happens below, since it will fall into the default case. The only
3328 case we know something about an integer treated like a pointer is
3329 when it is the NULL pointer, and then we just say it points to
7f70ef19 3330 NULL.
3331
3332 Do not do that if -fno-delete-null-pointer-checks though, because
3333 in that case *NULL does not fail, so it _should_ alias *anything.
3334 It is not worth adding a new option or renaming the existing one,
3335 since this case is relatively obscure. */
650b60e8 3336 if ((TREE_CODE (t) == INTEGER_CST
3337 && integer_zerop (t))
3338 /* The only valid CONSTRUCTORs in gimple with pointer typed
3339 elements are zero-initializer. But in IPA mode we also
3340 process global initializers, so verify at least. */
3341 || (TREE_CODE (t) == CONSTRUCTOR
3342 && CONSTRUCTOR_NELTS (t) == 0))
3343 {
3344 if (flag_delete_null_pointer_checks)
3345 temp.var = nothing_id;
3346 else
b55fb358 3347 temp.var = nonlocal_id;
29fd4364 3348 temp.type = ADDRESSOF;
3349 temp.offset = 0;
f1f41a6c 3350 results->safe_push (temp);
db026f5c 3351 return;
29fd4364 3352 }
3353
220322c1 3354 /* String constants are read-only. */
3355 if (TREE_CODE (t) == STRING_CST)
3356 {
3357 temp.var = readonly_id;
3358 temp.type = SCALAR;
3359 temp.offset = 0;
f1f41a6c 3360 results->safe_push (temp);
220322c1 3361 return;
3362 }
3363
29fd4364 3364 switch (TREE_CODE_CLASS (TREE_CODE (t)))
3365 {
3366 case tcc_expression:
3367 {
3368 switch (TREE_CODE (t))
3369 {
3370 case ADDR_EXPR:
60b9b3ae 3371 get_constraint_for_address_of (TREE_OPERAND (t, 0), results);
3372 return;
57e6b870 3373 default:;
29fd4364 3374 }
57e6b870 3375 break;
29fd4364 3376 }
3377 case tcc_reference:
3378 {
3379 switch (TREE_CODE (t))
3380 {
182cf5a9 3381 case MEM_REF:
29fd4364 3382 {
726308b5 3383 struct constraint_expr cs;
565bef3b 3384 varinfo_t vi, curr;
2ad5f5fc 3385 get_constraint_for_ptr_offset (TREE_OPERAND (t, 0),
3386 TREE_OPERAND (t, 1), results);
db026f5c 3387 do_deref (results);
565bef3b 3388
3389 /* If we are not taking the address then make sure to process
3390 all subvariables we might access. */
9dd84951 3391 if (address_p)
3392 return;
3393
f1f41a6c 3394 cs = results->last ();
b4c39a37 3395 if (cs.type == DEREF
3396 && type_can_have_subvars (TREE_TYPE (t)))
9dd84951 3397 {
3398 /* For dereferences this means we have to defer it
3399 to solving time. */
f1f41a6c 3400 results->last ().offset = UNKNOWN_OFFSET;
9dd84951 3401 return;
3402 }
3403 if (cs.type != SCALAR)
565bef3b 3404 return;
3405
726308b5 3406 vi = get_varinfo (cs.var);
5a950977 3407 curr = vi_next (vi);
565bef3b 3408 if (!vi->is_full_var
3409 && curr)
3410 {
3411 unsigned HOST_WIDE_INT size;
3412 if (host_integerp (TYPE_SIZE (TREE_TYPE (t)), 1))
3413 size = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (t)));
3414 else
3415 size = -1;
5a950977 3416 for (; curr; curr = vi_next (curr))
565bef3b 3417 {
3418 if (curr->offset - vi->offset < size)
3419 {
565bef3b 3420 cs.var = curr->id;
f1f41a6c 3421 results->safe_push (cs);
565bef3b 3422 }
3423 else
3424 break;
3425 }
3426 }
db026f5c 3427 return;
29fd4364 3428 }
3429 case ARRAY_REF:
629b962c 3430 case ARRAY_RANGE_REF:
29fd4364 3431 case COMPONENT_REF:
59b12eb5 3432 get_constraint_for_component_ref (t, results, address_p, lhs_p);
db026f5c 3433 return;
dd277d48 3434 case VIEW_CONVERT_EXPR:
59b12eb5 3435 get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p,
3436 lhs_p);
dd277d48 3437 return;
3438 /* We are missing handling for TARGET_MEM_REF here. */
57e6b870 3439 default:;
29fd4364 3440 }
57e6b870 3441 break;
29fd4364 3442 }
29fd4364 3443 case tcc_exceptional:
3444 {
3445 switch (TREE_CODE (t))
3446 {
29fd4364 3447 case SSA_NAME:
db026f5c 3448 {
79520942 3449 get_constraint_for_ssa_var (t, results, address_p);
db026f5c 3450 return;
3451 }
61cf0658 3452 case CONSTRUCTOR:
3453 {
3454 unsigned int i;
3455 tree val;
1e094109 3456 vec<ce_s> tmp = vNULL;
61cf0658 3457 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, val)
3458 {
3459 struct constraint_expr *rhsp;
3460 unsigned j;
59b12eb5 3461 get_constraint_for_1 (val, &tmp, address_p, lhs_p);
f1f41a6c 3462 FOR_EACH_VEC_ELT (tmp, j, rhsp)
3463 results->safe_push (*rhsp);
3464 tmp.truncate (0);
61cf0658 3465 }
f1f41a6c 3466 tmp.release ();
61cf0658 3467 /* We do not know whether the constructor was complete,
3468 so technically we have to add &NOTHING or &ANYTHING
3469 like we do for an empty constructor as well. */
3470 return;
3471 }
57e6b870 3472 default:;
29fd4364 3473 }
57e6b870 3474 break;
29fd4364 3475 }
3476 case tcc_declaration:
db026f5c 3477 {
79520942 3478 get_constraint_for_ssa_var (t, results, address_p);
db026f5c 3479 return;
3480 }
b55fb358 3481 case tcc_constant:
3482 {
3483 /* We cannot refer to automatic variables through constants. */
3484 temp.type = ADDRESSOF;
3485 temp.var = nonlocal_id;
3486 temp.offset = 0;
f1f41a6c 3487 results->safe_push (temp);
b55fb358 3488 return;
3489 }
57e6b870 3490 default:;
29fd4364 3491 }
57e6b870 3492
3493 /* The default fallback is a constraint from anything. */
3494 temp.type = ADDRESSOF;
3495 temp.var = anything_id;
3496 temp.offset = 0;
f1f41a6c 3497 results->safe_push (temp);
29fd4364 3498}
3499
79520942 3500/* Given a gimple tree T, return the constraint expression vector for it. */
3501
3502static void
f1f41a6c 3503get_constraint_for (tree t, vec<ce_s> *results)
79520942 3504{
f1f41a6c 3505 gcc_assert (results->length () == 0);
79520942 3506
59b12eb5 3507 get_constraint_for_1 (t, results, false, true);
3508}
3509
3510/* Given a gimple tree T, return the constraint expression vector for it
3511 to be used as the rhs of a constraint. */
3512
3513static void
f1f41a6c 3514get_constraint_for_rhs (tree t, vec<ce_s> *results)
59b12eb5 3515{
f1f41a6c 3516 gcc_assert (results->length () == 0);
59b12eb5 3517
3518 get_constraint_for_1 (t, results, false, false);
79520942 3519}
29fd4364 3520
047fdd47 3521
3522/* Efficiently generates constraints from all entries in *RHSC to all
3523 entries in *LHSC. */
3524
3525static void
f1f41a6c 3526process_all_all_constraints (vec<ce_s> lhsc,
3527 vec<ce_s> rhsc)
047fdd47 3528{
3529 struct constraint_expr *lhsp, *rhsp;
3530 unsigned i, j;
3531
f1f41a6c 3532 if (lhsc.length () <= 1 || rhsc.length () <= 1)
047fdd47 3533 {
f1f41a6c 3534 FOR_EACH_VEC_ELT (lhsc, i, lhsp)
3535 FOR_EACH_VEC_ELT (rhsc, j, rhsp)
047fdd47 3536 process_constraint (new_constraint (*lhsp, *rhsp));
3537 }
3538 else
3539 {
3540 struct constraint_expr tmp;
c2abd8e4 3541 tmp = new_scalar_tmp_constraint_exp ("allalltmp");
f1f41a6c 3542 FOR_EACH_VEC_ELT (rhsc, i, rhsp)
047fdd47 3543 process_constraint (new_constraint (tmp, *rhsp));
f1f41a6c 3544 FOR_EACH_VEC_ELT (lhsc, i, lhsp)
047fdd47 3545 process_constraint (new_constraint (*lhsp, tmp));
3546 }
3547}
3548
29fd4364 3549/* Handle aggregate copies by expanding into copies of the respective
3550 fields of the structures. */
3551
3552static void
3553do_structure_copy (tree lhsop, tree rhsop)
3554{
dd277d48 3555 struct constraint_expr *lhsp, *rhsp;
1e094109 3556 vec<ce_s> lhsc = vNULL;
3557 vec<ce_s> rhsc = vNULL;
dd277d48 3558 unsigned j;
3559
3560 get_constraint_for (lhsop, &lhsc);
59b12eb5 3561 get_constraint_for_rhs (rhsop, &rhsc);
f1f41a6c 3562 lhsp = &lhsc[0];
3563 rhsp = &rhsc[0];
dd277d48 3564 if (lhsp->type == DEREF
3565 || (lhsp->type == ADDRESSOF && lhsp->var == anything_id)
3566 || rhsp->type == DEREF)
3eaadea6 3567 {
3568 if (lhsp->type == DEREF)
3569 {
f1f41a6c 3570 gcc_assert (lhsc.length () == 1);
3eaadea6 3571 lhsp->offset = UNKNOWN_OFFSET;
3572 }
3573 if (rhsp->type == DEREF)
3574 {
f1f41a6c 3575 gcc_assert (rhsc.length () == 1);
3eaadea6 3576 rhsp->offset = UNKNOWN_OFFSET;
3577 }
3578 process_all_all_constraints (lhsc, rhsc);
3579 }
dd277d48 3580 else if (lhsp->type == SCALAR
3581 && (rhsp->type == SCALAR
3582 || rhsp->type == ADDRESSOF))
29fd4364 3583 {
dd277d48 3584 HOST_WIDE_INT lhssize, lhsmaxsize, lhsoffset;
3585 HOST_WIDE_INT rhssize, rhsmaxsize, rhsoffset;
3586 unsigned k = 0;
f018d957 3587 get_ref_base_and_extent (lhsop, &lhsoffset, &lhssize, &lhsmaxsize);
3588 get_ref_base_and_extent (rhsop, &rhsoffset, &rhssize, &rhsmaxsize);
f1f41a6c 3589 for (j = 0; lhsc.iterate (j, &lhsp);)
29fd4364 3590 {
dd277d48 3591 varinfo_t lhsv, rhsv;
f1f41a6c 3592 rhsp = &rhsc[k];
dd277d48 3593 lhsv = get_varinfo (lhsp->var);
3594 rhsv = get_varinfo (rhsp->var);
3595 if (lhsv->may_have_pointers
4b65cd43 3596 && (lhsv->is_full_var
3597 || rhsv->is_full_var
3598 || ranges_overlap_p (lhsv->offset + rhsoffset, lhsv->size,
3599 rhsv->offset + lhsoffset, rhsv->size)))
dd277d48 3600 process_constraint (new_constraint (*lhsp, *rhsp));
4b65cd43 3601 if (!rhsv->is_full_var
3602 && (lhsv->is_full_var
3603 || (lhsv->offset + rhsoffset + lhsv->size
3604 > rhsv->offset + lhsoffset + rhsv->size)))
dd277d48 3605 {
3606 ++k;
f1f41a6c 3607 if (k >= rhsc.length ())
dd277d48 3608 break;
3609 }
29fd4364 3610 else
dd277d48 3611 ++j;
29fd4364 3612 }
3613 }
3614 else
dd277d48 3615 gcc_unreachable ();
25fd8fda 3616
f1f41a6c 3617 lhsc.release ();
3618 rhsc.release ();
29fd4364 3619}
3620
86f29f5f 3621/* Create constraints ID = { rhsc }. */
0b3bf4d6 3622
3623static void
f1f41a6c 3624make_constraints_to (unsigned id, vec<ce_s> rhsc)
0b3bf4d6 3625{
0b3bf4d6 3626 struct constraint_expr *c;
3627 struct constraint_expr includes;
3628 unsigned int j;
3629
3630 includes.var = id;
3631 includes.offset = 0;
3632 includes.type = SCALAR;
3633
f1f41a6c 3634 FOR_EACH_VEC_ELT (rhsc, j, c)
339d7079 3635 process_constraint (new_constraint (includes, *c));
86f29f5f 3636}
3637
3638/* Create a constraint ID = OP. */
3639
3640static void
3641make_constraint_to (unsigned id, tree op)
3642{
1e094109 3643 vec<ce_s> rhsc = vNULL;
86f29f5f 3644 get_constraint_for_rhs (op, &rhsc);
3645 make_constraints_to (id, rhsc);
f1f41a6c 3646 rhsc.release ();
0b3bf4d6 3647}
3648
1c1f1bc0 3649/* Create a constraint ID = &FROM. */
3650
3651static void
3652make_constraint_from (varinfo_t vi, int from)
3653{
3654 struct constraint_expr lhs, rhs;
3655
3656 lhs.var = vi->id;
3657 lhs.offset = 0;
3658 lhs.type = SCALAR;
3659
3660 rhs.var = from;
3661 rhs.offset = 0;
3662 rhs.type = ADDRESSOF;
3663 process_constraint (new_constraint (lhs, rhs));
3664}
3665
3666/* Create a constraint ID = FROM. */
3667
3668static void
3669make_copy_constraint (varinfo_t vi, int from)
3670{
3671 struct constraint_expr lhs, rhs;
3672
3673 lhs.var = vi->id;
3674 lhs.offset = 0;
3675 lhs.type = SCALAR;
3676
3677 rhs.var = from;
3678 rhs.offset = 0;
3679 rhs.type = SCALAR;
3680 process_constraint (new_constraint (lhs, rhs));
3681}
3682
0b3bf4d6 3683/* Make constraints necessary to make OP escape. */
3684
3685static void
3686make_escape_constraint (tree op)
3687{
3688 make_constraint_to (escaped_id, op);
3689}
3690
c4ec6aca 3691/* Add constraints to that the solution of VI is transitively closed. */
3692
3693static void
3694make_transitive_closure_constraints (varinfo_t vi)
3695{
3696 struct constraint_expr lhs, rhs;
3697
3698 /* VAR = *VAR; */
3699 lhs.type = SCALAR;
3700 lhs.var = vi->id;
3701 lhs.offset = 0;
3702 rhs.type = DEREF;
3703 rhs.var = vi->id;
3704 rhs.offset = 0;
3705 process_constraint (new_constraint (lhs, rhs));
3706
3707 /* VAR = VAR + UNKNOWN; */
3708 lhs.type = SCALAR;
3709 lhs.var = vi->id;
3710 lhs.offset = 0;
3711 rhs.type = SCALAR;
3712 rhs.var = vi->id;
3713 rhs.offset = UNKNOWN_OFFSET;
3714 process_constraint (new_constraint (lhs, rhs));
3715}
3716
e44576dd 3717/* Temporary storage for fake var decls. */
3718struct obstack fake_var_decl_obstack;
3719
3720/* Build a fake VAR_DECL acting as referrer to a DECL_UID. */
3721
3722static tree
3723build_fake_var_decl (tree type)
3724{
3725 tree decl = (tree) XOBNEW (&fake_var_decl_obstack, struct tree_var_decl);
3726 memset (decl, 0, sizeof (struct tree_var_decl));
3727 TREE_SET_CODE (decl, VAR_DECL);
3728 TREE_TYPE (decl) = type;
3729 DECL_UID (decl) = allocate_decl_uid ();
3730 SET_DECL_PT_UID (decl, -1);
3731 layout_decl (decl, 0);
3732 return decl;
3733}
3734
8ce86007 3735/* Create a new artificial heap variable with NAME.
3736 Return the created variable. */
1c1f1bc0 3737
3738static varinfo_t
e44576dd 3739make_heapvar (const char *name)
1c1f1bc0 3740{
3741 varinfo_t vi;
e44576dd 3742 tree heapvar;
3743
3744 heapvar = build_fake_var_decl (ptr_type_node);
3745 DECL_EXTERNAL (heapvar) = 1;
1c1f1bc0 3746
3747 vi = new_var_info (heapvar, name);
3748 vi->is_artificial_var = true;
3749 vi->is_heap_var = true;
3750 vi->is_unknown_size_var = true;
96803d15 3751 vi->offset = 0;
1c1f1bc0 3752 vi->fullsize = ~0;
3753 vi->size = ~0;
3754 vi->is_full_var = true;
3755 insert_vi_for_tree (heapvar, vi);
3756
8ce86007 3757 return vi;
3758}
3759
3760/* Create a new artificial heap variable with NAME and make a
6fc56905 3761 constraint from it to LHS. Set flags according to a tag used
3762 for tracking restrict pointers. */
8ce86007 3763
3764static varinfo_t
6fc56905 3765make_constraint_from_restrict (varinfo_t lhs, const char *name)
8ce86007 3766{
e44576dd 3767 varinfo_t vi = make_heapvar (name);
6fc56905 3768 vi->is_global_var = 1;
3769 vi->may_have_pointers = 1;
1c1f1bc0 3770 make_constraint_from (lhs, vi->id);
1c1f1bc0 3771 return vi;
3772}
3773
3774/* Create a new artificial heap variable with NAME and make a
3775 constraint from it to LHS. Set flags according to a tag used
6fc56905 3776 for tracking restrict pointers and make the artificial heap
3777 point to global memory. */
1c1f1bc0 3778
6fc56905 3779static varinfo_t
3780make_constraint_from_global_restrict (varinfo_t lhs, const char *name)
1c1f1bc0 3781{
6fc56905 3782 varinfo_t vi = make_constraint_from_restrict (lhs, name);
3783 make_copy_constraint (vi, nonlocal_id);
3784 return vi;
1c1f1bc0 3785}
3786
1a981e1a 3787/* In IPA mode there are varinfos for different aspects of reach
3788 function designator. One for the points-to set of the return
3789 value, one for the variables that are clobbered by the function,
3790 one for its uses and one for each parameter (including a single
3791 glob for remaining variadic arguments). */
3792
3793enum { fi_clobbers = 1, fi_uses = 2,
3794 fi_static_chain = 3, fi_result = 4, fi_parm_base = 5 };
3795
3796/* Get a constraint for the requested part of a function designator FI
3797 when operating in IPA mode. */
3798
3799static struct constraint_expr
3800get_function_part_constraint (varinfo_t fi, unsigned part)
3801{
3802 struct constraint_expr c;
3803
3804 gcc_assert (in_ipa_mode);
3805
3806 if (fi->id == anything_id)
3807 {
3808 /* ??? We probably should have a ANYFN special variable. */
3809 c.var = anything_id;
3810 c.offset = 0;
3811 c.type = SCALAR;
3812 }
3813 else if (TREE_CODE (fi->decl) == FUNCTION_DECL)
3814 {
3815 varinfo_t ai = first_vi_for_offset (fi, part);
d812977b 3816 if (ai)
3817 c.var = ai->id;
3818 else
3819 c.var = anything_id;
1a981e1a 3820 c.offset = 0;
3821 c.type = SCALAR;
3822 }
3823 else
3824 {
3825 c.var = fi->id;
3826 c.offset = part;
3827 c.type = DEREF;
3828 }
3829
3830 return c;
3831}
3832
a6db8f14 3833/* For non-IPA mode, generate constraints necessary for a call on the
3834 RHS. */
3835
3836static void
f1f41a6c 3837handle_rhs_call (gimple stmt, vec<ce_s> *results)
a6db8f14 3838{
9d1d1fab 3839 struct constraint_expr rhsc;
75a70cf9 3840 unsigned i;
8ce86007 3841 bool returns_uses = false;
a6db8f14 3842
75a70cf9 3843 for (i = 0; i < gimple_call_num_args (stmt); ++i)
3844 {
3845 tree arg = gimple_call_arg (stmt, i);
8ce86007 3846 int flags = gimple_call_arg_flags (stmt, i);
75a70cf9 3847
e856db01 3848 /* If the argument is not used we can ignore it. */
3849 if (flags & EAF_UNUSED)
8ce86007 3850 continue;
3851
3852 /* As we compute ESCAPED context-insensitive we do not gain
3853 any precision with just EAF_NOCLOBBER but not EAF_NOESCAPE
3854 set. The argument would still get clobbered through the
488d5367 3855 escape solution. */
8ce86007 3856 if ((flags & EAF_NOCLOBBER)
3857 && (flags & EAF_NOESCAPE))
3858 {
3859 varinfo_t uses = get_call_use_vi (stmt);
3860 if (!(flags & EAF_DIRECT))
488d5367 3861 {
3862 varinfo_t tem = new_var_info (NULL_TREE, "callarg");
3863 make_constraint_to (tem->id, arg);
3864 make_transitive_closure_constraints (tem);
3865 make_copy_constraint (uses, tem->id);
3866 }
3867 else
3868 make_constraint_to (uses->id, arg);
8ce86007 3869 returns_uses = true;
3870 }
3871 else if (flags & EAF_NOESCAPE)
3872 {
488d5367 3873 struct constraint_expr lhs, rhs;
8ce86007 3874 varinfo_t uses = get_call_use_vi (stmt);
3875 varinfo_t clobbers = get_call_clobber_vi (stmt);
488d5367 3876 varinfo_t tem = new_var_info (NULL_TREE, "callarg");
3877 make_constraint_to (tem->id, arg);
8ce86007 3878 if (!(flags & EAF_DIRECT))
488d5367 3879 make_transitive_closure_constraints (tem);
3880 make_copy_constraint (uses, tem->id);
3881 make_copy_constraint (clobbers, tem->id);
3882 /* Add *tem = nonlocal, do not add *tem = callused as
3883 EAF_NOESCAPE parameters do not escape to other parameters
3884 and all other uses appear in NONLOCAL as well. */
3885 lhs.type = DEREF;
3886 lhs.var = tem->id;
3887 lhs.offset = 0;
3888 rhs.type = SCALAR;
3889 rhs.var = nonlocal_id;
3890 rhs.offset = 0;
3891 process_constraint (new_constraint (lhs, rhs));
8ce86007 3892 returns_uses = true;
3893 }
3894 else
75a70cf9 3895 make_escape_constraint (arg);
3896 }
0b3bf4d6 3897
8ce86007 3898 /* If we added to the calls uses solution make sure we account for
3899 pointers to it to be returned. */
3900 if (returns_uses)
3901 {
3902 rhsc.var = get_call_use_vi (stmt)->id;
3903 rhsc.offset = 0;
3904 rhsc.type = SCALAR;
f1f41a6c 3905 results->safe_push (rhsc);
8ce86007 3906 }
3907
0b3bf4d6 3908 /* The static chain escapes as well. */
75a70cf9 3909 if (gimple_call_chain (stmt))
3910 make_escape_constraint (gimple_call_chain (stmt));
9d1d1fab 3911
60b9b3ae 3912 /* And if we applied NRV the address of the return slot escapes as well. */
3913 if (gimple_call_return_slot_opt_p (stmt)
3914 && gimple_call_lhs (stmt) != NULL_TREE
c7e30df8 3915 && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
60b9b3ae 3916 {
1e094109 3917 vec<ce_s> tmpc = vNULL;
60b9b3ae 3918 struct constraint_expr lhsc, *c;
3919 get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
3920 lhsc.var = escaped_id;
3921 lhsc.offset = 0;
3922 lhsc.type = SCALAR;
f1f41a6c 3923 FOR_EACH_VEC_ELT (tmpc, i, c)
60b9b3ae 3924 process_constraint (new_constraint (lhsc, *c));
f1f41a6c 3925 tmpc.release ();
60b9b3ae 3926 }
3927
dd277d48 3928 /* Regular functions return nonlocal memory. */
3929 rhsc.var = nonlocal_id;
9d1d1fab 3930 rhsc.offset = 0;
dd277d48 3931 rhsc.type = SCALAR;
f1f41a6c 3932 results->safe_push (rhsc);
a6db8f14 3933}
260e7e11 3934
50fad245 3935/* For non-IPA mode, generate constraints necessary for a call
3936 that returns a pointer and assigns it to LHS. This simply makes
0b3bf4d6 3937 the LHS point to global and escaped variables. */
50fad245 3938
3939static void
f1f41a6c 3940handle_lhs_call (gimple stmt, tree lhs, int flags, vec<ce_s> rhsc,
8ce86007 3941 tree fndecl)
50fad245 3942{
1e094109 3943 vec<ce_s> lhsc = vNULL;
50fad245 3944
0b3bf4d6 3945 get_constraint_for (lhs, &lhsc);
8ce86007 3946 /* If the store is to a global decl make sure to
3947 add proper escape constraints. */
3948 lhs = get_base_address (lhs);
3949 if (lhs
3950 && DECL_P (lhs)
3951 && is_global_var (lhs))
3952 {
3953 struct constraint_expr tmpc;
3954 tmpc.var = escaped_id;
3955 tmpc.offset = 0;
3956 tmpc.type = SCALAR;
f1f41a6c 3957 lhsc.safe_push (tmpc);
8ce86007 3958 }
a7d6b13e 3959
8ce86007 3960 /* If the call returns an argument unmodified override the rhs
3961 constraints. */
3962 flags = gimple_call_return_flags (stmt);
3963 if (flags & ERF_RETURNS_ARG
3964 && (flags & ERF_RETURN_ARG_MASK) < gimple_call_num_args (stmt))
3965 {
3966 tree arg;
f1f41a6c 3967 rhsc.create (0);
8ce86007 3968 arg = gimple_call_arg (stmt, flags & ERF_RETURN_ARG_MASK);
3969 get_constraint_for (arg, &rhsc);
3970 process_all_all_constraints (lhsc, rhsc);
f1f41a6c 3971 rhsc.release ();
8ce86007 3972 }
3973 else if (flags & ERF_NOALIAS)
a7d6b13e 3974 {
a7d6b13e 3975 varinfo_t vi;
8ce86007 3976 struct constraint_expr tmpc;
f1f41a6c 3977 rhsc.create (0);
e44576dd 3978 vi = make_heapvar ("HEAP");
9df58cd1 3979 /* We delay marking allocated storage global until we know if
3980 it escapes. */
9b68b56b 3981 DECL_EXTERNAL (vi->decl) = 0;
9df58cd1 3982 vi->is_global_var = 0;
a4d2f616 3983 /* If this is not a real malloc call assume the memory was
8ce86007 3984 initialized and thus may point to global memory. All
a4d2f616 3985 builtin functions with the malloc attribute behave in a sane way. */
3986 if (!fndecl
3987 || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
3988 make_constraint_from (vi, nonlocal_id);
8ce86007 3989 tmpc.var = vi->id;
3990 tmpc.offset = 0;
3991 tmpc.type = ADDRESSOF;
f1f41a6c 3992 rhsc.safe_push (tmpc);
83b709f2 3993 process_all_all_constraints (lhsc, rhsc);
f1f41a6c 3994 rhsc.release ();
a7d6b13e 3995 }
83b709f2 3996 else
3997 process_all_all_constraints (lhsc, rhsc);
8ce86007 3998
f1f41a6c 3999 lhsc.release ();
0b3bf4d6 4000}
4001
4002/* For non-IPA mode, generate constraints necessary for a call of a
4003 const function that returns a pointer in the statement STMT. */
4004
4005static void
f1f41a6c 4006handle_const_call (gimple stmt, vec<ce_s> *results)
0b3bf4d6 4007{
c2abd8e4 4008 struct constraint_expr rhsc;
9d1d1fab 4009 unsigned int k;
0b3bf4d6 4010
9d1d1fab 4011 /* Treat nested const functions the same as pure functions as far
4012 as the static chain is concerned. */
75a70cf9 4013 if (gimple_call_chain (stmt))
0b3bf4d6 4014 {
c4ec6aca 4015 varinfo_t uses = get_call_use_vi (stmt);
4016 make_transitive_closure_constraints (uses);
4017 make_constraint_to (uses->id, gimple_call_chain (stmt));
4018 rhsc.var = uses->id;
0b3bf4d6 4019 rhsc.offset = 0;
9d1d1fab 4020 rhsc.type = SCALAR;
f1f41a6c 4021 results->safe_push (rhsc);
0b3bf4d6 4022 }
4023
0b3bf4d6 4024 /* May return arguments. */
75a70cf9 4025 for (k = 0; k < gimple_call_num_args (stmt); ++k)
4026 {
4027 tree arg = gimple_call_arg (stmt, k);
1e094109 4028 vec<ce_s> argc = vNULL;
e856db01 4029 unsigned i;
4030 struct constraint_expr *argp;
4031 get_constraint_for_rhs (arg, &argc);
f1f41a6c 4032 FOR_EACH_VEC_ELT (argc, i, argp)
4033 results->safe_push (*argp);
4034 argc.release ();
75a70cf9 4035 }
0b3bf4d6 4036
9d1d1fab 4037 /* May return addresses of globals. */
4038 rhsc.var = nonlocal_id;
4039 rhsc.offset = 0;
4040 rhsc.type = ADDRESSOF;
f1f41a6c 4041 results->safe_push (rhsc);
50fad245 4042}
4043
9f41ce98 4044/* For non-IPA mode, generate constraints necessary for a call to a
4045 pure function in statement STMT. */
4046
4047static void
f1f41a6c 4048handle_pure_call (gimple stmt, vec<ce_s> *results)
9f41ce98 4049{
9d1d1fab 4050 struct constraint_expr rhsc;
75a70cf9 4051 unsigned i;
c4ec6aca 4052 varinfo_t uses = NULL;
9f41ce98 4053
4054 /* Memory reached from pointer arguments is call-used. */
75a70cf9 4055 for (i = 0; i < gimple_call_num_args (stmt); ++i)
4056 {
4057 tree arg = gimple_call_arg (stmt, i);
e856db01 4058 if (!uses)
9d1d1fab 4059 {
e856db01 4060 uses = get_call_use_vi (stmt);
4061 make_transitive_closure_constraints (uses);
9d1d1fab 4062 }
e856db01 4063 make_constraint_to (uses->id, arg);
75a70cf9 4064 }
9f41ce98 4065
4066 /* The static chain is used as well. */
75a70cf9 4067 if (gimple_call_chain (stmt))
9f41ce98 4068 {
c4ec6aca 4069 if (!uses)
4070 {
4071 uses = get_call_use_vi (stmt);
4072 make_transitive_closure_constraints (uses);
4073 }
4074 make_constraint_to (uses->id, gimple_call_chain (stmt));
9d1d1fab 4075 }
9f41ce98 4076
c4ec6aca 4077 /* Pure functions may return call-used and nonlocal memory. */
4078 if (uses)
9d1d1fab 4079 {
c4ec6aca 4080 rhsc.var = uses->id;
9f41ce98 4081 rhsc.offset = 0;
9d1d1fab 4082 rhsc.type = SCALAR;
f1f41a6c 4083 results->safe_push (rhsc);
9f41ce98 4084 }
dd277d48 4085 rhsc.var = nonlocal_id;
9d1d1fab 4086 rhsc.offset = 0;
dd277d48 4087 rhsc.type = SCALAR;
f1f41a6c 4088 results->safe_push (rhsc);
9f41ce98 4089}
4090
1a981e1a 4091
4092/* Return the varinfo for the callee of CALL. */
4093
4094static varinfo_t
4095get_fi_for_callee (gimple call)
4096{
cb755135 4097 tree decl, fn = gimple_call_fn (call);
1a981e1a 4098
cb755135 4099 if (fn && TREE_CODE (fn) == OBJ_TYPE_REF)
4100 fn = OBJ_TYPE_REF_EXPR (fn);
fb049fba 4101
1a981e1a 4102 /* If we can directly resolve the function being called, do so.
4103 Otherwise, it must be some sort of indirect expression that
4104 we should still be able to handle. */
cb755135 4105 decl = gimple_call_addr_fndecl (fn);
1a981e1a 4106 if (decl)
4107 return get_vi_for_tree (decl);
4108
cb755135 4109 /* If the function is anything other than a SSA name pointer we have no
1a981e1a 4110 clue and should be getting ANYFN (well, ANYTHING for now). */
cb755135 4111 if (!fn || TREE_CODE (fn) != SSA_NAME)
1a981e1a 4112 return get_varinfo (anything_id);
cb755135 4113
2f4ec87c 4114 if (SSA_NAME_IS_DEFAULT_DEF (fn)
4115 && (TREE_CODE (SSA_NAME_VAR (fn)) == PARM_DECL
4116 || TREE_CODE (SSA_NAME_VAR (fn)) == RESULT_DECL))
cb755135 4117 fn = SSA_NAME_VAR (fn);
4118
4119 return get_vi_for_tree (fn);
1a981e1a 4120}
4121
882f2f67 4122/* Create constraints for the builtin call T. Return true if the call
4123 was handled, otherwise false. */
29fd4364 4124
882f2f67 4125static bool
4126find_func_aliases_for_builtin_call (gimple t)
29fd4364 4127{
882f2f67 4128 tree fndecl = gimple_call_fndecl (t);
1e094109 4129 vec<ce_s> lhsc = vNULL;
4130 vec<ce_s> rhsc = vNULL;
1a981e1a 4131 varinfo_t fi;
29fd4364 4132
789a8d72 4133 if (gimple_call_builtin_p (t, BUILT_IN_NORMAL))
882f2f67 4134 /* ??? All builtins that are handled here need to be handled
4135 in the alias-oracle query functions explicitly! */
4136 switch (DECL_FUNCTION_CODE (fndecl))
4137 {
4138 /* All the following functions return a pointer to the same object
4139 as their first argument points to. The functions do not add
4140 to the ESCAPED solution. The functions make the first argument
4141 pointed to memory point to what the second argument pointed to
4142 memory points to. */
4143 case BUILT_IN_STRCPY:
4144 case BUILT_IN_STRNCPY:
4145 case BUILT_IN_BCOPY:
4146 case BUILT_IN_MEMCPY:
4147 case BUILT_IN_MEMMOVE:
4148 case BUILT_IN_MEMPCPY:
4149 case BUILT_IN_STPCPY:
4150 case BUILT_IN_STPNCPY:
4151 case BUILT_IN_STRCAT:
4152 case BUILT_IN_STRNCAT:
939514e9 4153 case BUILT_IN_STRCPY_CHK:
4154 case BUILT_IN_STRNCPY_CHK:
4155 case BUILT_IN_MEMCPY_CHK:
4156 case BUILT_IN_MEMMOVE_CHK:
4157 case BUILT_IN_MEMPCPY_CHK:
4158 case BUILT_IN_STPCPY_CHK:
1063acde 4159 case BUILT_IN_STPNCPY_CHK:
939514e9 4160 case BUILT_IN_STRCAT_CHK:
4161 case BUILT_IN_STRNCAT_CHK:
4c0315d0 4162 case BUILT_IN_TM_MEMCPY:
4163 case BUILT_IN_TM_MEMMOVE:
260e7e11 4164 {
882f2f67 4165 tree res = gimple_call_lhs (t);
4166 tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
4167 == BUILT_IN_BCOPY ? 1 : 0));
4168 tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
4169 == BUILT_IN_BCOPY ? 0 : 1));
4170 if (res != NULL_TREE)
e856db01 4171 {
882f2f67 4172 get_constraint_for (res, &lhsc);
4173 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY
4174 || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY
c53a3b4b 4175 || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY
4176 || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY_CHK
1063acde 4177 || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY_CHK
4178 || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY_CHK)
882f2f67 4179 get_constraint_for_ptr_offset (dest, NULL_TREE, &rhsc);
4180 else
4181 get_constraint_for (dest, &rhsc);
4182 process_all_all_constraints (lhsc, rhsc);
f1f41a6c 4183 lhsc.release ();
4184 rhsc.release ();
7d1f52b2 4185 }
882f2f67 4186 get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
4187 get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
4188 do_deref (&lhsc);
4189 do_deref (&rhsc);
4190 process_all_all_constraints (lhsc, rhsc);
f1f41a6c 4191 lhsc.release ();
4192 rhsc.release ();
882f2f67 4193 return true;
db026f5c 4194 }
882f2f67 4195 case BUILT_IN_MEMSET:
939514e9 4196 case BUILT_IN_MEMSET_CHK:
4c0315d0 4197 case BUILT_IN_TM_MEMSET:
882f2f67 4198 {
4199 tree res = gimple_call_lhs (t);
4200 tree dest = gimple_call_arg (t, 0);
4201 unsigned i;
4202 ce_s *lhsp;
4203 struct constraint_expr ac;
4204 if (res != NULL_TREE)
047fdd47 4205 {
882f2f67 4206 get_constraint_for (res, &lhsc);
4207 get_constraint_for (dest, &rhsc);
047fdd47 4208 process_all_all_constraints (lhsc, rhsc);
f1f41a6c 4209 lhsc.release ();
4210 rhsc.release ();
047fdd47 4211 }
882f2f67 4212 get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
4213 do_deref (&lhsc);
4214 if (flag_delete_null_pointer_checks
4215 && integer_zerop (gimple_call_arg (t, 1)))
047fdd47 4216 {
882f2f67 4217 ac.type = ADDRESSOF;
4218 ac.var = nothing_id;
047fdd47 4219 }
882f2f67 4220 else
1a981e1a 4221 {
882f2f67 4222 ac.type = SCALAR;
4223 ac.var = integer_id;
1a981e1a 4224 }
882f2f67 4225 ac.offset = 0;
f1f41a6c 4226 FOR_EACH_VEC_ELT (lhsc, i, lhsp)
882f2f67 4227 process_constraint (new_constraint (*lhsp, ac));
f1f41a6c 4228 lhsc.release ();
882f2f67 4229 return true;
4230 }
da923e9c 4231 case BUILT_IN_ASSUME_ALIGNED:
4232 {
4233 tree res = gimple_call_lhs (t);
4234 tree dest = gimple_call_arg (t, 0);
4235 if (res != NULL_TREE)
4236 {
4237 get_constraint_for (res, &lhsc);
4238 get_constraint_for (dest, &rhsc);
4239 process_all_all_constraints (lhsc, rhsc);
f1f41a6c 4240 lhsc.release ();
4241 rhsc.release ();
da923e9c 4242 }
4243 return true;
4244 }
882f2f67 4245 /* All the following functions do not return pointers, do not
4246 modify the points-to sets of memory reachable from their
4247 arguments and do not add to the ESCAPED solution. */
4248 case BUILT_IN_SINCOS:
4249 case BUILT_IN_SINCOSF:
4250 case BUILT_IN_SINCOSL:
4251 case BUILT_IN_FREXP:
4252 case BUILT_IN_FREXPF:
4253 case BUILT_IN_FREXPL:
4254 case BUILT_IN_GAMMA_R:
4255 case BUILT_IN_GAMMAF_R:
4256 case BUILT_IN_GAMMAL_R:
4257 case BUILT_IN_LGAMMA_R:
4258 case BUILT_IN_LGAMMAF_R:
4259 case BUILT_IN_LGAMMAL_R:
4260 case BUILT_IN_MODF:
4261 case BUILT_IN_MODFF:
4262 case BUILT_IN_MODFL:
4263 case BUILT_IN_REMQUO:
4264 case BUILT_IN_REMQUOF:
4265 case BUILT_IN_REMQUOL:
4266 case BUILT_IN_FREE:
4267 return true;
77efe819 4268 case BUILT_IN_STRDUP:
4269 case BUILT_IN_STRNDUP:
4270 if (gimple_call_lhs (t))
4271 {
4272 handle_lhs_call (t, gimple_call_lhs (t), gimple_call_flags (t),
1e094109 4273 vNULL, fndecl);
77efe819 4274 get_constraint_for_ptr_offset (gimple_call_lhs (t),
4275 NULL_TREE, &lhsc);
4276 get_constraint_for_ptr_offset (gimple_call_arg (t, 0),
4277 NULL_TREE, &rhsc);
4278 do_deref (&lhsc);
4279 do_deref (&rhsc);
4280 process_all_all_constraints (lhsc, rhsc);
f1f41a6c 4281 lhsc.release ();
4282 rhsc.release ();
77efe819 4283 return true;
4284 }
4285 break;
4953672f 4286 /* String / character search functions return a pointer into the
4287 source string or NULL. */
4288 case BUILT_IN_INDEX:
4289 case BUILT_IN_STRCHR:
4290 case BUILT_IN_STRRCHR:
4291 case BUILT_IN_MEMCHR:
4292 case BUILT_IN_STRSTR:
4293 case BUILT_IN_STRPBRK:
4294 if (gimple_call_lhs (t))
4295 {
4296 tree src = gimple_call_arg (t, 0);
4297 get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
4298 constraint_expr nul;
4299 nul.var = nothing_id;
4300 nul.offset = 0;
4301 nul.type = ADDRESSOF;
4302 rhsc.safe_push (nul);
4303 get_constraint_for (gimple_call_lhs (t), &lhsc);
4304 process_all_all_constraints (lhsc, rhsc);
9af5ce0c 4305 lhsc.release ();
4306 rhsc.release ();
4953672f 4307 }
4308 return true;
882f2f67 4309 /* Trampolines are special - they set up passing the static
4310 frame. */
4311 case BUILT_IN_INIT_TRAMPOLINE:
4312 {
4313 tree tramp = gimple_call_arg (t, 0);
4314 tree nfunc = gimple_call_arg (t, 1);
4315 tree frame = gimple_call_arg (t, 2);
4316 unsigned i;
4317 struct constraint_expr lhs, *rhsp;
4318 if (in_ipa_mode)
1a981e1a 4319 {
882f2f67 4320 varinfo_t nfi = NULL;
4321 gcc_assert (TREE_CODE (nfunc) == ADDR_EXPR);
4322 nfi = lookup_vi_for_tree (TREE_OPERAND (nfunc, 0));
4323 if (nfi)
1a981e1a 4324 {
882f2f67 4325 lhs = get_function_part_constraint (nfi, fi_static_chain);
4326 get_constraint_for (frame, &rhsc);
f1f41a6c 4327 FOR_EACH_VEC_ELT (rhsc, i, rhsp)
882f2f67 4328 process_constraint (new_constraint (lhs, *rhsp));
f1f41a6c 4329 rhsc.release ();
882f2f67 4330
4331 /* Make the frame point to the function for
4332 the trampoline adjustment call. */
4333 get_constraint_for (tramp, &lhsc);
4334 do_deref (&lhsc);
4335 get_constraint_for (nfunc, &rhsc);
1a981e1a 4336 process_all_all_constraints (lhsc, rhsc);
f1f41a6c 4337 rhsc.release ();
4338 lhsc.release ();
882f2f67 4339
4340 return true;
1a981e1a 4341 }
1a981e1a 4342 }
882f2f67 4343 /* Else fallthru to generic handling which will let
4344 the frame escape. */
4345 break;
4346 }
4347 case BUILT_IN_ADJUST_TRAMPOLINE:
4348 {
4349 tree tramp = gimple_call_arg (t, 0);
4350 tree res = gimple_call_lhs (t);
4351 if (in_ipa_mode && res)
1a981e1a 4352 {
882f2f67 4353 get_constraint_for (res, &lhsc);
4354 get_constraint_for (tramp, &rhsc);
4355 do_deref (&rhsc);
4356 process_all_all_constraints (lhsc, rhsc);
f1f41a6c 4357 rhsc.release ();
4358 lhsc.release ();
1a981e1a 4359 }
882f2f67 4360 return true;
4361 }
4c0315d0 4362 CASE_BUILT_IN_TM_STORE (1):
4363 CASE_BUILT_IN_TM_STORE (2):
4364 CASE_BUILT_IN_TM_STORE (4):
4365 CASE_BUILT_IN_TM_STORE (8):
4366 CASE_BUILT_IN_TM_STORE (FLOAT):
4367 CASE_BUILT_IN_TM_STORE (DOUBLE):
4368 CASE_BUILT_IN_TM_STORE (LDOUBLE):
4369 CASE_BUILT_IN_TM_STORE (M64):
4370 CASE_BUILT_IN_TM_STORE (M128):
4371 CASE_BUILT_IN_TM_STORE (M256):
4372 {
4373 tree addr = gimple_call_arg (t, 0);
4374 tree src = gimple_call_arg (t, 1);
4375
4376 get_constraint_for (addr, &lhsc);
4377 do_deref (&lhsc);
4378 get_constraint_for (src, &rhsc);
4379 process_all_all_constraints (lhsc, rhsc);
f1f41a6c 4380 lhsc.release ();
4381 rhsc.release ();
4c0315d0 4382 return true;
4383 }
4384 CASE_BUILT_IN_TM_LOAD (1):
4385 CASE_BUILT_IN_TM_LOAD (2):
4386 CASE_BUILT_IN_TM_LOAD (4):
4387 CASE_BUILT_IN_TM_LOAD (8):
4388 CASE_BUILT_IN_TM_LOAD (FLOAT):
4389 CASE_BUILT_IN_TM_LOAD (DOUBLE):
4390 CASE_BUILT_IN_TM_LOAD (LDOUBLE):
4391 CASE_BUILT_IN_TM_LOAD (M64):
4392 CASE_BUILT_IN_TM_LOAD (M128):
4393 CASE_BUILT_IN_TM_LOAD (M256):
4394 {
4395 tree dest = gimple_call_lhs (t);
4396 tree addr = gimple_call_arg (t, 0);
4397
4398 get_constraint_for (dest, &lhsc);
4399 get_constraint_for (addr, &rhsc);
4400 do_deref (&rhsc);
4401 process_all_all_constraints (lhsc, rhsc);
f1f41a6c 4402 lhsc.release ();
4403 rhsc.release ();
4c0315d0 4404 return true;
4405 }
882f2f67 4406 /* Variadic argument handling needs to be handled in IPA
4407 mode as well. */
4408 case BUILT_IN_VA_START:
4409 {
9d17b4a8 4410 tree valist = gimple_call_arg (t, 0);
4411 struct constraint_expr rhs, *lhsp;
4412 unsigned i;
4413 get_constraint_for (valist, &lhsc);
4414 do_deref (&lhsc);
4415 /* The va_list gets access to pointers in variadic
4416 arguments. Which we know in the case of IPA analysis
4417 and otherwise are just all nonlocal variables. */
882f2f67 4418 if (in_ipa_mode)
9a7b938d 4419 {
882f2f67 4420 fi = lookup_vi_for_tree (cfun->decl);
882f2f67 4421 rhs = get_function_part_constraint (fi, ~0);
4422 rhs.type = ADDRESSOF;
9a7b938d 4423 }
9d17b4a8 4424 else
4425 {
4426 rhs.var = nonlocal_id;
4427 rhs.type = ADDRESSOF;
4428 rhs.offset = 0;
4429 }
f1f41a6c 4430 FOR_EACH_VEC_ELT (lhsc, i, lhsp)
9d17b4a8 4431 process_constraint (new_constraint (*lhsp, rhs));
f1f41a6c 4432 lhsc.release ();
9d17b4a8 4433 /* va_list is clobbered. */
4434 make_constraint_to (get_call_clobber_vi (t)->id, valist);
4435 return true;
882f2f67 4436 }
4437 /* va_end doesn't have any effect that matters. */
4438 case BUILT_IN_VA_END:
4439 return true;
4440 /* Alternate return. Simply give up for now. */
4441 case BUILT_IN_RETURN:
db026f5c 4442 {
882f2f67 4443 fi = NULL;
4444 if (!in_ipa_mode
4445 || !(fi = get_vi_for_tree (cfun->decl)))
4446 make_constraint_from (get_varinfo (escaped_id), anything_id);
4447 else if (in_ipa_mode
4448 && fi != NULL)
0b3bf4d6 4449 {
882f2f67 4450 struct constraint_expr lhs, rhs;
4451 lhs = get_function_part_constraint (fi, fi_result);
4452 rhs.var = anything_id;
4453 rhs.offset = 0;
4454 rhs.type = SCALAR;
4455 process_constraint (new_constraint (lhs, rhs));
0b3bf4d6 4456 }
882f2f67 4457 return true;
4458 }
4459 /* printf-style functions may have hooks to set pointers to
4460 point to somewhere into the generated string. Leave them
c31fb425 4461 for a later exercise... */
882f2f67 4462 default:
4463 /* Fallthru to general call handling. */;
4464 }
4465
4466 return false;
4467}
4468
4469/* Create constraints for the call T. */
4470
4471static void
4472find_func_aliases_for_call (gimple t)
4473{
4474 tree fndecl = gimple_call_fndecl (t);
1e094109 4475 vec<ce_s> lhsc = vNULL;
4476 vec<ce_s> rhsc = vNULL;
882f2f67 4477 varinfo_t fi;
4478
4479 if (fndecl != NULL_TREE
4480 && DECL_BUILT_IN (fndecl)
4481 && find_func_aliases_for_builtin_call (t))
4482 return;
4483
cb755135 4484 fi = get_fi_for_callee (t);
882f2f67 4485 if (!in_ipa_mode
cb755135 4486 || (fndecl && !fi->is_fn_info))
882f2f67 4487 {
1e094109 4488 vec<ce_s> rhsc = vNULL;
882f2f67 4489 int flags = gimple_call_flags (t);
4490
4491 /* Const functions can return their arguments and addresses
4492 of global memory but not of escaped memory. */
4493 if (flags & (ECF_CONST|ECF_NOVOPS))
4494 {
86f29f5f 4495 if (gimple_call_lhs (t))
882f2f67 4496 handle_const_call (t, &rhsc);
db026f5c 4497 }
882f2f67 4498 /* Pure functions can return addresses in and of memory
4499 reachable from their arguments, but they are not an escape
4500 point for reachable memory of their arguments. */
4501 else if (flags & (ECF_PURE|ECF_LOOPING_CONST_OR_PURE))
4502 handle_pure_call (t, &rhsc);
db026f5c 4503 else
882f2f67 4504 handle_rhs_call (t, &rhsc);
4505 if (gimple_call_lhs (t))
4506 handle_lhs_call (t, gimple_call_lhs (t), flags, rhsc, fndecl);
f1f41a6c 4507 rhsc.release ();
882f2f67 4508 }
4509 else
4510 {
4511 tree lhsop;
4512 unsigned j;
085b7aab 4513
882f2f67 4514 /* Assign all the passed arguments to the appropriate incoming
4515 parameters of the function. */
4516 for (j = 0; j < gimple_call_num_args (t); j++)
4517 {
4518 struct constraint_expr lhs ;
4519 struct constraint_expr *rhsp;
4520 tree arg = gimple_call_arg (t, j);
a6db8f14 4521
882f2f67 4522 get_constraint_for_rhs (arg, &rhsc);
4523 lhs = get_function_part_constraint (fi, fi_parm_base + j);
f1f41a6c 4524 while (rhsc.length () != 0)
db026f5c 4525 {
f1f41a6c 4526 rhsp = &rhsc.last ();
882f2f67 4527 process_constraint (new_constraint (lhs, *rhsp));
f1f41a6c 4528 rhsc.pop ();
db026f5c 4529 }
882f2f67 4530 }
4531
4532 /* If we are returning a value, assign it to the result. */
4533 lhsop = gimple_call_lhs (t);
4534 if (lhsop)
4535 {
4536 struct constraint_expr rhs;
4537 struct constraint_expr *lhsp;
1a981e1a 4538
882f2f67 4539 get_constraint_for (lhsop, &lhsc);
4540 rhs = get_function_part_constraint (fi, fi_result);
4541 if (fndecl
1a981e1a 4542 && DECL_RESULT (fndecl)
4543 && DECL_BY_REFERENCE (DECL_RESULT (fndecl)))
4544 {
1e094109 4545 vec<ce_s> tem = vNULL;
f1f41a6c 4546 tem.safe_push (rhs);
882f2f67 4547 do_deref (&tem);
f1f41a6c 4548 rhs = tem[0];
4549 tem.release ();
1a981e1a 4550 }
f1f41a6c 4551 FOR_EACH_VEC_ELT (lhsc, j, lhsp)
cb755135 4552 process_constraint (new_constraint (*lhsp, rhs));
882f2f67 4553 }
1a981e1a 4554
882f2f67 4555 /* If we pass the result decl by reference, honor that. */
4556 if (lhsop
4557 && fndecl
4558 && DECL_RESULT (fndecl)
4559 && DECL_BY_REFERENCE (DECL_RESULT (fndecl)))
4560 {
4561 struct constraint_expr lhs;
4562 struct constraint_expr *rhsp;
4563
4564 get_constraint_for_address_of (lhsop, &rhsc);
4565 lhs = get_function_part_constraint (fi, fi_result);
f1f41a6c 4566 FOR_EACH_VEC_ELT (rhsc, j, rhsp)
cb755135 4567 process_constraint (new_constraint (lhs, *rhsp));
f1f41a6c 4568 rhsc.release ();
882f2f67 4569 }
1a981e1a 4570
882f2f67 4571 /* If we use a static chain, pass it along. */
4572 if (gimple_call_chain (t))
4573 {
4574 struct constraint_expr lhs;
4575 struct constraint_expr *rhsp;
4576
4577 get_constraint_for (gimple_call_chain (t), &rhsc);
4578 lhs = get_function_part_constraint (fi, fi_static_chain);
f1f41a6c 4579 FOR_EACH_VEC_ELT (rhsc, j, rhsp)
cb755135 4580 process_constraint (new_constraint (lhs, *rhsp));
882f2f67 4581 }
4582 }
4583}
4584
4585/* Walk statement T setting up aliasing constraints according to the
4586 references found in T. This function is the main part of the
4587 constraint builder. AI points to auxiliary alias information used
4588 when building alias sets and computing alias grouping heuristics. */
4589
4590static void
4591find_func_aliases (gimple origt)
4592{
4593 gimple t = origt;
1e094109 4594 vec<ce_s> lhsc = vNULL;
4595 vec<ce_s> rhsc = vNULL;
882f2f67 4596 struct constraint_expr *c;
4597 varinfo_t fi;
4598
4599 /* Now build constraints expressions. */
4600 if (gimple_code (t) == GIMPLE_PHI)
4601 {
4602 size_t i;
4603 unsigned int j;
4604
4605 /* For a phi node, assign all the arguments to
4606 the result. */
4607 get_constraint_for (gimple_phi_result (t), &lhsc);
4608 for (i = 0; i < gimple_phi_num_args (t); i++)
4609 {
4610 tree strippedrhs = PHI_ARG_DEF (t, i);
4611
4612 STRIP_NOPS (strippedrhs);
4613 get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc);
4614
f1f41a6c 4615 FOR_EACH_VEC_ELT (lhsc, j, c)
882f2f67 4616 {
4617 struct constraint_expr *c2;
f1f41a6c 4618 while (rhsc.length () > 0)
882f2f67 4619 {
f1f41a6c 4620 c2 = &rhsc.last ();
882f2f67 4621 process_constraint (new_constraint (*c, *c2));
f1f41a6c 4622 rhsc.pop ();
882f2f67 4623 }
1a981e1a 4624 }
7d1f52b2 4625 }
260e7e11 4626 }
882f2f67 4627 /* In IPA mode, we need to generate constraints to pass call
4628 arguments through their calls. There are two cases,
4629 either a GIMPLE_CALL returning a value, or just a plain
4630 GIMPLE_CALL when we are not.
4631
4632 In non-ipa mode, we need to generate constraints for each
4633 pointer passed by address. */
4634 else if (is_gimple_call (t))
4635 find_func_aliases_for_call (t);
4636
57e6b870 4637 /* Otherwise, just a regular assignment statement. Only care about
4638 operations with pointer result, others are dealt with as escape
4639 points if they have pointer operands. */
e856db01 4640 else if (is_gimple_assign (t))
260e7e11 4641 {
75a70cf9 4642 /* Otherwise, just a regular assignment statement. */
4643 tree lhsop = gimple_assign_lhs (t);
4644 tree rhsop = (gimple_num_ops (t) == 2) ? gimple_assign_rhs1 (t) : NULL;
260e7e11 4645
3c25489e 4646 if (rhsop && TREE_CLOBBER_P (rhsop))
4647 /* Ignore clobbers, they don't actually store anything into
4648 the LHS. */
4649 ;
4650 else if (rhsop && AGGREGATE_TYPE_P (TREE_TYPE (lhsop)))
57e6b870 4651 do_structure_copy (lhsop, rhsop);
260e7e11 4652 else
4653 {
12d9baf9 4654 enum tree_code code = gimple_assign_rhs_code (t);
4655
57e6b870 4656 get_constraint_for (lhsop, &lhsc);
75a70cf9 4657
f837b1f7 4658 if (FLOAT_TYPE_P (TREE_TYPE (lhsop)))
4659 /* If the operation produces a floating point result then
4660 assume the value is not produced to transfer a pointer. */
4661 ;
4662 else if (code == POINTER_PLUS_EXPR)
75a70cf9 4663 get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
4664 gimple_assign_rhs2 (t), &rhsc);
12d9baf9 4665 else if (code == BIT_AND_EXPR
b03fbfbd 4666 && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST)
4667 {
4668 /* Aligning a pointer via a BIT_AND_EXPR is offsetting
4669 the pointer. Handle it by offsetting it by UNKNOWN. */
4670 get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
4671 NULL_TREE, &rhsc);
4672 }
12d9baf9 4673 else if ((CONVERT_EXPR_CODE_P (code)
2d9a4f3c 4674 && !(POINTER_TYPE_P (gimple_expr_type (t))
4675 && !POINTER_TYPE_P (TREE_TYPE (rhsop))))
4676 || gimple_assign_single_p (t))
59b12eb5 4677 get_constraint_for_rhs (rhsop, &rhsc);
e42ce38b 4678 else if (code == COND_EXPR)
4679 {
4680 /* The result is a merge of both COND_EXPR arms. */
1e094109 4681 vec<ce_s> tmp = vNULL;
e42ce38b 4682 struct constraint_expr *rhsp;
4683 unsigned i;
4684 get_constraint_for_rhs (gimple_assign_rhs2 (t), &rhsc);
4685 get_constraint_for_rhs (gimple_assign_rhs3 (t), &tmp);
f1f41a6c 4686 FOR_EACH_VEC_ELT (tmp, i, rhsp)
4687 rhsc.safe_push (*rhsp);
4688 tmp.release ();
e42ce38b 4689 }
12d9baf9 4690 else if (truth_value_p (code))
4691 /* Truth value results are not pointer (parts). Or at least
4692 very very unreasonable obfuscation of a part. */
4693 ;
75a70cf9 4694 else
4695 {
e856db01 4696 /* All other operations are merges. */
1e094109 4697 vec<ce_s> tmp = vNULL;
e856db01 4698 struct constraint_expr *rhsp;
4699 unsigned i, j;
4700 get_constraint_for_rhs (gimple_assign_rhs1 (t), &rhsc);
4701 for (i = 2; i < gimple_num_ops (t); ++i)
4702 {
4703 get_constraint_for_rhs (gimple_op (t, i), &tmp);
f1f41a6c 4704 FOR_EACH_VEC_ELT (tmp, j, rhsp)
4705 rhsc.safe_push (*rhsp);
4706 tmp.truncate (0);
e856db01 4707 }
f1f41a6c 4708 tmp.release ();
75a70cf9 4709 }
047fdd47 4710 process_all_all_constraints (lhsc, rhsc);
260e7e11 4711 }
c174c650 4712 /* If there is a store to a global variable the rhs escapes. */
4713 if ((lhsop = get_base_address (lhsop)) != NULL_TREE
4714 && DECL_P (lhsop)
1a981e1a 4715 && is_global_var (lhsop)
4716 && (!in_ipa_mode
4717 || DECL_EXTERNAL (lhsop) || TREE_PUBLIC (lhsop)))
c174c650 4718 make_escape_constraint (rhsop);
29fd4364 4719 }
9df58cd1 4720 /* Handle escapes through return. */
4721 else if (gimple_code (t) == GIMPLE_RETURN
e856db01 4722 && gimple_return_retval (t) != NULL_TREE)
9df58cd1 4723 {
1a981e1a 4724 fi = NULL;
4725 if (!in_ipa_mode
4726 || !(fi = get_vi_for_tree (cfun->decl)))
4727 make_escape_constraint (gimple_return_retval (t));
4728 else if (in_ipa_mode
4729 && fi != NULL)
4730 {
4731 struct constraint_expr lhs ;
4732 struct constraint_expr *rhsp;
4733 unsigned i;
4734
4735 lhs = get_function_part_constraint (fi, fi_result);
59b12eb5 4736 get_constraint_for_rhs (gimple_return_retval (t), &rhsc);
f1f41a6c 4737 FOR_EACH_VEC_ELT (rhsc, i, rhsp)
1a981e1a 4738 process_constraint (new_constraint (lhs, *rhsp));
4739 }
9df58cd1 4740 }
e8146f09 4741 /* Handle asms conservatively by adding escape constraints to everything. */
4742 else if (gimple_code (t) == GIMPLE_ASM)
0b3bf4d6 4743 {
dd277d48 4744 unsigned i, noutputs;
4745 const char **oconstraints;
4746 const char *constraint;
4747 bool allows_mem, allows_reg, is_inout;
4748
4749 noutputs = gimple_asm_noutputs (t);
4750 oconstraints = XALLOCAVEC (const char *, noutputs);
4751
4752 for (i = 0; i < noutputs; ++i)
0b3bf4d6 4753 {
dd277d48 4754 tree link = gimple_asm_output_op (t, i);
4755 tree op = TREE_VALUE (link);
4756
4757 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
4758 oconstraints[i] = constraint;
4759 parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
4760 &allows_reg, &is_inout);
4761
4762 /* A memory constraint makes the address of the operand escape. */
4763 if (!allows_reg && allows_mem)
4764 make_escape_constraint (build_fold_addr_expr (op));
4765
4766 /* The asm may read global memory, so outputs may point to
4767 any global memory. */
e856db01 4768 if (op)
dd277d48 4769 {
1e094109 4770 vec<ce_s> lhsc = vNULL;
dd277d48 4771 struct constraint_expr rhsc, *lhsp;
4772 unsigned j;
4773 get_constraint_for (op, &lhsc);
4774 rhsc.var = nonlocal_id;
4775 rhsc.offset = 0;
4776 rhsc.type = SCALAR;
f1f41a6c 4777 FOR_EACH_VEC_ELT (lhsc, j, lhsp)
dd277d48 4778 process_constraint (new_constraint (*lhsp, rhsc));
f1f41a6c 4779 lhsc.release ();
dd277d48 4780 }
0b3bf4d6 4781 }
75a70cf9 4782 for (i = 0; i < gimple_asm_ninputs (t); ++i)
0b3bf4d6 4783 {
dd277d48 4784 tree link = gimple_asm_input_op (t, i);
4785 tree op = TREE_VALUE (link);
4786
4787 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
4788
4789 parse_input_constraint (&constraint, 0, 0, noutputs, 0, oconstraints,
4790 &allows_mem, &allows_reg);
4791
4792 /* A memory constraint makes the address of the operand escape. */
4793 if (!allows_reg && allows_mem)
4794 make_escape_constraint (build_fold_addr_expr (op));
4795 /* Strictly we'd only need the constraint to ESCAPED if
c4ec6aca 4796 the asm clobbers memory, otherwise using something
4797 along the lines of per-call clobbers/uses would be enough. */
e856db01 4798 else if (op)
0b3bf4d6 4799 make_escape_constraint (op);
4800 }
4801 }
4802
f1f41a6c 4803 rhsc.release ();
4804 lhsc.release ();
29fd4364 4805}
4806
4807
1a981e1a 4808/* Create a constraint adding to the clobber set of FI the memory
4809 pointed to by PTR. */
4810
4811static void
4812process_ipa_clobber (varinfo_t fi, tree ptr)
4813{
1e094109 4814 vec<ce_s> ptrc = vNULL;
1a981e1a 4815 struct constraint_expr *c, lhs;
4816 unsigned i;
59b12eb5 4817 get_constraint_for_rhs (ptr, &ptrc);
1a981e1a 4818 lhs = get_function_part_constraint (fi, fi_clobbers);
f1f41a6c 4819 FOR_EACH_VEC_ELT (ptrc, i, c)
1a981e1a 4820 process_constraint (new_constraint (lhs, *c));
f1f41a6c 4821 ptrc.release ();
1a981e1a 4822}
4823
4824/* Walk statement T setting up clobber and use constraints according to the
4825 references found in T. This function is a main part of the
4826 IPA constraint builder. */
4827
4828static void
4829find_func_clobbers (gimple origt)
4830{
4831 gimple t = origt;
1e094109 4832 vec<ce_s> lhsc = vNULL;
4833 vec<ce_s> rhsc = vNULL;
1a981e1a 4834 varinfo_t fi;
4835
4836 /* Add constraints for clobbered/used in IPA mode.
4837 We are not interested in what automatic variables are clobbered
4838 or used as we only use the information in the caller to which
4839 they do not escape. */
4840 gcc_assert (in_ipa_mode);
4841
4842 /* If the stmt refers to memory in any way it better had a VUSE. */
4843 if (gimple_vuse (t) == NULL_TREE)
4844 return;
4845
4846 /* We'd better have function information for the current function. */
4847 fi = lookup_vi_for_tree (cfun->decl);
4848 gcc_assert (fi != NULL);
4849
4850 /* Account for stores in assignments and calls. */
4851 if (gimple_vdef (t) != NULL_TREE
4852 && gimple_has_lhs (t))
4853 {
4854 tree lhs = gimple_get_lhs (t);
4855 tree tem = lhs;
4856 while (handled_component_p (tem))
4857 tem = TREE_OPERAND (tem, 0);
4858 if ((DECL_P (tem)
4859 && !auto_var_in_fn_p (tem, cfun->decl))
182cf5a9 4860 || INDIRECT_REF_P (tem)
4861 || (TREE_CODE (tem) == MEM_REF
4862 && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
4863 && auto_var_in_fn_p
4864 (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), cfun->decl))))
1a981e1a 4865 {
4866 struct constraint_expr lhsc, *rhsp;
4867 unsigned i;
4868 lhsc = get_function_part_constraint (fi, fi_clobbers);
4869 get_constraint_for_address_of (lhs, &rhsc);
f1f41a6c 4870 FOR_EACH_VEC_ELT (rhsc, i, rhsp)
1a981e1a 4871 process_constraint (new_constraint (lhsc, *rhsp));
f1f41a6c 4872 rhsc.release ();
1a981e1a 4873 }
4874 }
4875
4876 /* Account for uses in assigments and returns. */
4877 if (gimple_assign_single_p (t)
4878 || (gimple_code (t) == GIMPLE_RETURN
4879 && gimple_return_retval (t) != NULL_TREE))
4880 {
4881 tree rhs = (gimple_assign_single_p (t)
4882 ? gimple_assign_rhs1 (t) : gimple_return_retval (t));
4883 tree tem = rhs;
4884 while (handled_component_p (tem))
4885 tem = TREE_OPERAND (tem, 0);
4886 if ((DECL_P (tem)
4887 && !auto_var_in_fn_p (tem, cfun->decl))
182cf5a9 4888 || INDIRECT_REF_P (tem)
4889 || (TREE_CODE (tem) == MEM_REF
4890 && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
4891 && auto_var_in_fn_p
4892 (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), cfun->decl))))
1a981e1a 4893 {
4894 struct constraint_expr lhs, *rhsp;
4895 unsigned i;
4896 lhs = get_function_part_constraint (fi, fi_uses);
4897 get_constraint_for_address_of (rhs, &rhsc);
f1f41a6c 4898 FOR_EACH_VEC_ELT (rhsc, i, rhsp)
1a981e1a 4899 process_constraint (new_constraint (lhs, *rhsp));
f1f41a6c 4900 rhsc.release ();
1a981e1a 4901 }
4902 }
4903
4904 if (is_gimple_call (t))
4905 {
4906 varinfo_t cfi = NULL;
4907 tree decl = gimple_call_fndecl (t);
4908 struct constraint_expr lhs, rhs;
4909 unsigned i, j;
4910
4911 /* For builtins we do not have separate function info. For those
4912 we do not generate escapes for we have to generate clobbers/uses. */
789a8d72 4913 if (gimple_call_builtin_p (t, BUILT_IN_NORMAL))
1a981e1a 4914 switch (DECL_FUNCTION_CODE (decl))
4915 {
4916 /* The following functions use and clobber memory pointed to
4917 by their arguments. */
4918 case BUILT_IN_STRCPY:
4919 case BUILT_IN_STRNCPY:
4920 case BUILT_IN_BCOPY:
4921 case BUILT_IN_MEMCPY:
4922 case BUILT_IN_MEMMOVE:
4923 case BUILT_IN_MEMPCPY:
4924 case BUILT_IN_STPCPY:
4925 case BUILT_IN_STPNCPY:
4926 case BUILT_IN_STRCAT:
4927 case BUILT_IN_STRNCAT:
939514e9 4928 case BUILT_IN_STRCPY_CHK:
4929 case BUILT_IN_STRNCPY_CHK:
4930 case BUILT_IN_MEMCPY_CHK:
4931 case BUILT_IN_MEMMOVE_CHK:
4932 case BUILT_IN_MEMPCPY_CHK:
4933 case BUILT_IN_STPCPY_CHK:
1063acde 4934 case BUILT_IN_STPNCPY_CHK:
939514e9 4935 case BUILT_IN_STRCAT_CHK:
4936 case BUILT_IN_STRNCAT_CHK:
1a981e1a 4937 {
4938 tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
4939 == BUILT_IN_BCOPY ? 1 : 0));
4940 tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
4941 == BUILT_IN_BCOPY ? 0 : 1));
4942 unsigned i;
4943 struct constraint_expr *rhsp, *lhsp;
4944 get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
4945 lhs = get_function_part_constraint (fi, fi_clobbers);
f1f41a6c 4946 FOR_EACH_VEC_ELT (lhsc, i, lhsp)
1a981e1a 4947 process_constraint (new_constraint (lhs, *lhsp));
f1f41a6c 4948 lhsc.release ();
1a981e1a 4949 get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
4950 lhs = get_function_part_constraint (fi, fi_uses);
f1f41a6c 4951 FOR_EACH_VEC_ELT (rhsc, i, rhsp)
1a981e1a 4952 process_constraint (new_constraint (lhs, *rhsp));
f1f41a6c 4953 rhsc.release ();
1a981e1a 4954 return;
4955 }
4956 /* The following function clobbers memory pointed to by
4957 its argument. */
4958 case BUILT_IN_MEMSET:
939514e9 4959 case BUILT_IN_MEMSET_CHK:
1a981e1a 4960 {
4961 tree dest = gimple_call_arg (t, 0);
4962 unsigned i;
4963 ce_s *lhsp;
4964 get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
4965 lhs = get_function_part_constraint (fi, fi_clobbers);
f1f41a6c 4966 FOR_EACH_VEC_ELT (lhsc, i, lhsp)
1a981e1a 4967 process_constraint (new_constraint (lhs, *lhsp));
f1f41a6c 4968 lhsc.release ();
1a981e1a 4969 return;
4970 }
4971 /* The following functions clobber their second and third
4972 arguments. */
4973 case BUILT_IN_SINCOS:
4974 case BUILT_IN_SINCOSF:
4975 case BUILT_IN_SINCOSL:
4976 {
4977 process_ipa_clobber (fi, gimple_call_arg (t, 1));
4978 process_ipa_clobber (fi, gimple_call_arg (t, 2));
4979 return;
4980 }
4981 /* The following functions clobber their second argument. */
4982 case BUILT_IN_FREXP:
4983 case BUILT_IN_FREXPF:
4984 case BUILT_IN_FREXPL:
4985 case BUILT_IN_LGAMMA_R:
4986 case BUILT_IN_LGAMMAF_R:
4987 case BUILT_IN_LGAMMAL_R:
4988 case BUILT_IN_GAMMA_R:
4989 case BUILT_IN_GAMMAF_R:
4990 case BUILT_IN_GAMMAL_R:
4991 case BUILT_IN_MODF:
4992 case BUILT_IN_MODFF:
4993 case BUILT_IN_MODFL:
4994 {
4995 process_ipa_clobber (fi, gimple_call_arg (t, 1));
4996 return;
4997 }
4998 /* The following functions clobber their third argument. */
4999 case BUILT_IN_REMQUO:
5000 case BUILT_IN_REMQUOF:
5001 case BUILT_IN_REMQUOL:
5002 {
5003 process_ipa_clobber (fi, gimple_call_arg (t, 2));
5004 return;
5005 }
5006 /* The following functions neither read nor clobber memory. */
fca0886c 5007 case BUILT_IN_ASSUME_ALIGNED:
1a981e1a 5008 case BUILT_IN_FREE:
5009 return;
5010 /* Trampolines are of no interest to us. */
5011 case BUILT_IN_INIT_TRAMPOLINE:
5012 case BUILT_IN_ADJUST_TRAMPOLINE:
5013 return;
5014 case BUILT_IN_VA_START:
5015 case BUILT_IN_VA_END:
5016 return;
5017 /* printf-style functions may have hooks to set pointers to
5018 point to somewhere into the generated string. Leave them
c31fb425 5019 for a later exercise... */
1a981e1a 5020 default:
5021 /* Fallthru to general call handling. */;
5022 }
5023
5024 /* Parameters passed by value are used. */
5025 lhs = get_function_part_constraint (fi, fi_uses);
5026 for (i = 0; i < gimple_call_num_args (t); i++)
5027 {
5028 struct constraint_expr *rhsp;
5029 tree arg = gimple_call_arg (t, i);
5030
5031 if (TREE_CODE (arg) == SSA_NAME
5032 || is_gimple_min_invariant (arg))
5033 continue;
5034
5035 get_constraint_for_address_of (arg, &rhsc);
f1f41a6c 5036 FOR_EACH_VEC_ELT (rhsc, j, rhsp)
1a981e1a 5037 process_constraint (new_constraint (lhs, *rhsp));
f1f41a6c 5038 rhsc.release ();
1a981e1a 5039 }
5040
5041 /* Build constraints for propagating clobbers/uses along the
5042 callgraph edges. */
5043 cfi = get_fi_for_callee (t);
5044 if (cfi->id == anything_id)
5045 {
5046 if (gimple_vdef (t))
5047 make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
5048 anything_id);
5049 make_constraint_from (first_vi_for_offset (fi, fi_uses),
5050 anything_id);
5051 return;
5052 }
5053
5054 /* For callees without function info (that's external functions),
5055 ESCAPED is clobbered and used. */
5056 if (gimple_call_fndecl (t)
5057 && !cfi->is_fn_info)
5058 {
5059 varinfo_t vi;
5060
5061 if (gimple_vdef (t))
5062 make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
5063 escaped_id);
5064 make_copy_constraint (first_vi_for_offset (fi, fi_uses), escaped_id);
5065
5066 /* Also honor the call statement use/clobber info. */
5067 if ((vi = lookup_call_clobber_vi (t)) != NULL)
5068 make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
5069 vi->id);
5070 if ((vi = lookup_call_use_vi (t)) != NULL)
5071 make_copy_constraint (first_vi_for_offset (fi, fi_uses),
5072 vi->id);
5073 return;
5074 }
5075
5076 /* Otherwise the caller clobbers and uses what the callee does.
5077 ??? This should use a new complex constraint that filters
5078 local variables of the callee. */
5079 if (gimple_vdef (t))
5080 {
5081 lhs = get_function_part_constraint (fi, fi_clobbers);
5082 rhs = get_function_part_constraint (cfi, fi_clobbers);
5083 process_constraint (new_constraint (lhs, rhs));
5084 }
5085 lhs = get_function_part_constraint (fi, fi_uses);
5086 rhs = get_function_part_constraint (cfi, fi_uses);
5087 process_constraint (new_constraint (lhs, rhs));
5088 }
5089 else if (gimple_code (t) == GIMPLE_ASM)
5090 {
5091 /* ??? Ick. We can do better. */
5092 if (gimple_vdef (t))
5093 make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
5094 anything_id);
5095 make_constraint_from (first_vi_for_offset (fi, fi_uses),
5096 anything_id);
5097 }
5098
f1f41a6c 5099 rhsc.release ();
1a981e1a 5100}
5101
5102
29fd4364 5103/* Find the first varinfo in the same variable as START that overlaps with
dd277d48 5104 OFFSET. Return NULL if we can't find one. */
29fd4364 5105
7d1f52b2 5106static varinfo_t
29fd4364 5107first_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset)
5108{
dd277d48 5109 /* If the offset is outside of the variable, bail out. */
5110 if (offset >= start->fullsize)
5111 return NULL;
5112
5113 /* If we cannot reach offset from start, lookup the first field
5114 and start from there. */
5115 if (start->offset > offset)
5a950977 5116 start = get_varinfo (start->head);
dd277d48 5117
5118 while (start)
29fd4364 5119 {
5120 /* We may not find a variable in the field list with the actual
5121 offset when when we have glommed a structure to a variable.
5122 In that case, however, offset should still be within the size
5123 of the variable. */
dd277d48 5124 if (offset >= start->offset
4bfcb72d 5125 && (offset - start->offset) < start->size)
dd277d48 5126 return start;
5127
5a950977 5128 start = vi_next (start);
29fd4364 5129 }
dd277d48 5130
ff77282c 5131 return NULL;
29fd4364 5132}
5133
dd277d48 5134/* Find the first varinfo in the same variable as START that overlaps with
5135 OFFSET. If there is no such varinfo the varinfo directly preceding
5136 OFFSET is returned. */
5137
5138static varinfo_t
5139first_or_preceding_vi_for_offset (varinfo_t start,
5140 unsigned HOST_WIDE_INT offset)
5141{
5142 /* If we cannot reach offset from start, lookup the first field
5143 and start from there. */
5144 if (start->offset > offset)
5a950977 5145 start = get_varinfo (start->head);
dd277d48 5146
5147 /* We may not find a variable in the field list with the actual
5148 offset when when we have glommed a structure to a variable.
5149 In that case, however, offset should still be within the size
5150 of the variable.
5151 If we got beyond the offset we look for return the field
5152 directly preceding offset which may be the last field. */
5153 while (start->next
5154 && offset >= start->offset
4bfcb72d 5155 && !((offset - start->offset) < start->size))
5a950977 5156 start = vi_next (start);
dd277d48 5157
5158 return start;
5159}
5160
29fd4364 5161
3423d8f7 5162/* This structure is used during pushing fields onto the fieldstack
5163 to track the offset of the field, since bitpos_of_field gives it
5164 relative to its immediate containing type, and we want it relative
5165 to the ultimate containing object. */
5166
5167struct fieldoff
5168{
9bdfd02b 5169 /* Offset from the base of the base containing object to this field. */
5170 HOST_WIDE_INT offset;
3423d8f7 5171
5172 /* Size, in bits, of the field. */
9bdfd02b 5173 unsigned HOST_WIDE_INT size;
3423d8f7 5174
9bdfd02b 5175 unsigned has_unknown_size : 1;
3423d8f7 5176
e856db01 5177 unsigned must_have_pointers : 1;
5178
9bdfd02b 5179 unsigned may_have_pointers : 1;
1c1f1bc0 5180
5181 unsigned only_restrict_pointers : 1;
3423d8f7 5182};
5183typedef struct fieldoff fieldoff_s;
5184
3423d8f7 5185
29fd4364 5186/* qsort comparison function for two fieldoff's PA and PB */
5187
7d1f52b2 5188static int
29fd4364 5189fieldoff_compare (const void *pa, const void *pb)
5190{
5191 const fieldoff_s *foa = (const fieldoff_s *)pa;
5192 const fieldoff_s *fob = (const fieldoff_s *)pb;
d2864a71 5193 unsigned HOST_WIDE_INT foasize, fobsize;
7d1f52b2 5194
d2864a71 5195 if (foa->offset < fob->offset)
5196 return -1;
5197 else if (foa->offset > fob->offset)
5198 return 1;
29fd4364 5199
9bdfd02b 5200 foasize = foa->size;
5201 fobsize = fob->size;
d2864a71 5202 if (foasize < fobsize)
9bdfd02b 5203 return -1;
d2864a71 5204 else if (foasize > fobsize)
5205 return 1;
5206 return 0;
29fd4364 5207}
5208
5209/* Sort a fieldstack according to the field offset and sizes. */
3423d8f7 5210static void
f1f41a6c 5211sort_fieldstack (vec<fieldoff_s> fieldstack)
29fd4364 5212{
f1f41a6c 5213 fieldstack.qsort (fieldoff_compare);
29fd4364 5214}
5215
b4c39a37 5216/* Return true if T is a type that can have subvars. */
5217
5218static inline bool
5219type_can_have_subvars (const_tree t)
5220{
5221 /* Aggregates without overlapping fields can have subvars. */
5222 return TREE_CODE (t) == RECORD_TYPE;
5223}
5224
3423d8f7 5225/* Return true if V is a tree that we can have subvars for.
5226 Normally, this is any aggregate type. Also complex
5227 types which are not gimple registers can have subvars. */
5228
5229static inline bool
5230var_can_have_subvars (const_tree v)
5231{
5232 /* Volatile variables should never have subvars. */
5233 if (TREE_THIS_VOLATILE (v))
5234 return false;
5235
5236 /* Non decls or memory tags can never have subvars. */
dd277d48 5237 if (!DECL_P (v))
3423d8f7 5238 return false;
5239
b4c39a37 5240 return type_can_have_subvars (TREE_TYPE (v));
3423d8f7 5241}
5242
e856db01 5243/* Return true if T is a type that does contain pointers. */
5244
5245static bool
5246type_must_have_pointers (tree type)
5247{
5248 if (POINTER_TYPE_P (type))
5249 return true;
5250
5251 if (TREE_CODE (type) == ARRAY_TYPE)
5252 return type_must_have_pointers (TREE_TYPE (type));
5253
5254 /* A function or method can have pointers as arguments, so track
5255 those separately. */
5256 if (TREE_CODE (type) == FUNCTION_TYPE
5257 || TREE_CODE (type) == METHOD_TYPE)
5258 return true;
5259
5260 return false;
5261}
5262
5263static bool
5264field_must_have_pointers (tree t)
5265{
5266 return type_must_have_pointers (TREE_TYPE (t));
5267}
5268
18346ecd 5269/* Given a TYPE, and a vector of field offsets FIELDSTACK, push all
5270 the fields of TYPE onto fieldstack, recording their offsets along
5271 the way.
5272
5273 OFFSET is used to keep track of the offset in this entire
5274 structure, rather than just the immediately containing structure.
d812977b 5275 Returns false if the caller is supposed to handle the field we
5276 recursed for. */
29fd4364 5277
d812977b 5278static bool
f1f41a6c 5279push_fields_onto_fieldstack (tree type, vec<fieldoff_s> *fieldstack,
e856db01 5280 HOST_WIDE_INT offset)
29fd4364 5281{
5282 tree field;
d812977b 5283 bool empty_p = true;
3423d8f7 5284
5285 if (TREE_CODE (type) != RECORD_TYPE)
d812977b 5286 return false;
454a1307 5287
5288 /* If the vector of fields is growing too big, bail out early.
f1f41a6c 5289 Callers check for vec::length <= MAX_FIELDS_FOR_FIELD_SENSITIVE, make
454a1307 5290 sure this fails. */
f1f41a6c 5291 if (fieldstack->length () > MAX_FIELDS_FOR_FIELD_SENSITIVE)
d812977b 5292 return false;
7d1f52b2 5293
1767a056 5294 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
3423d8f7 5295 if (TREE_CODE (field) == FIELD_DECL)
5296 {
5297 bool push = false;
9bdfd02b 5298 HOST_WIDE_INT foff = bitpos_of_field (field);
3423d8f7 5299
9bdfd02b 5300 if (!var_can_have_subvars (field)
5301 || TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
5302 || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
3423d8f7 5303 push = true;
d812977b 5304 else if (!push_fields_onto_fieldstack
e856db01 5305 (TREE_TYPE (field), fieldstack, offset + foff)
3423d8f7 5306 && (DECL_SIZE (field)
5307 && !integer_zerop (DECL_SIZE (field))))
5308 /* Empty structures may have actual size, like in C++. So
5309 see if we didn't push any subfields and the size is
5310 nonzero, push the field onto the stack. */
5311 push = true;
5312
5313 if (push)
29fd4364 5314 {
9bdfd02b 5315 fieldoff_s *pair = NULL;
5316 bool has_unknown_size = false;
e856db01 5317 bool must_have_pointers_p;
9bdfd02b 5318
f1f41a6c 5319 if (!fieldstack->is_empty ())
5320 pair = &fieldstack->last ();
9bdfd02b 5321
f82bdab4 5322 /* If there isn't anything at offset zero, create sth. */
5323 if (!pair
5324 && offset + foff != 0)
5325 {
e82e4eb5 5326 fieldoff_s e = {0, offset + foff, false, false, false, false};
f1f41a6c 5327 pair = fieldstack->safe_push (e);
f82bdab4 5328 }
5329
9bdfd02b 5330 if (!DECL_SIZE (field)
5331 || !host_integerp (DECL_SIZE (field), 1))
5332 has_unknown_size = true;
5333
5334 /* If adjacent fields do not contain pointers merge them. */
e856db01 5335 must_have_pointers_p = field_must_have_pointers (field);
9bdfd02b 5336 if (pair
9bdfd02b 5337 && !has_unknown_size
7a3ffe99 5338 && !must_have_pointers_p
e856db01 5339 && !pair->must_have_pointers
5340 && !pair->has_unknown_size
5341 && pair->offset + (HOST_WIDE_INT)pair->size == offset + foff)
9bdfd02b 5342 {
9bdfd02b 5343 pair->size += TREE_INT_CST_LOW (DECL_SIZE (field));
5344 }
5345 else
5346 {
e82e4eb5 5347 fieldoff_s e;
5348 e.offset = offset + foff;
5349 e.has_unknown_size = has_unknown_size;
9bdfd02b 5350 if (!has_unknown_size)
e82e4eb5 5351 e.size = TREE_INT_CST_LOW (DECL_SIZE (field));
9bdfd02b 5352 else
e82e4eb5 5353 e.size = -1;
5354 e.must_have_pointers = must_have_pointers_p;
5355 e.may_have_pointers = true;
5356 e.only_restrict_pointers
1c1f1bc0 5357 = (!has_unknown_size
5358 && POINTER_TYPE_P (TREE_TYPE (field))
5359 && TYPE_RESTRICT (TREE_TYPE (field)));
f1f41a6c 5360 fieldstack->safe_push (e);
9bdfd02b 5361 }
3423d8f7 5362 }
d812977b 5363
5364 empty_p = false;
3423d8f7 5365 }
29fd4364 5366
d812977b 5367 return !empty_p;
29fd4364 5368}
5369
dd277d48 5370/* Count the number of arguments DECL has, and set IS_VARARGS to true
5371 if it is a varargs function. */
5372
5373static unsigned int
5374count_num_arguments (tree decl, bool *is_varargs)
5375{
4bfcb72d 5376 unsigned int num = 0;
dd277d48 5377 tree t;
5378
4bfcb72d 5379 /* Capture named arguments for K&R functions. They do not
5380 have a prototype and thus no TYPE_ARG_TYPES. */
1767a056 5381 for (t = DECL_ARGUMENTS (decl); t; t = DECL_CHAIN (t))
4bfcb72d 5382 ++num;
7d1f52b2 5383
4bfcb72d 5384 /* Check if the function has variadic arguments. */
5385 for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
5386 if (TREE_VALUE (t) == void_type_node)
5387 break;
db026f5c 5388 if (!t)
5389 *is_varargs = true;
4bfcb72d 5390
5391 return num;
db026f5c 5392}
5393
5394/* Creation function node for DECL, using NAME, and return the index
5395 of the variable we've created for the function. */
5396
7981828b 5397static varinfo_t
db026f5c 5398create_function_info_for (tree decl, const char *name)
5399{
1a981e1a 5400 struct function *fn = DECL_STRUCT_FUNCTION (decl);
5401 varinfo_t vi, prev_vi;
7d1f52b2 5402 tree arg;
db026f5c 5403 unsigned int i;
5404 bool is_varargs = false;
1a981e1a 5405 unsigned int num_args = count_num_arguments (decl, &is_varargs);
db026f5c 5406
5407 /* Create the variable info. */
5408
97709d23 5409 vi = new_var_info (decl, name);
db026f5c 5410 vi->offset = 0;
db026f5c 5411 vi->size = 1;
1a981e1a 5412 vi->fullsize = fi_parm_base + num_args;
5413 vi->is_fn_info = 1;
5414 vi->may_have_pointers = false;
5415 if (is_varargs)
5416 vi->fullsize = ~0;
8a3fd8a7 5417 insert_vi_for_tree (vi->decl, vi);
db026f5c 5418
1a981e1a 5419 prev_vi = vi;
5420
5421 /* Create a variable for things the function clobbers and one for
5422 things the function uses. */
db026f5c 5423 {
1a981e1a 5424 varinfo_t clobbervi, usevi;
5425 const char *newname;
5426 char *tempname;
5427
5428 asprintf (&tempname, "%s.clobber", name);
5429 newname = ggc_strdup (tempname);
5430 free (tempname);
5431
5432 clobbervi = new_var_info (NULL, newname);
5433 clobbervi->offset = fi_clobbers;
5434 clobbervi->size = 1;
5435 clobbervi->fullsize = vi->fullsize;
5436 clobbervi->is_full_var = true;
5437 clobbervi->is_global_var = false;
5438 gcc_assert (prev_vi->offset < clobbervi->offset);
5a950977 5439 prev_vi->next = clobbervi->id;
1a981e1a 5440 prev_vi = clobbervi;
1a981e1a 5441
5442 asprintf (&tempname, "%s.use", name);
5443 newname = ggc_strdup (tempname);
5444 free (tempname);
5445
5446 usevi = new_var_info (NULL, newname);
5447 usevi->offset = fi_uses;
5448 usevi->size = 1;
5449 usevi->fullsize = vi->fullsize;
5450 usevi->is_full_var = true;
5451 usevi->is_global_var = false;
5452 gcc_assert (prev_vi->offset < usevi->offset);
5a950977 5453 prev_vi->next = usevi->id;
1a981e1a 5454 prev_vi = usevi;
db026f5c 5455 }
5456
1a981e1a 5457 /* And one for the static chain. */
5458 if (fn->static_chain_decl != NULL_TREE)
5459 {
5460 varinfo_t chainvi;
5461 const char *newname;
5462 char *tempname;
5463
5464 asprintf (&tempname, "%s.chain", name);
5465 newname = ggc_strdup (tempname);
5466 free (tempname);
5467
5468 chainvi = new_var_info (fn->static_chain_decl, newname);
5469 chainvi->offset = fi_static_chain;
5470 chainvi->size = 1;
5471 chainvi->fullsize = vi->fullsize;
5472 chainvi->is_full_var = true;
5473 chainvi->is_global_var = false;
5474 gcc_assert (prev_vi->offset < chainvi->offset);
5a950977 5475 prev_vi->next = chainvi->id;
1a981e1a 5476 prev_vi = chainvi;
1a981e1a 5477 insert_vi_for_tree (fn->static_chain_decl, chainvi);
5478 }
5479
5480 /* Create a variable for the return var. */
5481 if (DECL_RESULT (decl) != NULL
5482 || !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
5483 {
5484 varinfo_t resultvi;
5485 const char *newname;
5486 char *tempname;
5487 tree resultdecl = decl;
5488
5489 if (DECL_RESULT (decl))
5490 resultdecl = DECL_RESULT (decl);
5491
5492 asprintf (&tempname, "%s.result", name);
5493 newname = ggc_strdup (tempname);
5494 free (tempname);
5495
5496 resultvi = new_var_info (resultdecl, newname);
5497 resultvi->offset = fi_result;
5498 resultvi->size = 1;
5499 resultvi->fullsize = vi->fullsize;
5500 resultvi->is_full_var = true;
5501 if (DECL_RESULT (decl))
e856db01 5502 resultvi->may_have_pointers = true;
1a981e1a 5503 gcc_assert (prev_vi->offset < resultvi->offset);
5a950977 5504 prev_vi->next = resultvi->id;
1a981e1a 5505 prev_vi = resultvi;
1a981e1a 5506 if (DECL_RESULT (decl))
5507 insert_vi_for_tree (DECL_RESULT (decl), resultvi);
5508 }
db026f5c 5509
191ec5a2 5510 /* Set up variables for each argument. */
1a981e1a 5511 arg = DECL_ARGUMENTS (decl);
5512 for (i = 0; i < num_args; i++)
7d1f52b2 5513 {
db026f5c 5514 varinfo_t argvi;
5515 const char *newname;
5516 char *tempname;
db026f5c 5517 tree argdecl = decl;
5518
5519 if (arg)
5520 argdecl = arg;
7d1f52b2 5521
1a981e1a 5522 asprintf (&tempname, "%s.arg%d", name, i);
db026f5c 5523 newname = ggc_strdup (tempname);
5524 free (tempname);
5525
97709d23 5526 argvi = new_var_info (argdecl, newname);
1a981e1a 5527 argvi->offset = fi_parm_base + i;
db026f5c 5528 argvi->size = 1;
57e6b870 5529 argvi->is_full_var = true;
db026f5c 5530 argvi->fullsize = vi->fullsize;
1a981e1a 5531 if (arg)
e856db01 5532 argvi->may_have_pointers = true;
1a981e1a 5533 gcc_assert (prev_vi->offset < argvi->offset);
5a950977 5534 prev_vi->next = argvi->id;
1a981e1a 5535 prev_vi = argvi;
db026f5c 5536 if (arg)
5537 {
8a3fd8a7 5538 insert_vi_for_tree (arg, argvi);
1767a056 5539 arg = DECL_CHAIN (arg);
db026f5c 5540 }
5541 }
bdf4f142 5542
1a981e1a 5543 /* Add one representative for all further args. */
5544 if (is_varargs)
db026f5c 5545 {
1a981e1a 5546 varinfo_t argvi;
db026f5c 5547 const char *newname;
5548 char *tempname;
1a981e1a 5549 tree decl;
7d1f52b2 5550
1a981e1a 5551 asprintf (&tempname, "%s.varargs", name);
db026f5c 5552 newname = ggc_strdup (tempname);
5553 free (tempname);
5554
1a981e1a 5555 /* We need sth that can be pointed to for va_start. */
e44576dd 5556 decl = build_fake_var_decl (ptr_type_node);
1a981e1a 5557
5558 argvi = new_var_info (decl, newname);
5559 argvi->offset = fi_parm_base + num_args;
5560 argvi->size = ~0;
5561 argvi->is_full_var = true;
5562 argvi->is_heap_var = true;
5563 argvi->fullsize = vi->fullsize;
5564 gcc_assert (prev_vi->offset < argvi->offset);
5a950977 5565 prev_vi->next = argvi->id;
1a981e1a 5566 prev_vi = argvi;
db026f5c 5567 }
97709d23 5568
7981828b 5569 return vi;
7d1f52b2 5570}
db026f5c 5571
bb7e787c 5572
7d1f52b2 5573/* Return true if FIELDSTACK contains fields that overlap.
bb7e787c 5574 FIELDSTACK is assumed to be sorted by offset. */
5575
5576static bool
f1f41a6c 5577check_for_overlaps (vec<fieldoff_s> fieldstack)
bb7e787c 5578{
5579 fieldoff_s *fo = NULL;
5580 unsigned int i;
208a7c09 5581 HOST_WIDE_INT lastoffset = -1;
bb7e787c 5582
f1f41a6c 5583 FOR_EACH_VEC_ELT (fieldstack, i, fo)
bb7e787c 5584 {
5585 if (fo->offset == lastoffset)
5586 return true;
5587 lastoffset = fo->offset;
5588 }
5589 return false;
5590}
499be8ef 5591
29fd4364 5592/* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
5593 This will also create any varinfo structures necessary for fields
5594 of DECL. */
5595
d812977b 5596static varinfo_t
5597create_variable_info_for_1 (tree decl, const char *name)
29fd4364 5598{
d812977b 5599 varinfo_t vi, newvi;
f4e36c33 5600 tree decl_type = TREE_TYPE (decl);
5601 tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type);
1e094109 5602 vec<fieldoff_s> fieldstack = vNULL;
d812977b 5603 fieldoff_s *fo;
5604 unsigned int i;
7d1f52b2 5605
db026f5c 5606 if (!declsize
9bdfd02b 5607 || !host_integerp (declsize, 1))
29fd4364 5608 {
d812977b 5609 vi = new_var_info (decl, name);
5610 vi->offset = 0;
29fd4364 5611 vi->size = ~0;
d812977b 5612 vi->fullsize = ~0;
5613 vi->is_unknown_size_var = true;
5614 vi->is_full_var = true;
e856db01 5615 vi->may_have_pointers = true;
d812977b 5616 return vi;
29fd4364 5617 }
d812977b 5618
5619 /* Collect field information. */
5620 if (use_field_sensitive
5621 && var_can_have_subvars (decl)
5622 /* ??? Force us to not use subfields for global initializers
5623 in IPA mode. Else we'd have to parse arbitrary initializers. */
5624 && !(in_ipa_mode
5625 && is_global_var (decl)
5626 && DECL_INITIAL (decl)))
29fd4364 5627 {
d812977b 5628 fieldoff_s *fo = NULL;
5629 bool notokay = false;
5630 unsigned int i;
5631
e856db01 5632 push_fields_onto_fieldstack (decl_type, &fieldstack, 0);
d812977b 5633
f1f41a6c 5634 for (i = 0; !notokay && fieldstack.iterate (i, &fo); i++)
d812977b 5635 if (fo->has_unknown_size
5636 || fo->offset < 0)
5637 {
5638 notokay = true;
5639 break;
5640 }
5641
5642 /* We can't sort them if we have a field with a variable sized type,
5643 which will make notokay = true. In that case, we are going to return
5644 without creating varinfos for the fields anyway, so sorting them is a
5645 waste to boot. */
5646 if (!notokay)
5647 {
5648 sort_fieldstack (fieldstack);
5649 /* Due to some C++ FE issues, like PR 22488, we might end up
5650 what appear to be overlapping fields even though they,
5651 in reality, do not overlap. Until the C++ FE is fixed,
5652 we will simply disable field-sensitivity for these cases. */
5653 notokay = check_for_overlaps (fieldstack);
5654 }
5655
5656 if (notokay)
f1f41a6c 5657 fieldstack.release ();
d812977b 5658 }
5659
5660 /* If we didn't end up collecting sub-variables create a full
5661 variable for the decl. */
f1f41a6c 5662 if (fieldstack.length () <= 1
5663 || fieldstack.length () > MAX_FIELDS_FOR_FIELD_SENSITIVE)
d812977b 5664 {
5665 vi = new_var_info (decl, name);
5666 vi->offset = 0;
e856db01 5667 vi->may_have_pointers = true;
db026f5c 5668 vi->fullsize = TREE_INT_CST_LOW (declsize);
29fd4364 5669 vi->size = vi->fullsize;
d812977b 5670 vi->is_full_var = true;
f1f41a6c 5671 fieldstack.release ();
d812977b 5672 return vi;
29fd4364 5673 }
7d1f52b2 5674
d812977b 5675 vi = new_var_info (decl, name);
5676 vi->fullsize = TREE_INT_CST_LOW (declsize);
5677 for (i = 0, newvi = vi;
f1f41a6c 5678 fieldstack.iterate (i, &fo);
5a950977 5679 ++i, newvi = vi_next (newvi))
d812977b 5680 {
5681 const char *newname = "NULL";
5682 char *tempname;
5683
5684 if (dump_file)
5685 {
5686 asprintf (&tempname, "%s." HOST_WIDE_INT_PRINT_DEC
5687 "+" HOST_WIDE_INT_PRINT_DEC, name, fo->offset, fo->size);
5688 newname = ggc_strdup (tempname);
5689 free (tempname);
5690 }
5691 newvi->name = newname;
5692 newvi->offset = fo->offset;
5693 newvi->size = fo->size;
5694 newvi->fullsize = vi->fullsize;
5695 newvi->may_have_pointers = fo->may_have_pointers;
5696 newvi->only_restrict_pointers = fo->only_restrict_pointers;
f1f41a6c 5697 if (i + 1 < fieldstack.length ())
5a950977 5698 {
5699 varinfo_t tem = new_var_info (decl, name);
5700 newvi->next = tem->id;
5701 tem->head = vi->id;
5702 }
d812977b 5703 }
5704
f1f41a6c 5705 fieldstack.release ();
1a981e1a 5706
d812977b 5707 return vi;
5708}
5709
5710static unsigned int
5711create_variable_info_for (tree decl, const char *name)
5712{
5713 varinfo_t vi = create_variable_info_for_1 (decl, name);
5714 unsigned int id = vi->id;
5715
5716 insert_vi_for_tree (decl, vi);
5717
841e98fa 5718 if (TREE_CODE (decl) != VAR_DECL)
5719 return id;
5720
d812977b 5721 /* Create initial constraints for globals. */
5a950977 5722 for (; vi; vi = vi_next (vi))
20283a99 5723 {
d812977b 5724 if (!vi->may_have_pointers
5725 || !vi->is_global_var)
5726 continue;
5727
1a981e1a 5728 /* Mark global restrict qualified pointers. */
d812977b 5729 if ((POINTER_TYPE_P (TREE_TYPE (decl))
5730 && TYPE_RESTRICT (TREE_TYPE (decl)))
5731 || vi->only_restrict_pointers)
6fc56905 5732 {
5733 make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT");
5734 continue;
5735 }
1a981e1a 5736
841e98fa 5737 /* In non-IPA mode the initializer from nonlocal is all we need. */
1a981e1a 5738 if (!in_ipa_mode
841e98fa 5739 || DECL_HARD_REGISTER (decl))
1a981e1a 5740 make_copy_constraint (vi, nonlocal_id);
5741
6fc56905 5742 /* In IPA mode parse the initializer and generate proper constraints
5743 for it. */
841e98fa 5744 else
1a981e1a 5745 {
841e98fa 5746 struct varpool_node *vnode = varpool_get_node (decl);
5747
5748 /* For escaped variables initialize them from nonlocal. */
5749 if (!varpool_all_refs_explicit_p (vnode))
5750 make_copy_constraint (vi, nonlocal_id);
5751
5752 /* If this is a global variable with an initializer and we are in
5753 IPA mode generate constraints for it. */
f963f90b 5754 if (DECL_INITIAL (decl)
15ca8f90 5755 && vnode->symbol.definition)
1a981e1a 5756 {
1e094109 5757 vec<ce_s> rhsc = vNULL;
841e98fa 5758 struct constraint_expr lhs, *rhsp;
5759 unsigned i;
5760 get_constraint_for_rhs (DECL_INITIAL (decl), &rhsc);
5761 lhs.var = vi->id;
1a981e1a 5762 lhs.offset = 0;
5763 lhs.type = SCALAR;
f1f41a6c 5764 FOR_EACH_VEC_ELT (rhsc, i, rhsp)
1a981e1a 5765 process_constraint (new_constraint (lhs, *rhsp));
841e98fa 5766 /* If this is a variable that escapes from the unit
5767 the initializer escapes as well. */
5768 if (!varpool_all_refs_explicit_p (vnode))
5769 {
5770 lhs.var = escaped_id;
5771 lhs.offset = 0;
5772 lhs.type = SCALAR;
f1f41a6c 5773 FOR_EACH_VEC_ELT (rhsc, i, rhsp)
841e98fa 5774 process_constraint (new_constraint (lhs, *rhsp));
5775 }
f1f41a6c 5776 rhsc.release ();
1a981e1a 5777 }
1a981e1a 5778 }
20283a99 5779 }
29fd4364 5780
d812977b 5781 return id;
29fd4364 5782}
5783
5784/* Print out the points-to solution for VAR to FILE. */
5785
dd277d48 5786static void
29fd4364 5787dump_solution_for_var (FILE *file, unsigned int var)
5788{
5789 varinfo_t vi = get_varinfo (var);
5790 unsigned int i;
7d1f52b2 5791 bitmap_iterator bi;
5792
1a981e1a 5793 /* Dump the solution for unified vars anyway, this avoids difficulties
5794 in scanning dumps in the testsuite. */
5795 fprintf (file, "%s = { ", vi->name);
5796 vi = get_varinfo (find (var));
5797 EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
5798 fprintf (file, "%s ", get_varinfo (i)->name);
5799 fprintf (file, "}");
5800
5801 /* But note when the variable was unified. */
5802 if (vi->id != var)
5803 fprintf (file, " same as %s", vi->name);
5804
5805 fprintf (file, "\n");
29fd4364 5806}
5807
5808/* Print the points-to solution for VAR to stdout. */
5809
4b987fac 5810DEBUG_FUNCTION void
29fd4364 5811debug_solution_for_var (unsigned int var)
5812{
5813 dump_solution_for_var (stdout, var);
5814}
5815
29fd4364 5816/* Create varinfo structures for all of the variables in the
5817 function for intraprocedural mode. */
5818
5819static void
5820intra_create_variable_infos (void)
5821{
5822 tree t;
91fbe448 5823
085b7aab 5824 /* For each incoming pointer argument arg, create the constraint ARG
e190b18a 5825 = NONLOCAL or a dummy variable if it is a restrict qualified
5826 passed-by-reference argument. */
1767a056 5827 for (t = DECL_ARGUMENTS (current_function_decl); t; t = DECL_CHAIN (t))
29fd4364 5828 {
6fc56905 5829 varinfo_t p = get_vi_for_tree (t);
7d1f52b2 5830
7e17648b 5831 /* For restrict qualified pointers to objects passed by
f277142a 5832 reference build a real representative for the pointed-to object.
5833 Treat restrict qualified references the same. */
5834 if (TYPE_RESTRICT (TREE_TYPE (t))
5835 && ((DECL_BY_REFERENCE (t) && POINTER_TYPE_P (TREE_TYPE (t)))
bd57fdff 5836 || TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
5837 && !type_contains_placeholder_p (TREE_TYPE (TREE_TYPE (t))))
7e17648b 5838 {
5839 struct constraint_expr lhsc, rhsc;
5840 varinfo_t vi;
e44576dd 5841 tree heapvar = build_fake_var_decl (TREE_TYPE (TREE_TYPE (t)));
5842 DECL_EXTERNAL (heapvar) = 1;
841e98fa 5843 vi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS");
5844 insert_vi_for_tree (heapvar, vi);
6fc56905 5845 lhsc.var = p->id;
7e17648b 5846 lhsc.type = SCALAR;
5847 lhsc.offset = 0;
e44576dd 5848 rhsc.var = vi->id;
7e17648b 5849 rhsc.type = ADDRESSOF;
5850 rhsc.offset = 0;
5851 process_constraint (new_constraint (lhsc, rhsc));
5a950977 5852 for (; vi; vi = vi_next (vi))
841e98fa 5853 if (vi->may_have_pointers)
5854 {
5855 if (vi->only_restrict_pointers)
6fc56905 5856 make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT");
5857 else
5858 make_copy_constraint (vi, nonlocal_id);
841e98fa 5859 }
7e17648b 5860 continue;
5861 }
5862
1c1f1bc0 5863 if (POINTER_TYPE_P (TREE_TYPE (t))
5864 && TYPE_RESTRICT (TREE_TYPE (t)))
6fc56905 5865 make_constraint_from_global_restrict (p, "PARM_RESTRICT");
5866 else
5867 {
5a950977 5868 for (; p; p = vi_next (p))
6fc56905 5869 {
5870 if (p->only_restrict_pointers)
5871 make_constraint_from_global_restrict (p, "PARM_RESTRICT");
5872 else if (p->may_have_pointers)
5873 make_constraint_from (p, nonlocal_id);
5874 }
5875 }
499be8ef 5876 }
f8473bb3 5877
48d49ced 5878 /* Add a constraint for a result decl that is passed by reference. */
5879 if (DECL_RESULT (cfun->decl)
5880 && DECL_BY_REFERENCE (DECL_RESULT (cfun->decl)))
5881 {
5882 varinfo_t p, result_vi = get_vi_for_tree (DECL_RESULT (cfun->decl));
5883
5a950977 5884 for (p = result_vi; p; p = vi_next (p))
dd277d48 5885 make_constraint_from (p, nonlocal_id);
48d49ced 5886 }
5887
f8473bb3 5888 /* Add a constraint for the incoming static chain parameter. */
5889 if (cfun->static_chain_decl != NULL_TREE)
5890 {
5891 varinfo_t p, chain_vi = get_vi_for_tree (cfun->static_chain_decl);
5892
5a950977 5893 for (p = chain_vi; p; p = vi_next (p))
f8473bb3 5894 make_constraint_from (p, nonlocal_id);
5895 }
29fd4364 5896}
5897
58d16c5f 5898/* Structure used to put solution bitmaps in a hashtable so they can
5899 be shared among variables with the same points-to set. */
5900
5901typedef struct shared_bitmap_info
5902{
5903 bitmap pt_vars;
5904 hashval_t hashcode;
5905} *shared_bitmap_info_t;
dea3189b 5906typedef const struct shared_bitmap_info *const_shared_bitmap_info_t;
58d16c5f 5907
3e871d4d 5908/* Shared_bitmap hashtable helpers. */
5909
5910struct shared_bitmap_hasher : typed_free_remove <shared_bitmap_info>
5911{
5912 typedef shared_bitmap_info value_type;
5913 typedef shared_bitmap_info compare_type;
5914 static inline hashval_t hash (const value_type *);
5915 static inline bool equal (const value_type *, const compare_type *);
5916};
58d16c5f 5917
5918/* Hash function for a shared_bitmap_info_t */
5919
3e871d4d 5920inline hashval_t
5921shared_bitmap_hasher::hash (const value_type *bi)
58d16c5f 5922{
58d16c5f 5923 return bi->hashcode;
5924}
5925
5926/* Equality function for two shared_bitmap_info_t's. */
5927
3e871d4d 5928inline bool
5929shared_bitmap_hasher::equal (const value_type *sbi1, const compare_type *sbi2)
58d16c5f 5930{
58d16c5f 5931 return bitmap_equal_p (sbi1->pt_vars, sbi2->pt_vars);
5932}
5933
3e871d4d 5934/* Shared_bitmap hashtable. */
5935
5936static hash_table <shared_bitmap_hasher> shared_bitmap_table;
5937
58d16c5f 5938/* Lookup a bitmap in the shared bitmap hashtable, and return an already
5939 existing instance if there is one, NULL otherwise. */
5940
5941static bitmap
5942shared_bitmap_lookup (bitmap pt_vars)
5943{
3e871d4d 5944 shared_bitmap_info **slot;
58d16c5f 5945 struct shared_bitmap_info sbi;
5946
5947 sbi.pt_vars = pt_vars;
5948 sbi.hashcode = bitmap_hash (pt_vars);
a6db8f14 5949
3e871d4d 5950 slot = shared_bitmap_table.find_slot_with_hash (&sbi, sbi.hashcode,
5951 NO_INSERT);
58d16c5f 5952 if (!slot)
5953 return NULL;
5954 else
3e871d4d 5955 return (*slot)->pt_vars;
58d16c5f 5956}
5957
5958
5959/* Add a bitmap to the shared bitmap hashtable. */
5960
5961static void
5962shared_bitmap_add (bitmap pt_vars)
5963{
3e871d4d 5964 shared_bitmap_info **slot;
58d16c5f 5965 shared_bitmap_info_t sbi = XNEW (struct shared_bitmap_info);
a6db8f14 5966
58d16c5f 5967 sbi->pt_vars = pt_vars;
5968 sbi->hashcode = bitmap_hash (pt_vars);
a6db8f14 5969
3e871d4d 5970 slot = shared_bitmap_table.find_slot_with_hash (sbi, sbi->hashcode, INSERT);
58d16c5f 5971 gcc_assert (!*slot);
3e871d4d 5972 *slot = sbi;
58d16c5f 5973}
5974
5975
2a3ebafa 5976/* Set bits in INTO corresponding to the variable uids in solution set FROM. */
29fd4364 5977
48e1416a 5978static void
2a3ebafa 5979set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt)
29fd4364 5980{
5981 unsigned int i;
5982 bitmap_iterator bi;
e66c4ec1 5983
29fd4364 5984 EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
5985 {
5986 varinfo_t vi = get_varinfo (i);
7d1f52b2 5987
260e7e11 5988 /* The only artificial variables that are allowed in a may-alias
5989 set are heap variables. */
5990 if (vi->is_artificial_var && !vi->is_heap_var)
5991 continue;
7d1f52b2 5992
2afb4be3 5993 if (TREE_CODE (vi->decl) == VAR_DECL
5994 || TREE_CODE (vi->decl) == PARM_DECL
5995 || TREE_CODE (vi->decl) == RESULT_DECL)
e71afe8f 5996 {
1a981e1a 5997 /* If we are in IPA mode we will not recompute points-to
5998 sets after inlining so make sure they stay valid. */
5999 if (in_ipa_mode
6000 && !DECL_PT_UID_SET_P (vi->decl))
6001 SET_DECL_PT_UID (vi->decl, DECL_UID (vi->decl));
6002
dd277d48 6003 /* Add the decl to the points-to set. Note that the points-to
6004 set contains global variables. */
1a981e1a 6005 bitmap_set_bit (into, DECL_PT_UID (vi->decl));
1c1f1bc0 6006 if (vi->is_global_var)
dd277d48 6007 pt->vars_contains_global = true;
260e7e11 6008 }
29fd4364 6009 }
6010}
260e7e11 6011
6012
2a3ebafa 6013/* Compute the points-to solution *PT for the variable VI. */
fb5930be 6014
dd6f8b2c 6015static struct pt_solution
6016find_what_var_points_to (varinfo_t orig_vi)
fb5930be 6017{
2a3ebafa 6018 unsigned int i;
dd277d48 6019 bitmap_iterator bi;
6020 bitmap finished_solution;
6021 bitmap result;
048f1033 6022 varinfo_t vi;
dd6f8b2c 6023 void **slot;
6024 struct pt_solution *pt;
dd277d48 6025
6026 /* This variable may have been collapsed, let's get the real
6027 variable. */
048f1033 6028 vi = get_varinfo (find (orig_vi->id));
dd277d48 6029
dd6f8b2c 6030 /* See if we have already computed the solution and return it. */
6031 slot = pointer_map_insert (final_solutions, vi);
6032 if (*slot != NULL)
6033 return *(struct pt_solution *)*slot;
6034
6035 *slot = pt = XOBNEW (&final_solutions_obstack, struct pt_solution);
6036 memset (pt, 0, sizeof (struct pt_solution));
6037
dd277d48 6038 /* Translate artificial variables into SSA_NAME_PTR_INFO
6039 attributes. */
6040 EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
6041 {
6042 varinfo_t vi = get_varinfo (i);
6043
6044 if (vi->is_artificial_var)
6045 {
6046 if (vi->id == nothing_id)
6047 pt->null = 1;
6048 else if (vi->id == escaped_id)
1a981e1a 6049 {
6050 if (in_ipa_mode)
6051 pt->ipa_escaped = 1;
6052 else
6053 pt->escaped = 1;
6054 }
dd277d48 6055 else if (vi->id == nonlocal_id)
6056 pt->nonlocal = 1;
6057 else if (vi->is_heap_var)
6058 /* We represent heapvars in the points-to set properly. */
6059 ;
9b68b56b 6060 else if (vi->id == readonly_id)
6061 /* Nobody cares. */
6062 ;
dd277d48 6063 else if (vi->id == anything_id
dd277d48 6064 || vi->id == integer_id)
6065 pt->anything = 1;
6066 }
6067 }
6068
6069 /* Instead of doing extra work, simply do not create
6070 elaborate points-to information for pt_anything pointers. */
6fc56905 6071 if (pt->anything)
dd6f8b2c 6072 return *pt;
dd277d48 6073
6074 /* Share the final set of variables when possible. */
6075 finished_solution = BITMAP_GGC_ALLOC ();
6076 stats.points_to_sets_created++;
6077
2a3ebafa 6078 set_uids_in_ptset (finished_solution, vi->solution, pt);
dd277d48 6079 result = shared_bitmap_lookup (finished_solution);
6080 if (!result)
6081 {
6082 shared_bitmap_add (finished_solution);
6083 pt->vars = finished_solution;
6084 }
6085 else
6086 {
6087 pt->vars = result;
6088 bitmap_clear (finished_solution);
6089 }
dd6f8b2c 6090
6091 return *pt;
dd277d48 6092}
6093
2a3ebafa 6094/* Given a pointer variable P, fill in its points-to set. */
dd277d48 6095
6096static void
2a3ebafa 6097find_what_p_points_to (tree p)
dd277d48 6098{
6099 struct ptr_info_def *pi;
fb45032e 6100 tree lookup_p = p;
8a3fd8a7 6101 varinfo_t vi;
260e7e11 6102
fb45032e 6103 /* For parameters, get at the points-to set for the actual parm
6104 decl. */
7d1f52b2 6105 if (TREE_CODE (p) == SSA_NAME
2f4ec87c 6106 && SSA_NAME_IS_DEFAULT_DEF (p)
524a0531 6107 && (TREE_CODE (SSA_NAME_VAR (p)) == PARM_DECL
2f4ec87c 6108 || TREE_CODE (SSA_NAME_VAR (p)) == RESULT_DECL))
fb45032e 6109 lookup_p = SSA_NAME_VAR (p);
6110
b30a8715 6111 vi = lookup_vi_for_tree (lookup_p);
dd277d48 6112 if (!vi)
6113 return;
6114
6115 pi = get_ptr_info (p);
dd6f8b2c 6116 pi->pt = find_what_var_points_to (vi);
dd277d48 6117}
a6db8f14 6118
29fd4364 6119
dd277d48 6120/* Query statistics for points-to solutions. */
7d1f52b2 6121
dd277d48 6122static struct {
6123 unsigned HOST_WIDE_INT pt_solution_includes_may_alias;
6124 unsigned HOST_WIDE_INT pt_solution_includes_no_alias;
6125 unsigned HOST_WIDE_INT pt_solutions_intersect_may_alias;
6126 unsigned HOST_WIDE_INT pt_solutions_intersect_no_alias;
6127} pta_stats;
260e7e11 6128
dd277d48 6129void
6130dump_pta_stats (FILE *s)
6131{
6132 fprintf (s, "\nPTA query stats:\n");
6133 fprintf (s, " pt_solution_includes: "
6134 HOST_WIDE_INT_PRINT_DEC" disambiguations, "
6135 HOST_WIDE_INT_PRINT_DEC" queries\n",
6136 pta_stats.pt_solution_includes_no_alias,
6137 pta_stats.pt_solution_includes_no_alias
6138 + pta_stats.pt_solution_includes_may_alias);
6139 fprintf (s, " pt_solutions_intersect: "
6140 HOST_WIDE_INT_PRINT_DEC" disambiguations, "
6141 HOST_WIDE_INT_PRINT_DEC" queries\n",
6142 pta_stats.pt_solutions_intersect_no_alias,
6143 pta_stats.pt_solutions_intersect_no_alias
6144 + pta_stats.pt_solutions_intersect_may_alias);
6145}
260e7e11 6146
ddca26d5 6147
dd277d48 6148/* Reset the points-to solution *PT to a conservative default
6149 (point to anything). */
a6db8f14 6150
dd277d48 6151void
6152pt_solution_reset (struct pt_solution *pt)
6153{
6154 memset (pt, 0, sizeof (struct pt_solution));
6155 pt->anything = true;
6156}
58d16c5f 6157
3a443843 6158/* Set the points-to solution *PT to point only to the variables
1a981e1a 6159 in VARS. VARS_CONTAINS_GLOBAL specifies whether that contains
6160 global variables and VARS_CONTAINS_RESTRICT specifies whether
6161 it contains restrict tag variables. */
3a443843 6162
6163void
6fc56905 6164pt_solution_set (struct pt_solution *pt, bitmap vars, bool vars_contains_global)
3a443843 6165{
3a443843 6166 memset (pt, 0, sizeof (struct pt_solution));
6167 pt->vars = vars;
1a981e1a 6168 pt->vars_contains_global = vars_contains_global;
1a981e1a 6169}
6170
e1c894dd 6171/* Set the points-to solution *PT to point only to the variable VAR. */
6172
6173void
6174pt_solution_set_var (struct pt_solution *pt, tree var)
6175{
6176 memset (pt, 0, sizeof (struct pt_solution));
6177 pt->vars = BITMAP_GGC_ALLOC ();
ce9d76aa 6178 bitmap_set_bit (pt->vars, DECL_PT_UID (var));
e1c894dd 6179 pt->vars_contains_global = is_global_var (var);
6180}
6181
1a981e1a 6182/* Computes the union of the points-to solutions *DEST and *SRC and
6183 stores the result in *DEST. This changes the points-to bitmap
6184 of *DEST and thus may not be used if that might be shared.
6185 The points-to bitmap of *SRC and *DEST will not be shared after
6186 this function if they were not before. */
6187
6188static void
6189pt_solution_ior_into (struct pt_solution *dest, struct pt_solution *src)
6190{
6191 dest->anything |= src->anything;
6192 if (dest->anything)
3a443843 6193 {
1a981e1a 6194 pt_solution_reset (dest);
6195 return;
3a443843 6196 }
1a981e1a 6197
6198 dest->nonlocal |= src->nonlocal;
6199 dest->escaped |= src->escaped;
6200 dest->ipa_escaped |= src->ipa_escaped;
6201 dest->null |= src->null;
6202 dest->vars_contains_global |= src->vars_contains_global;
1a981e1a 6203 if (!src->vars)
6204 return;
6205
6206 if (!dest->vars)
6207 dest->vars = BITMAP_GGC_ALLOC ();
6208 bitmap_ior_into (dest->vars, src->vars);
3a443843 6209}
6210
dd277d48 6211/* Return true if the points-to solution *PT is empty. */
260e7e11 6212
1a981e1a 6213bool
dd277d48 6214pt_solution_empty_p (struct pt_solution *pt)
6215{
6216 if (pt->anything
6217 || pt->nonlocal)
6218 return false;
260e7e11 6219
dd277d48 6220 if (pt->vars
6221 && !bitmap_empty_p (pt->vars))
6222 return false;
260e7e11 6223
dd277d48 6224 /* If the solution includes ESCAPED, check if that is empty. */
6225 if (pt->escaped
6226 && !pt_solution_empty_p (&cfun->gimple_df->escaped))
6227 return false;
6228
1a981e1a 6229 /* If the solution includes ESCAPED, check if that is empty. */
6230 if (pt->ipa_escaped
6231 && !pt_solution_empty_p (&ipa_escaped_pt))
6232 return false;
6233
dd277d48 6234 return true;
29fd4364 6235}
6236
3d4a0a4b 6237/* Return true if the points-to solution *PT only point to a single var, and
6238 return the var uid in *UID. */
6239
6240bool
6241pt_solution_singleton_p (struct pt_solution *pt, unsigned *uid)
6242{
6243 if (pt->anything || pt->nonlocal || pt->escaped || pt->ipa_escaped
6244 || pt->null || pt->vars == NULL
6245 || !bitmap_single_bit_set_p (pt->vars))
6246 return false;
6247
6248 *uid = bitmap_first_set_bit (pt->vars);
6249 return true;
6250}
6251
dd277d48 6252/* Return true if the points-to solution *PT includes global memory. */
d7bac116 6253
e2486556 6254bool
dd277d48 6255pt_solution_includes_global (struct pt_solution *pt)
e2486556 6256{
dd277d48 6257 if (pt->anything
6258 || pt->nonlocal
6259 || pt->vars_contains_global)
6260 return true;
e2486556 6261
dd277d48 6262 if (pt->escaped)
6263 return pt_solution_includes_global (&cfun->gimple_df->escaped);
e2486556 6264
1a981e1a 6265 if (pt->ipa_escaped)
6266 return pt_solution_includes_global (&ipa_escaped_pt);
6267
6268 /* ??? This predicate is not correct for the IPA-PTA solution
6269 as we do not properly distinguish between unit escape points
6270 and global variables. */
6271 if (cfun->gimple_df->ipa_pta)
6272 return true;
6273
dd277d48 6274 return false;
6275}
e2486556 6276
dd277d48 6277/* Return true if the points-to solution *PT includes the variable
6278 declaration DECL. */
9f41ce98 6279
dd277d48 6280static bool
6281pt_solution_includes_1 (struct pt_solution *pt, const_tree decl)
6282{
6283 if (pt->anything)
6284 return true;
e2486556 6285
dd277d48 6286 if (pt->nonlocal
6287 && is_global_var (decl))
6288 return true;
e2486556 6289
dd277d48 6290 if (pt->vars
1a981e1a 6291 && bitmap_bit_p (pt->vars, DECL_PT_UID (decl)))
dd277d48 6292 return true;
e2486556 6293
dd277d48 6294 /* If the solution includes ESCAPED, check it. */
6295 if (pt->escaped
6296 && pt_solution_includes_1 (&cfun->gimple_df->escaped, decl))
6297 return true;
e2486556 6298
1a981e1a 6299 /* If the solution includes ESCAPED, check it. */
6300 if (pt->ipa_escaped
6301 && pt_solution_includes_1 (&ipa_escaped_pt, decl))
6302 return true;
6303
dd277d48 6304 return false;
e2486556 6305}
29fd4364 6306
dd277d48 6307bool
6308pt_solution_includes (struct pt_solution *pt, const_tree decl)
9f41ce98 6309{
dd277d48 6310 bool res = pt_solution_includes_1 (pt, decl);
6311 if (res)
6312 ++pta_stats.pt_solution_includes_may_alias;
6313 else
6314 ++pta_stats.pt_solution_includes_no_alias;
6315 return res;
6316}
9f41ce98 6317
dd277d48 6318/* Return true if both points-to solutions PT1 and PT2 have a non-empty
6319 intersection. */
9f41ce98 6320
dd277d48 6321static bool
6322pt_solutions_intersect_1 (struct pt_solution *pt1, struct pt_solution *pt2)
6323{
6324 if (pt1->anything || pt2->anything)
6325 return true;
9f41ce98 6326
dd277d48 6327 /* If either points to unknown global memory and the other points to
6328 any global memory they alias. */
6329 if ((pt1->nonlocal
6330 && (pt2->nonlocal
6331 || pt2->vars_contains_global))
6332 || (pt2->nonlocal
6333 && pt1->vars_contains_global))
6334 return true;
9f41ce98 6335
dd277d48 6336 /* Check the escaped solution if required. */
6337 if ((pt1->escaped || pt2->escaped)
6338 && !pt_solution_empty_p (&cfun->gimple_df->escaped))
6339 {
6340 /* If both point to escaped memory and that solution
6341 is not empty they alias. */
6342 if (pt1->escaped && pt2->escaped)
6343 return true;
9f41ce98 6344
dd277d48 6345 /* If either points to escaped memory see if the escaped solution
6346 intersects with the other. */
6347 if ((pt1->escaped
6348 && pt_solutions_intersect_1 (&cfun->gimple_df->escaped, pt2))
6349 || (pt2->escaped
6350 && pt_solutions_intersect_1 (&cfun->gimple_df->escaped, pt1)))
6351 return true;
9f41ce98 6352 }
6353
1a981e1a 6354 /* Check the escaped solution if required.
6355 ??? Do we need to check the local against the IPA escaped sets? */
6356 if ((pt1->ipa_escaped || pt2->ipa_escaped)
6357 && !pt_solution_empty_p (&ipa_escaped_pt))
6358 {
6359 /* If both point to escaped memory and that solution
6360 is not empty they alias. */
6361 if (pt1->ipa_escaped && pt2->ipa_escaped)
6362 return true;
6363
6364 /* If either points to escaped memory see if the escaped solution
6365 intersects with the other. */
6366 if ((pt1->ipa_escaped
6367 && pt_solutions_intersect_1 (&ipa_escaped_pt, pt2))
6368 || (pt2->ipa_escaped
6369 && pt_solutions_intersect_1 (&ipa_escaped_pt, pt1)))
6370 return true;
6371 }
6372
dd277d48 6373 /* Now both pointers alias if their points-to solution intersects. */
6374 return (pt1->vars
6375 && pt2->vars
6376 && bitmap_intersect_p (pt1->vars, pt2->vars));
6377}
6378
6379bool
6380pt_solutions_intersect (struct pt_solution *pt1, struct pt_solution *pt2)
6381{
6382 bool res = pt_solutions_intersect_1 (pt1, pt2);
6383 if (res)
6384 ++pta_stats.pt_solutions_intersect_may_alias;
6385 else
6386 ++pta_stats.pt_solutions_intersect_no_alias;
6387 return res;
9f41ce98 6388}
6389
0b3bf4d6 6390
d7bac116 6391/* Dump points-to information to OUTFILE. */
6392
dd277d48 6393static void
29fd4364 6394dump_sa_points_to_info (FILE *outfile)
6395{
29fd4364 6396 unsigned int i;
d7bac116 6397
260e7e11 6398 fprintf (outfile, "\nPoints-to sets\n\n");
d7bac116 6399
29fd4364 6400 if (dump_flags & TDF_STATS)
6401 {
6402 fprintf (outfile, "Stats:\n");
d7bac116 6403 fprintf (outfile, "Total vars: %d\n", stats.total_vars);
8a3fd8a7 6404 fprintf (outfile, "Non-pointer vars: %d\n",
6405 stats.nonpointer_vars);
d7bac116 6406 fprintf (outfile, "Statically unified vars: %d\n",
6407 stats.unified_vars_static);
d7bac116 6408 fprintf (outfile, "Dynamically unified vars: %d\n",
6409 stats.unified_vars_dynamic);
6410 fprintf (outfile, "Iterations: %d\n", stats.iterations);
db026f5c 6411 fprintf (outfile, "Number of edges: %d\n", stats.num_edges);
8a3fd8a7 6412 fprintf (outfile, "Number of implicit edges: %d\n",
6413 stats.num_implicit_edges);
29fd4364 6414 }
d7bac116 6415
5a950977 6416 for (i = 1; i < varmap.length (); i++)
1a981e1a 6417 {
6418 varinfo_t vi = get_varinfo (i);
6419 if (!vi->may_have_pointers)
3eaadea6 6420 continue;
1a981e1a 6421 dump_solution_for_var (outfile, i);
6422 }
29fd4364 6423}
6424
6425
d7bac116 6426/* Debug points-to information to stderr. */
6427
4b987fac 6428DEBUG_FUNCTION void
d7bac116 6429debug_sa_points_to_info (void)
6430{
6431 dump_sa_points_to_info (stderr);
6432}
6433
6434
29fd4364 6435/* Initialize the always-existing constraint variables for NULL
6436 ANYTHING, READONLY, and INTEGER */
6437
6438static void
6439init_base_vars (void)
6440{
6441 struct constraint_expr lhs, rhs;
97709d23 6442 varinfo_t var_anything;
6443 varinfo_t var_nothing;
6444 varinfo_t var_readonly;
6445 varinfo_t var_escaped;
6446 varinfo_t var_nonlocal;
97709d23 6447 varinfo_t var_storedanything;
6448 varinfo_t var_integer;
29fd4364 6449
5a950977 6450 /* Variable ID zero is reserved and should be NULL. */
6451 varmap.safe_push (NULL);
6452
29fd4364 6453 /* Create the NULL variable, used to represent that a variable points
6454 to NULL. */
97709d23 6455 var_nothing = new_var_info (NULL_TREE, "NULL");
6456 gcc_assert (var_nothing->id == nothing_id);
29fd4364 6457 var_nothing->is_artificial_var = 1;
6458 var_nothing->offset = 0;
6459 var_nothing->size = ~0;
6460 var_nothing->fullsize = ~0;
300b54b8 6461 var_nothing->is_special_var = 1;
3eaadea6 6462 var_nothing->may_have_pointers = 0;
6463 var_nothing->is_global_var = 0;
29fd4364 6464
6465 /* Create the ANYTHING variable, used to represent that a variable
6466 points to some unknown piece of memory. */
97709d23 6467 var_anything = new_var_info (NULL_TREE, "ANYTHING");
6468 gcc_assert (var_anything->id == anything_id);
29fd4364 6469 var_anything->is_artificial_var = 1;
6470 var_anything->size = ~0;
6471 var_anything->offset = 0;
29fd4364 6472 var_anything->fullsize = ~0;
300b54b8 6473 var_anything->is_special_var = 1;
29fd4364 6474
6475 /* Anything points to anything. This makes deref constraints just
7d1f52b2 6476 work in the presence of linked list and other p = *p type loops,
29fd4364 6477 by saying that *ANYTHING = ANYTHING. */
29fd4364 6478 lhs.type = SCALAR;
6479 lhs.var = anything_id;
6480 lhs.offset = 0;
8a3fd8a7 6481 rhs.type = ADDRESSOF;
29fd4364 6482 rhs.var = anything_id;
6483 rhs.offset = 0;
260e7e11 6484
25fd8fda 6485 /* This specifically does not use process_constraint because
6486 process_constraint ignores all anything = anything constraints, since all
6487 but this one are redundant. */
f1f41a6c 6488 constraints.safe_push (new_constraint (lhs, rhs));
7d1f52b2 6489
29fd4364 6490 /* Create the READONLY variable, used to represent that a variable
6491 points to readonly memory. */
97709d23 6492 var_readonly = new_var_info (NULL_TREE, "READONLY");
6493 gcc_assert (var_readonly->id == readonly_id);
29fd4364 6494 var_readonly->is_artificial_var = 1;
6495 var_readonly->offset = 0;
6496 var_readonly->size = ~0;
6497 var_readonly->fullsize = ~0;
300b54b8 6498 var_readonly->is_special_var = 1;
29fd4364 6499
6500 /* readonly memory points to anything, in order to make deref
6501 easier. In reality, it points to anything the particular
6502 readonly variable can point to, but we don't track this
ce10738f 6503 separately. */
29fd4364 6504 lhs.type = SCALAR;
6505 lhs.var = readonly_id;
6506 lhs.offset = 0;
8a3fd8a7 6507 rhs.type = ADDRESSOF;
0b3bf4d6 6508 rhs.var = readonly_id; /* FIXME */
29fd4364 6509 rhs.offset = 0;
0b3bf4d6 6510 process_constraint (new_constraint (lhs, rhs));
7d1f52b2 6511
0b3bf4d6 6512 /* Create the ESCAPED variable, used to represent the set of escaped
6513 memory. */
97709d23 6514 var_escaped = new_var_info (NULL_TREE, "ESCAPED");
6515 gcc_assert (var_escaped->id == escaped_id);
0b3bf4d6 6516 var_escaped->is_artificial_var = 1;
6517 var_escaped->offset = 0;
6518 var_escaped->size = ~0;
6519 var_escaped->fullsize = ~0;
6520 var_escaped->is_special_var = 0;
0b3bf4d6 6521
0b3bf4d6 6522 /* Create the NONLOCAL variable, used to represent the set of nonlocal
6523 memory. */
97709d23 6524 var_nonlocal = new_var_info (NULL_TREE, "NONLOCAL");
6525 gcc_assert (var_nonlocal->id == nonlocal_id);
0b3bf4d6 6526 var_nonlocal->is_artificial_var = 1;
6527 var_nonlocal->offset = 0;
6528 var_nonlocal->size = ~0;
6529 var_nonlocal->fullsize = ~0;
6530 var_nonlocal->is_special_var = 1;
0b3bf4d6 6531
dd277d48 6532 /* ESCAPED = *ESCAPED, because escaped is may-deref'd at calls, etc. */
6533 lhs.type = SCALAR;
6534 lhs.var = escaped_id;
6535 lhs.offset = 0;
6536 rhs.type = DEREF;
6537 rhs.var = escaped_id;
6538 rhs.offset = 0;
6539 process_constraint (new_constraint (lhs, rhs));
6540
6541 /* ESCAPED = ESCAPED + UNKNOWN_OFFSET, because if a sub-field escapes the
6542 whole variable escapes. */
6543 lhs.type = SCALAR;
6544 lhs.var = escaped_id;
6545 lhs.offset = 0;
6546 rhs.type = SCALAR;
6547 rhs.var = escaped_id;
6548 rhs.offset = UNKNOWN_OFFSET;
6549 process_constraint (new_constraint (lhs, rhs));
6550
6551 /* *ESCAPED = NONLOCAL. This is true because we have to assume
6552 everything pointed to by escaped points to what global memory can
6553 point to. */
6554 lhs.type = DEREF;
6555 lhs.var = escaped_id;
6556 lhs.offset = 0;
6557 rhs.type = SCALAR;
6558 rhs.var = nonlocal_id;
6559 rhs.offset = 0;
6560 process_constraint (new_constraint (lhs, rhs));
6561
6562 /* NONLOCAL = &NONLOCAL, NONLOCAL = &ESCAPED. This is true because
6563 global memory may point to global memory and escaped memory. */
0b3bf4d6 6564 lhs.type = SCALAR;
6565 lhs.var = nonlocal_id;
6566 lhs.offset = 0;
6567 rhs.type = ADDRESSOF;
dd277d48 6568 rhs.var = nonlocal_id;
6569 rhs.offset = 0;
6570 process_constraint (new_constraint (lhs, rhs));
6571 rhs.type = ADDRESSOF;
0b3bf4d6 6572 rhs.var = escaped_id;
6573 rhs.offset = 0;
29fd4364 6574 process_constraint (new_constraint (lhs, rhs));
7d1f52b2 6575
c5168a9e 6576 /* Create the STOREDANYTHING variable, used to represent the set of
6577 variables stored to *ANYTHING. */
97709d23 6578 var_storedanything = new_var_info (NULL_TREE, "STOREDANYTHING");
6579 gcc_assert (var_storedanything->id == storedanything_id);
c5168a9e 6580 var_storedanything->is_artificial_var = 1;
6581 var_storedanything->offset = 0;
6582 var_storedanything->size = ~0;
6583 var_storedanything->fullsize = ~0;
6584 var_storedanything->is_special_var = 0;
c5168a9e 6585
29fd4364 6586 /* Create the INTEGER variable, used to represent that a variable points
dd277d48 6587 to what an INTEGER "points to". */
97709d23 6588 var_integer = new_var_info (NULL_TREE, "INTEGER");
6589 gcc_assert (var_integer->id == integer_id);
29fd4364 6590 var_integer->is_artificial_var = 1;
6591 var_integer->size = ~0;
6592 var_integer->fullsize = ~0;
6593 var_integer->offset = 0;
300b54b8 6594 var_integer->is_special_var = 1;
25fd8fda 6595
499be8ef 6596 /* INTEGER = ANYTHING, because we don't know where a dereference of
6597 a random integer will point to. */
25fd8fda 6598 lhs.type = SCALAR;
6599 lhs.var = integer_id;
6600 lhs.offset = 0;
8a3fd8a7 6601 rhs.type = ADDRESSOF;
25fd8fda 6602 rhs.var = anything_id;
6603 rhs.offset = 0;
6604 process_constraint (new_constraint (lhs, rhs));
7d1f52b2 6605}
29fd4364 6606
db026f5c 6607/* Initialize things necessary to perform PTA */
29fd4364 6608
db026f5c 6609static void
6610init_alias_vars (void)
29fd4364 6611{
57e6b870 6612 use_field_sensitive = (MAX_FIELDS_FOR_FIELD_SENSITIVE > 1);
6613
8a3fd8a7 6614 bitmap_obstack_initialize (&pta_obstack);
6615 bitmap_obstack_initialize (&oldpta_obstack);
db026f5c 6616 bitmap_obstack_initialize (&predbitmap_obstack);
29fd4364 6617
7d1f52b2 6618 constraint_pool = create_alloc_pool ("Constraint pool",
29fd4364 6619 sizeof (struct constraint), 30);
6620 variable_info_pool = create_alloc_pool ("Variable info pool",
6621 sizeof (struct variable_info), 30);
f1f41a6c 6622 constraints.create (8);
6623 varmap.create (8);
b30a8715 6624 vi_for_tree = pointer_map_create ();
c4ec6aca 6625 call_stmt_vars = pointer_map_create ();
8a3fd8a7 6626
29fd4364 6627 memset (&stats, 0, sizeof (stats));
3e871d4d 6628 shared_bitmap_table.create (511);
29fd4364 6629 init_base_vars ();
e44576dd 6630
6631 gcc_obstack_init (&fake_var_decl_obstack);
dd6f8b2c 6632
6633 final_solutions = pointer_map_create ();
6634 gcc_obstack_init (&final_solutions_obstack);
db026f5c 6635}
6636
8a3fd8a7 6637/* Remove the REF and ADDRESS edges from GRAPH, as well as all the
6638 predecessor edges. */
6639
6640static void
6641remove_preds_and_fake_succs (constraint_graph_t graph)
6642{
6643 unsigned int i;
6644
6645 /* Clear the implicit ref and address nodes from the successor
6646 lists. */
5a950977 6647 for (i = 1; i < FIRST_REF_NODE; i++)
8a3fd8a7 6648 {
6649 if (graph->succs[i])
6650 bitmap_clear_range (graph->succs[i], FIRST_REF_NODE,
6651 FIRST_REF_NODE * 2);
6652 }
6653
6654 /* Free the successor list for the non-ref nodes. */
5a950977 6655 for (i = FIRST_REF_NODE + 1; i < graph->size; i++)
8a3fd8a7 6656 {
6657 if (graph->succs[i])
6658 BITMAP_FREE (graph->succs[i]);
6659 }
6660
6661 /* Now reallocate the size of the successor list as, and blow away
6662 the predecessor bitmaps. */
f1f41a6c 6663 graph->size = varmap.length ();
f0d6e81c 6664 graph->succs = XRESIZEVEC (bitmap, graph->succs, graph->size);
8a3fd8a7 6665
6666 free (graph->implicit_preds);
6667 graph->implicit_preds = NULL;
6668 free (graph->preds);
6669 graph->preds = NULL;
6670 bitmap_obstack_release (&predbitmap_obstack);
6671}
6672
170c35d5 6673/* Solve the constraint set. */
db026f5c 6674
dd277d48 6675static void
170c35d5 6676solve_constraints (void)
db026f5c 6677{
8a3fd8a7 6678 struct scc_info *si;
29fd4364 6679
499be8ef 6680 if (dump_file)
6681 fprintf (dump_file,
6682 "\nCollapsing static cycles and doing variable "
a6db8f14 6683 "substitution\n");
6684
f1f41a6c 6685 init_graph (varmap.length () * 2);
48e1416a 6686
a6db8f14 6687 if (dump_file)
6688 fprintf (dump_file, "Building predecessor graph\n");
8a3fd8a7 6689 build_pred_graph ();
48e1416a 6690
a6db8f14 6691 if (dump_file)
6692 fprintf (dump_file, "Detecting pointer and location "
6693 "equivalences\n");
8a3fd8a7 6694 si = perform_var_substitution (graph);
48e1416a 6695
a6db8f14 6696 if (dump_file)
6697 fprintf (dump_file, "Rewriting constraints and unifying "
6698 "variables\n");
6699 rewrite_constraints (graph, si);
48926532 6700
bbe0034f 6701 build_succ_graph ();
48926532 6702
bd2bd89d 6703 free_var_substitution_info (si);
6704
bbe0034f 6705 /* Attach complex constraints to graph nodes. */
a6db8f14 6706 move_complex_constraints (graph);
6707
6708 if (dump_file)
6709 fprintf (dump_file, "Uniting pointer but not location equivalent "
6710 "variables\n");
6711 unite_pointer_equivalences (graph);
6712
6713 if (dump_file)
6714 fprintf (dump_file, "Finding indirect cycles\n");
8a3fd8a7 6715 find_indirect_cycles (graph);
7d1f52b2 6716
8a3fd8a7 6717 /* Implicit nodes and predecessors are no longer necessary at this
6718 point. */
6719 remove_preds_and_fake_succs (graph);
7d1f52b2 6720
bbe0034f 6721 if (dump_file && (dump_flags & TDF_GRAPH))
6722 {
6723 fprintf (dump_file, "\n\n// The constraint graph before solve-graph "
6724 "in dot format:\n");
6725 dump_constraint_graph (dump_file);
6726 fprintf (dump_file, "\n\n");
6727 }
6728
499be8ef 6729 if (dump_file)
a6db8f14 6730 fprintf (dump_file, "Solving graph\n");
7d1f52b2 6731
499be8ef 6732 solve_graph (graph);
7d1f52b2 6733
bbe0034f 6734 if (dump_file && (dump_flags & TDF_GRAPH))
6735 {
6736 fprintf (dump_file, "\n\n// The constraint graph after solve-graph "
6737 "in dot format:\n");
6738 dump_constraint_graph (dump_file);
6739 fprintf (dump_file, "\n\n");
6740 }
6741
29fd4364 6742 if (dump_file)
6743 dump_sa_points_to_info (dump_file);
170c35d5 6744}
6745
6746/* Create points-to sets for the current function. See the comments
6747 at the start of the file for an algorithmic overview. */
6748
6749static void
6750compute_points_to_sets (void)
6751{
6752 basic_block bb;
6753 unsigned i;
6754 varinfo_t vi;
6755
6756 timevar_push (TV_TREE_PTA);
6757
6758 init_alias_vars ();
170c35d5 6759
6760 intra_create_variable_infos ();
6761
1a981e1a 6762 /* Now walk all statements and build the constraint set. */
170c35d5 6763 FOR_EACH_BB (bb)
6764 {
6765 gimple_stmt_iterator gsi;
6766
6767 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
6768 {
6769 gimple phi = gsi_stmt (gsi);
6770
7c782c9b 6771 if (! virtual_operand_p (gimple_phi_result (phi)))
170c35d5 6772 find_func_aliases (phi);
6773 }
6774
6775 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
6776 {
6777 gimple stmt = gsi_stmt (gsi);
6778
6779 find_func_aliases (stmt);
6780 }
6781 }
6782
1a981e1a 6783 if (dump_file)
6784 {
6785 fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n");
6786 dump_constraints (dump_file, 0);
6787 }
6788
170c35d5 6789 /* From the constraints compute the points-to sets. */
6790 solve_constraints ();
7d1f52b2 6791
c4ec6aca 6792 /* Compute the points-to set for ESCAPED used for call-clobber analysis. */
dd6f8b2c 6793 cfun->gimple_df->escaped = find_what_var_points_to (get_varinfo (escaped_id));
dd277d48 6794
6795 /* Make sure the ESCAPED solution (which is used as placeholder in
6796 other solutions) does not reference itself. This simplifies
6797 points-to solution queries. */
6798 cfun->gimple_df->escaped.escaped = 0;
6799
9df58cd1 6800 /* Mark escaped HEAP variables as global. */
f1f41a6c 6801 FOR_EACH_VEC_ELT (varmap, i, vi)
5a950977 6802 if (vi
6803 && vi->is_heap_var
9df58cd1 6804 && !vi->is_global_var)
9b68b56b 6805 DECL_EXTERNAL (vi->decl) = vi->is_global_var
6806 = pt_solution_includes (&cfun->gimple_df->escaped, vi->decl);
9df58cd1 6807
dd277d48 6808 /* Compute the points-to sets for pointer SSA_NAMEs. */
6809 for (i = 0; i < num_ssa_names; ++i)
6810 {
6811 tree ptr = ssa_name (i);
6812 if (ptr
6813 && POINTER_TYPE_P (TREE_TYPE (ptr)))
2a3ebafa 6814 find_what_p_points_to (ptr);
dd277d48 6815 }
260e7e11 6816
cb245216 6817 /* Compute the call-used/clobbered sets. */
6818 FOR_EACH_BB (bb)
6819 {
6820 gimple_stmt_iterator gsi;
6821
6822 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
6823 {
6824 gimple stmt = gsi_stmt (gsi);
6825 struct pt_solution *pt;
6826 if (!is_gimple_call (stmt))
6827 continue;
6828
6829 pt = gimple_call_use_set (stmt);
6830 if (gimple_call_flags (stmt) & ECF_CONST)
6831 memset (pt, 0, sizeof (struct pt_solution));
c4ec6aca 6832 else if ((vi = lookup_call_use_vi (stmt)) != NULL)
cb245216 6833 {
dd6f8b2c 6834 *pt = find_what_var_points_to (vi);
c4ec6aca 6835 /* Escaped (and thus nonlocal) variables are always
6836 implicitly used by calls. */
cb245216 6837 /* ??? ESCAPED can be empty even though NONLOCAL
6838 always escaped. */
6839 pt->nonlocal = 1;
6840 pt->escaped = 1;
6841 }
6842 else
6843 {
c4ec6aca 6844 /* If there is nothing special about this call then
6845 we have made everything that is used also escape. */
cb245216 6846 *pt = cfun->gimple_df->escaped;
6847 pt->nonlocal = 1;
6848 }
6849
6850 pt = gimple_call_clobber_set (stmt);
6851 if (gimple_call_flags (stmt) & (ECF_CONST|ECF_PURE|ECF_NOVOPS))
6852 memset (pt, 0, sizeof (struct pt_solution));
c4ec6aca 6853 else if ((vi = lookup_call_clobber_vi (stmt)) != NULL)
6854 {
dd6f8b2c 6855 *pt = find_what_var_points_to (vi);
c4ec6aca 6856 /* Escaped (and thus nonlocal) variables are always
6857 implicitly clobbered by calls. */
6858 /* ??? ESCAPED can be empty even though NONLOCAL
6859 always escaped. */
6860 pt->nonlocal = 1;
6861 pt->escaped = 1;
6862 }
cb245216 6863 else
6864 {
c4ec6aca 6865 /* If there is nothing special about this call then
6866 we have made everything that is used also escape. */
cb245216 6867 *pt = cfun->gimple_df->escaped;
6868 pt->nonlocal = 1;
6869 }
6870 }
6871 }
6872
260e7e11 6873 timevar_pop (TV_TREE_PTA);
29fd4364 6874}
6875
29fd4364 6876
6877/* Delete created points-to sets. */
6878
dd277d48 6879static void
260e7e11 6880delete_points_to_sets (void)
29fd4364 6881{
a6db8f14 6882 unsigned int i;
7d1f52b2 6883
3e871d4d 6884 shared_bitmap_table.dispose ();
8a3fd8a7 6885 if (dump_file && (dump_flags & TDF_STATS))
6886 fprintf (dump_file, "Points to sets created:%d\n",
6887 stats.points_to_sets_created);
6888
b30a8715 6889 pointer_map_destroy (vi_for_tree);
c4ec6aca 6890 pointer_map_destroy (call_stmt_vars);
8a3fd8a7 6891 bitmap_obstack_release (&pta_obstack);
f1f41a6c 6892 constraints.release ();
7d1f52b2 6893
a6db8f14 6894 for (i = 0; i < graph->size; i++)
f1f41a6c 6895 graph->complex[i].release ();
cf95b243 6896 free (graph->complex);
499be8ef 6897
8a3fd8a7 6898 free (graph->rep);
eb68f239 6899 free (graph->succs);
a6db8f14 6900 free (graph->pe);
6901 free (graph->pe_rep);
8a3fd8a7 6902 free (graph->indirect_cycles);
f2731e4b 6903 free (graph);
6904
f1f41a6c 6905 varmap.release ();
29fd4364 6906 free_alloc_pool (variable_info_pool);
7d1f52b2 6907 free_alloc_pool (constraint_pool);
e44576dd 6908
6909 obstack_free (&fake_var_decl_obstack, NULL);
dd6f8b2c 6910
6911 pointer_map_destroy (final_solutions);
6912 obstack_free (&final_solutions_obstack, NULL);
29fd4364 6913}
05fb844e 6914
dd277d48 6915
6916/* Compute points-to information for every SSA_NAME pointer in the
6917 current function and compute the transitive closure of escaped
6918 variables to re-initialize the call-clobber states of local variables. */
6919
6920unsigned int
6921compute_may_aliases (void)
6922{
1a981e1a 6923 if (cfun->gimple_df->ipa_pta)
6924 {
6925 if (dump_file)
6926 {
6927 fprintf (dump_file, "\nNot re-computing points-to information "
6928 "because IPA points-to information is available.\n\n");
6929
6930 /* But still dump what we have remaining it. */
6931 dump_alias_info (dump_file);
1a981e1a 6932 }
6933
6934 return 0;
6935 }
6936
dd277d48 6937 /* For each pointer P_i, determine the sets of variables that P_i may
6938 point-to. Compute the reachability set of escaped and call-used
6939 variables. */
6940 compute_points_to_sets ();
6941
6942 /* Debugging dumps. */
6943 if (dump_file)
24ccd9c6 6944 dump_alias_info (dump_file);
dd277d48 6945
6946 /* Deallocate memory used by aliasing data structures and the internal
6947 points-to solution. */
6948 delete_points_to_sets ();
6949
6950 gcc_assert (!need_ssa_update_p (cfun));
6951
6952 return 0;
6953}
6954
408c3c77 6955static bool
6956gate_tree_pta (void)
6957{
6958 return flag_tree_pta;
6959}
dd277d48 6960
6961/* A dummy pass to cause points-to information to be computed via
6962 TODO_rebuild_alias. */
6963
cbe8bda8 6964namespace {
6965
6966const pass_data pass_data_build_alias =
6967{
6968 GIMPLE_PASS, /* type */
6969 "alias", /* name */
6970 OPTGROUP_NONE, /* optinfo_flags */
6971 true, /* has_gate */
6972 false, /* has_execute */
6973 TV_NONE, /* tv_id */
6974 ( PROP_cfg | PROP_ssa ), /* properties_required */
6975 0, /* properties_provided */
6976 0, /* properties_destroyed */
6977 0, /* todo_flags_start */
6978 TODO_rebuild_alias, /* todo_flags_finish */
dd277d48 6979};
6980
cbe8bda8 6981class pass_build_alias : public gimple_opt_pass
6982{
6983public:
9af5ce0c 6984 pass_build_alias (gcc::context *ctxt)
6985 : gimple_opt_pass (pass_data_build_alias, ctxt)
cbe8bda8 6986 {}
6987
6988 /* opt_pass methods: */
6989 bool gate () { return gate_tree_pta (); }
6990
6991}; // class pass_build_alias
6992
6993} // anon namespace
6994
6995gimple_opt_pass *
6996make_pass_build_alias (gcc::context *ctxt)
6997{
6998 return new pass_build_alias (ctxt);
6999}
7000
7f81b5ee 7001/* A dummy pass to cause points-to information to be computed via
7002 TODO_rebuild_alias. */
7003
cbe8bda8 7004namespace {
7005
7006const pass_data pass_data_build_ealias =
7007{
7008 GIMPLE_PASS, /* type */
7009 "ealias", /* name */
7010 OPTGROUP_NONE, /* optinfo_flags */
7011 true, /* has_gate */
7012 false, /* has_execute */
7013 TV_NONE, /* tv_id */
7014 ( PROP_cfg | PROP_ssa ), /* properties_required */
7015 0, /* properties_provided */
7016 0, /* properties_destroyed */
7017 0, /* todo_flags_start */
7018 TODO_rebuild_alias, /* todo_flags_finish */
7f81b5ee 7019};
7020
cbe8bda8 7021class pass_build_ealias : public gimple_opt_pass
7022{
7023public:
9af5ce0c 7024 pass_build_ealias (gcc::context *ctxt)
7025 : gimple_opt_pass (pass_data_build_ealias, ctxt)
cbe8bda8 7026 {}
7027
7028 /* opt_pass methods: */
7029 bool gate () { return gate_tree_pta (); }
7030
7031}; // class pass_build_ealias
7032
7033} // anon namespace
7034
7035gimple_opt_pass *
7036make_pass_build_ealias (gcc::context *ctxt)
7037{
7038 return new pass_build_ealias (ctxt);
7039}
7040
dd277d48 7041
db026f5c 7042/* Return true if we should execute IPA PTA. */
7043static bool
7044gate_ipa_pta (void)
7045{
4bfcb72d 7046 return (optimize
7047 && flag_ipa_pta
db026f5c 7048 /* Don't bother doing anything if the program has errors. */
852f689e 7049 && !seen_error ());
db026f5c 7050}
7051
1a981e1a 7052/* IPA PTA solutions for ESCAPED. */
7053struct pt_solution ipa_escaped_pt
6fc56905 7054 = { true, false, false, false, false, false, NULL };
1a981e1a 7055
c70f46b0 7056/* Associate node with varinfo DATA. Worker for
7057 cgraph_for_node_and_aliases. */
7058static bool
7059associate_varinfo_to_alias (struct cgraph_node *node, void *data)
7060{
15ca8f90 7061 if ((node->symbol.alias || node->thunk.thunk_p)
7062 && node->symbol.analyzed)
7d0d0ce1 7063 insert_vi_for_tree (node->symbol.decl, (varinfo_t)data);
c70f46b0 7064 return false;
7065}
7066
db026f5c 7067/* Execute the driver for IPA PTA. */
2a1990e9 7068static unsigned int
db026f5c 7069ipa_pta_execute (void)
7070{
7071 struct cgraph_node *node;
1a981e1a 7072 struct varpool_node *var;
7073 int from;
8a3fd8a7 7074
db026f5c 7075 in_ipa_mode = 1;
170c35d5 7076
db026f5c 7077 init_alias_vars ();
7d1f52b2 7078
841e98fa 7079 if (dump_file && (dump_flags & TDF_DETAILS))
7080 {
18841b0c 7081 dump_symtab (dump_file);
841e98fa 7082 fprintf (dump_file, "\n");
7083 }
7084
170c35d5 7085 /* Build the constraints. */
7c455d87 7086 FOR_EACH_DEFINED_FUNCTION (node)
db026f5c 7087 {
7981828b 7088 varinfo_t vi;
170c35d5 7089 /* Nodes without a body are not interesting. Especially do not
7090 visit clones at this point for now - we get duplicate decls
7091 there for inline clones at least. */
eaad46f2 7092 if (!cgraph_function_with_gimple_body_p (node) || node->clone_of)
170c35d5 7093 continue;
eaad46f2 7094 cgraph_get_body (node);
170c35d5 7095
841e98fa 7096 gcc_assert (!node->clone_of);
7097
7d0d0ce1 7098 vi = create_function_info_for (node->symbol.decl,
7099 alias_get_name (node->symbol.decl));
c70f46b0 7100 cgraph_for_node_and_aliases (node, associate_varinfo_to_alias, vi, true);
db026f5c 7101 }
170c35d5 7102
1a981e1a 7103 /* Create constraints for global variables and their initializers. */
7c455d87 7104 FOR_EACH_VARIABLE (var)
7981828b 7105 {
15ca8f90 7106 if (var->symbol.alias && var->symbol.analyzed)
e0eaac80 7107 continue;
7981828b 7108
7d0d0ce1 7109 get_vi_for_tree (var->symbol.decl);
7981828b 7110 }
1a981e1a 7111
7112 if (dump_file)
7113 {
7114 fprintf (dump_file,
7115 "Generating constraints for global initializers\n\n");
7116 dump_constraints (dump_file, 0);
7117 fprintf (dump_file, "\n");
7118 }
f1f41a6c 7119 from = constraints.length ();
1a981e1a 7120
7c455d87 7121 FOR_EACH_DEFINED_FUNCTION (node)
db026f5c 7122 {
170c35d5 7123 struct function *func;
7124 basic_block bb;
db026f5c 7125
170c35d5 7126 /* Nodes without a body are not interesting. */
eaad46f2 7127 if (!cgraph_function_with_gimple_body_p (node) || node->clone_of)
170c35d5 7128 continue;
7d1f52b2 7129
170c35d5 7130 if (dump_file)
7981828b 7131 {
7132 fprintf (dump_file,
7133 "Generating constraints for %s", cgraph_node_name (node));
7d0d0ce1 7134 if (DECL_ASSEMBLER_NAME_SET_P (node->symbol.decl))
7981828b 7135 fprintf (dump_file, " (%s)",
7d0d0ce1 7136 IDENTIFIER_POINTER
7137 (DECL_ASSEMBLER_NAME (node->symbol.decl)));
7981828b 7138 fprintf (dump_file, "\n");
7139 }
7d1f52b2 7140
7d0d0ce1 7141 func = DECL_STRUCT_FUNCTION (node->symbol.decl);
170c35d5 7142 push_cfun (func);
75a70cf9 7143
841e98fa 7144 /* For externally visible or attribute used annotated functions use
7145 local constraints for their arguments.
7146 For local functions we see all callers and thus do not need initial
7147 constraints for parameters. */
7d0d0ce1 7148 if (node->symbol.used_from_other_partition
7149 || node->symbol.externally_visible
8efa224a 7150 || node->symbol.force_output)
12d9baf9 7151 {
12d9baf9 7152 intra_create_variable_infos ();
7153
7154 /* We also need to make function return values escape. Nothing
7155 escapes by returning from main though. */
7d0d0ce1 7156 if (!MAIN_NAME_P (DECL_NAME (node->symbol.decl)))
12d9baf9 7157 {
7158 varinfo_t fi, rvi;
7d0d0ce1 7159 fi = lookup_vi_for_tree (node->symbol.decl);
12d9baf9 7160 rvi = first_vi_for_offset (fi, fi_result);
7161 if (rvi && rvi->offset == fi_result)
7162 {
7163 struct constraint_expr includes;
7164 struct constraint_expr var;
7165 includes.var = escaped_id;
7166 includes.offset = 0;
7167 includes.type = SCALAR;
7168 var.var = rvi->id;
7169 var.offset = 0;
7170 var.type = SCALAR;
7171 process_constraint (new_constraint (includes, var));
7172 }
7173 }
7174 }
db026f5c 7175
170c35d5 7176 /* Build constriants for the function body. */
7177 FOR_EACH_BB_FN (bb, func)
7178 {
7179 gimple_stmt_iterator gsi;
7d1f52b2 7180
170c35d5 7181 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
7182 gsi_next (&gsi))
7183 {
7184 gimple phi = gsi_stmt (gsi);
7d1f52b2 7185
7c782c9b 7186 if (! virtual_operand_p (gimple_phi_result (phi)))
170c35d5 7187 find_func_aliases (phi);
7188 }
8a3fd8a7 7189
170c35d5 7190 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
7191 {
7192 gimple stmt = gsi_stmt (gsi);
8a3fd8a7 7193
170c35d5 7194 find_func_aliases (stmt);
1a981e1a 7195 find_func_clobbers (stmt);
170c35d5 7196 }
7197 }
7d1f52b2 7198
170c35d5 7199 pop_cfun ();
1a981e1a 7200
7201 if (dump_file)
7202 {
7203 fprintf (dump_file, "\n");
7204 dump_constraints (dump_file, from);
7205 fprintf (dump_file, "\n");
7206 }
f1f41a6c 7207 from = constraints.length ();
170c35d5 7208 }
7d1f52b2 7209
170c35d5 7210 /* From the constraints compute the points-to sets. */
7211 solve_constraints ();
7d1f52b2 7212
1a981e1a 7213 /* Compute the global points-to sets for ESCAPED.
7214 ??? Note that the computed escape set is not correct
7215 for the whole unit as we fail to consider graph edges to
7216 externally visible functions. */
dd6f8b2c 7217 ipa_escaped_pt = find_what_var_points_to (get_varinfo (escaped_id));
1a981e1a 7218
7219 /* Make sure the ESCAPED solution (which is used as placeholder in
7220 other solutions) does not reference itself. This simplifies
7221 points-to solution queries. */
7222 ipa_escaped_pt.ipa_escaped = 0;
7223
7224 /* Assign the points-to sets to the SSA names in the unit. */
7c455d87 7225 FOR_EACH_DEFINED_FUNCTION (node)
1a981e1a 7226 {
7227 tree ptr;
7228 struct function *fn;
7229 unsigned i;
7230 varinfo_t fi;
7231 basic_block bb;
7232 struct pt_solution uses, clobbers;
7233 struct cgraph_edge *e;
7234
7235 /* Nodes without a body are not interesting. */
eaad46f2 7236 if (!cgraph_function_with_gimple_body_p (node) || node->clone_of)
1a981e1a 7237 continue;
7238
7d0d0ce1 7239 fn = DECL_STRUCT_FUNCTION (node->symbol.decl);
1a981e1a 7240
7241 /* Compute the points-to sets for pointer SSA_NAMEs. */
f1f41a6c 7242 FOR_EACH_VEC_ELT (*fn->gimple_df->ssa_names, i, ptr)
1a981e1a 7243 {
7244 if (ptr
7245 && POINTER_TYPE_P (TREE_TYPE (ptr)))
7246 find_what_p_points_to (ptr);
7247 }
7248
7249 /* Compute the call-use and call-clobber sets for all direct calls. */
7d0d0ce1 7250 fi = lookup_vi_for_tree (node->symbol.decl);
1a981e1a 7251 gcc_assert (fi->is_fn_info);
dd6f8b2c 7252 clobbers
7253 = find_what_var_points_to (first_vi_for_offset (fi, fi_clobbers));
7254 uses = find_what_var_points_to (first_vi_for_offset (fi, fi_uses));
1a981e1a 7255 for (e = node->callers; e; e = e->next_caller)
7256 {
7257 if (!e->call_stmt)
7258 continue;
7259
7260 *gimple_call_clobber_set (e->call_stmt) = clobbers;
7261 *gimple_call_use_set (e->call_stmt) = uses;
7262 }
7263
7264 /* Compute the call-use and call-clobber sets for indirect calls
7265 and calls to external functions. */
7266 FOR_EACH_BB_FN (bb, fn)
7267 {
7268 gimple_stmt_iterator gsi;
7269
7270 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
7271 {
7272 gimple stmt = gsi_stmt (gsi);
7273 struct pt_solution *pt;
7274 varinfo_t vi;
7275 tree decl;
7276
7277 if (!is_gimple_call (stmt))
7278 continue;
7279
7280 /* Handle direct calls to external functions. */
7281 decl = gimple_call_fndecl (stmt);
7282 if (decl
7283 && (!(fi = lookup_vi_for_tree (decl))
7284 || !fi->is_fn_info))
7285 {
7286 pt = gimple_call_use_set (stmt);
7287 if (gimple_call_flags (stmt) & ECF_CONST)
7288 memset (pt, 0, sizeof (struct pt_solution));
7289 else if ((vi = lookup_call_use_vi (stmt)) != NULL)
7290 {
dd6f8b2c 7291 *pt = find_what_var_points_to (vi);
1a981e1a 7292 /* Escaped (and thus nonlocal) variables are always
7293 implicitly used by calls. */
7294 /* ??? ESCAPED can be empty even though NONLOCAL
7295 always escaped. */
7296 pt->nonlocal = 1;
7297 pt->ipa_escaped = 1;
7298 }
7299 else
7300 {
7301 /* If there is nothing special about this call then
7302 we have made everything that is used also escape. */
7303 *pt = ipa_escaped_pt;
7304 pt->nonlocal = 1;
7305 }
7306
7307 pt = gimple_call_clobber_set (stmt);
7308 if (gimple_call_flags (stmt) & (ECF_CONST|ECF_PURE|ECF_NOVOPS))
7309 memset (pt, 0, sizeof (struct pt_solution));
7310 else if ((vi = lookup_call_clobber_vi (stmt)) != NULL)
7311 {
dd6f8b2c 7312 *pt = find_what_var_points_to (vi);
1a981e1a 7313 /* Escaped (and thus nonlocal) variables are always
7314 implicitly clobbered by calls. */
7315 /* ??? ESCAPED can be empty even though NONLOCAL
7316 always escaped. */
7317 pt->nonlocal = 1;
7318 pt->ipa_escaped = 1;
7319 }
7320 else
7321 {
7322 /* If there is nothing special about this call then
7323 we have made everything that is used also escape. */
7324 *pt = ipa_escaped_pt;
7325 pt->nonlocal = 1;
7326 }
7327 }
7328
7329 /* Handle indirect calls. */
7330 if (!decl
7331 && (fi = get_fi_for_callee (stmt)))
7332 {
7333 /* We need to accumulate all clobbers/uses of all possible
7334 callees. */
7335 fi = get_varinfo (find (fi->id));
7336 /* If we cannot constrain the set of functions we'll end up
7337 calling we end up using/clobbering everything. */
7338 if (bitmap_bit_p (fi->solution, anything_id)
7339 || bitmap_bit_p (fi->solution, nonlocal_id)
7340 || bitmap_bit_p (fi->solution, escaped_id))
7341 {
7342 pt_solution_reset (gimple_call_clobber_set (stmt));
7343 pt_solution_reset (gimple_call_use_set (stmt));
7344 }
7345 else
7346 {
7347 bitmap_iterator bi;
7348 unsigned i;
7349 struct pt_solution *uses, *clobbers;
7350
7351 uses = gimple_call_use_set (stmt);
7352 clobbers = gimple_call_clobber_set (stmt);
7353 memset (uses, 0, sizeof (struct pt_solution));
7354 memset (clobbers, 0, sizeof (struct pt_solution));
7355 EXECUTE_IF_SET_IN_BITMAP (fi->solution, 0, i, bi)
7356 {
7357 struct pt_solution sol;
7358
7359 vi = get_varinfo (i);
7360 if (!vi->is_fn_info)
7361 {
7362 /* ??? We could be more precise here? */
7363 uses->nonlocal = 1;
7364 uses->ipa_escaped = 1;
7365 clobbers->nonlocal = 1;
7366 clobbers->ipa_escaped = 1;
7367 continue;
7368 }
7369
7370 if (!uses->anything)
7371 {
dd6f8b2c 7372 sol = find_what_var_points_to
7373 (first_vi_for_offset (vi, fi_uses));
1a981e1a 7374 pt_solution_ior_into (uses, &sol);
7375 }
7376 if (!clobbers->anything)
7377 {
dd6f8b2c 7378 sol = find_what_var_points_to
7379 (first_vi_for_offset (vi, fi_clobbers));
1a981e1a 7380 pt_solution_ior_into (clobbers, &sol);
7381 }
7382 }
7383 }
7384 }
7385 }
7386 }
7387
7388 fn->gimple_df->ipa_pta = true;
7389 }
7390
170c35d5 7391 delete_points_to_sets ();
7d1f52b2 7392
db026f5c 7393 in_ipa_mode = 0;
170c35d5 7394
2a1990e9 7395 return 0;
db026f5c 7396}
7d1f52b2 7397
cbe8bda8 7398namespace {
7399
7400const pass_data pass_data_ipa_pta =
7401{
7402 SIMPLE_IPA_PASS, /* type */
7403 "pta", /* name */
7404 OPTGROUP_NONE, /* optinfo_flags */
7405 true, /* has_gate */
7406 true, /* has_execute */
7407 TV_IPA_PTA, /* tv_id */
7408 0, /* properties_required */
7409 0, /* properties_provided */
7410 0, /* properties_destroyed */
7411 0, /* todo_flags_start */
7412 TODO_update_ssa, /* todo_flags_finish */
db026f5c 7413};
cbe8bda8 7414
7415class pass_ipa_pta : public simple_ipa_opt_pass
7416{
7417public:
9af5ce0c 7418 pass_ipa_pta (gcc::context *ctxt)
7419 : simple_ipa_opt_pass (pass_data_ipa_pta, ctxt)
cbe8bda8 7420 {}
7421
7422 /* opt_pass methods: */
7423 bool gate () { return gate_ipa_pta (); }
7424 unsigned int execute () { return ipa_pta_execute (); }
7425
7426}; // class pass_ipa_pta
7427
7428} // anon namespace
7429
7430simple_ipa_opt_pass *
7431make_pass_ipa_pta (gcc::context *ctxt)
7432{
7433 return new pass_ipa_pta (ctxt);
7434}