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