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