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