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