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