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