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 : 6158080622 : get_varinfo (unsigned int n)
352 : : {
353 : 13786997 : 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 : 630726036 : vi_next (varinfo_t vi)
361 : : {
362 : 630726036 : 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 : 221553789 : new_var_info (tree t, const char *name, bool add_id)
377 : : {
378 : 221553789 : unsigned index = varmap.length ();
379 : 221553789 : varinfo_t ret = variable_info_pool.allocate ();
380 : :
381 : 221553789 : if (dump_file && add_id)
382 : : {
383 : 2326 : char *tempname = xasprintf ("%s(%d)", name, index);
384 : 2326 : name = ggc_strdup (tempname);
385 : 2326 : free (tempname);
386 : : }
387 : :
388 : 221553789 : ret->id = index;
389 : 221553789 : ret->name = name;
390 : 221553789 : ret->decl = t;
391 : : /* Vars without decl are artificial and do not have sub-variables. */
392 : 221553789 : ret->is_artificial_var = (t == NULL_TREE);
393 : 221553789 : ret->is_special_var = false;
394 : 221553789 : ret->is_unknown_size_var = false;
395 : 221553789 : ret->is_full_var = (t == NULL_TREE);
396 : 221553789 : ret->is_heap_var = false;
397 : 221553789 : ret->may_have_pointers = true;
398 : 221553789 : ret->only_restrict_pointers = false;
399 : 221553789 : ret->is_restrict_var = false;
400 : 221553789 : ret->ruid = 0;
401 : 221553789 : ret->is_global_var = (t == NULL_TREE);
402 : 221553789 : ret->is_ipa_escape_point = false;
403 : 221553789 : ret->is_fn_info = false;
404 : 221553789 : ret->address_taken = false;
405 : 221553789 : if (t && DECL_P (t))
406 : 43109167 : ret->is_global_var = (is_global_var (t)
407 : : /* We have to treat even local register variables
408 : : as escape points. */
409 : 43109167 : || (VAR_P (t) && DECL_HARD_REGISTER (t)));
410 : 106175735 : ret->is_reg_var = (t && TREE_CODE (t) == SSA_NAME);
411 : 221553789 : ret->solution = BITMAP_ALLOC (&pta_obstack);
412 : 221553789 : ret->oldsolution = NULL;
413 : 221553789 : ret->next = 0;
414 : 221553789 : ret->shadow_var_uid = 0;
415 : 221553789 : ret->head = ret->id;
416 : :
417 : 221553789 : stats.total_vars++;
418 : :
419 : 221553789 : varmap.safe_push (ret);
420 : :
421 : 221553789 : 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 : 67656900 : get_call_vi (gcall *call)
432 : : {
433 : 67656900 : varinfo_t vi, vi2;
434 : :
435 : 67656900 : bool existed;
436 : 67656900 : varinfo_t *slot_p = &call_stmt_vars->get_or_insert (call, &existed);
437 : 67656900 : if (existed)
438 : 51878135 : return *slot_p;
439 : :
440 : 15778765 : vi = new_var_info (NULL_TREE, "CALLUSED", true);
441 : 15778765 : vi->offset = 0;
442 : 15778765 : vi->size = 1;
443 : 15778765 : vi->fullsize = 2;
444 : 15778765 : vi->is_full_var = true;
445 : 15778765 : vi->is_reg_var = true;
446 : :
447 : 15778765 : vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED", true);
448 : 15778765 : vi2->offset = 1;
449 : 15778765 : vi2->size = 1;
450 : 15778765 : vi2->fullsize = 2;
451 : 15778765 : vi2->is_full_var = true;
452 : 15778765 : vi2->is_reg_var = true;
453 : :
454 : 15778765 : vi->next = vi2->id;
455 : :
456 : 15778765 : *slot_p = vi;
457 : 15778765 : 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 : 30286355 : lookup_call_use_vi (gcall *call)
465 : : {
466 : 30286355 : varinfo_t *slot_p = call_stmt_vars->get (call);
467 : 30286355 : if (slot_p)
468 : 28590168 : 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 : 14506446 : lookup_call_clobber_vi (gcall *call)
478 : : {
479 : 14506446 : varinfo_t uses = lookup_call_use_vi (call);
480 : 14506446 : if (!uses)
481 : : return NULL;
482 : :
483 : 13666668 : 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 : 42411003 : 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 : 25245897 : get_call_clobber_vi (gcall *call)
500 : : {
501 : 25245897 : 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 : 9279382516 : find (unsigned int node)
641 : : {
642 : 9279382516 : gcc_checking_assert (node < graph->size);
643 : 9279382516 : if (graph->rep[node] != node)
644 : 1037240886 : 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 : 592378788 : unite (unsigned int to, unsigned int from)
655 : : {
656 : 592378788 : gcc_checking_assert (to < graph->size && from < graph->size);
657 : 592378788 : if (to != from && graph->rep[from] != to)
658 : : {
659 : 70524764 : graph->rep[from] = to;
660 : 70524764 : 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 : 438673337 : new_constraint (const struct constraint_expr lhs,
669 : : const struct constraint_expr rhs)
670 : : {
671 : 0 : constraint_t ret = constraint_pool.allocate ();
672 : 438673337 : ret->lhs = lhs;
673 : 438673337 : ret->rhs = rhs;
674 : 438673337 : return ret;
675 : : }
676 : :
677 : : /* Print out constraint C to FILE. */
678 : :
679 : : static void
680 : 9433 : dump_constraint (FILE *file, constraint_t c)
681 : : {
682 : 9433 : if (c->lhs.type == ADDRESSOF)
683 : 0 : fprintf (file, "&");
684 : 9433 : else if (c->lhs.type == DEREF)
685 : 864 : fprintf (file, "*");
686 : 9433 : if (dump_file)
687 : 9433 : fprintf (file, "%s", get_varinfo (c->lhs.var)->name);
688 : : else
689 : 0 : fprintf (file, "V%d", c->lhs.var);
690 : 9433 : if (c->lhs.offset == UNKNOWN_OFFSET)
691 : 6 : fprintf (file, " + UNKNOWN");
692 : 9427 : else if (c->lhs.offset != 0)
693 : 4 : fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->lhs.offset);
694 : 9433 : fprintf (file, " = ");
695 : 9433 : if (c->rhs.type == ADDRESSOF)
696 : 3385 : fprintf (file, "&");
697 : 6048 : else if (c->rhs.type == DEREF)
698 : 1206 : fprintf (file, "*");
699 : 9433 : if (dump_file)
700 : 9433 : fprintf (file, "%s", get_varinfo (c->rhs.var)->name);
701 : : else
702 : 0 : fprintf (file, "V%d", c->rhs.var);
703 : 9433 : if (c->rhs.offset == UNKNOWN_OFFSET)
704 : 1570 : fprintf (file, " + UNKNOWN");
705 : 7863 : else if (c->rhs.offset != 0)
706 : 103 : fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->rhs.offset);
707 : 9433 : }
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 : 9721 : for (i = from; constraints.iterate (i, &c); i++)
735 : 9337 : if (c)
736 : : {
737 : 9337 : dump_constraint (file, c);
738 : 9337 : 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 : 19318189 : constraint_expr_equal (struct constraint_expr a, struct constraint_expr b)
866 : : {
867 : 12087739 : 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 : 454118085 : constraint_expr_less (struct constraint_expr a, struct constraint_expr b)
876 : : {
877 : 0 : if (a.type == b.type)
878 : : {
879 : 271552118 : if (a.var == b.var)
880 : 203393263 : return a.offset < b.offset;
881 : : else
882 : 68158855 : return a.var < b.var;
883 : : }
884 : : else
885 : 182565967 : 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 : 249938001 : constraint_less (const constraint_t &a, const constraint_t &b)
893 : : {
894 : 499876002 : if (constraint_expr_less (a->lhs, b->lhs))
895 : : return true;
896 : 215876604 : else if (constraint_expr_less (b->lhs, a->lhs))
897 : : return false;
898 : : else
899 : 96241782 : 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 : 12666548 : constraint_equal (const constraint &a, const constraint &b)
906 : : {
907 : 19318189 : return constraint_expr_equal (a.lhs, b.lhs)
908 : 12666548 : && 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 : 278981 : constraint_vec_find (vec<constraint_t> vec,
916 : : constraint &lookfor)
917 : : {
918 : 278981 : unsigned int place;
919 : 278981 : constraint_t found;
920 : :
921 : 278981 : if (!vec.exists ())
922 : : return NULL;
923 : :
924 : 224629 : place = vec.lower_bound (&lookfor, constraint_less);
925 : 224629 : if (place >= vec.length ())
926 : : return NULL;
927 : 90098 : found = vec[place];
928 : 90098 : 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 : 70404505 : constraint_set_union (vec<constraint_t> *to,
938 : : vec<constraint_t> *from)
939 : : {
940 : 70404505 : int i;
941 : 70404505 : constraint_t c;
942 : 70404505 : bool any_change = false;
943 : :
944 : 70683486 : FOR_EACH_VEC_ELT (*from, i, c)
945 : : {
946 : 278981 : if (constraint_vec_find (*to, *c) == NULL)
947 : : {
948 : 278323 : unsigned int place = to->lower_bound (c, constraint_less);
949 : 278323 : to->safe_insert (place, c);
950 : 278323 : any_change = true;
951 : : }
952 : : }
953 : 70404505 : return any_change;
954 : : }
955 : :
956 : : /* Expands the solution in SET to all sub-fields of variables included. */
957 : :
958 : : static bitmap
959 : 135284593 : solution_set_expand (bitmap set, bitmap *expanded)
960 : : {
961 : 135284593 : bitmap_iterator bi;
962 : 135284593 : unsigned j;
963 : :
964 : 135284593 : if (*expanded)
965 : : return *expanded;
966 : :
967 : 75347555 : *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 : 75347555 : unsigned prev_head = 0;
972 : 295410656 : EXECUTE_IF_SET_IN_BITMAP (set, 0, j, bi)
973 : : {
974 : 220063101 : varinfo_t v = get_varinfo (j);
975 : 220063101 : if (v->is_artificial_var
976 : 130702373 : || v->is_full_var)
977 : 110569267 : continue;
978 : 109493834 : if (v->head != prev_head)
979 : : {
980 : 24949000 : varinfo_t head = get_varinfo (v->head);
981 : 24949000 : unsigned num = 1;
982 : 145885116 : for (varinfo_t n = vi_next (head); n != NULL; n = vi_next (n))
983 : : {
984 : 120936116 : 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 : 14522 : bitmap_set_range (*expanded, head->id, num);
990 : 14522 : head = n;
991 : 14522 : num = 1;
992 : : }
993 : : else
994 : 120921594 : num++;
995 : : }
996 : :
997 : 24949000 : bitmap_set_range (*expanded, head->id, num);
998 : 24949000 : prev_head = v->head;
999 : : }
1000 : : }
1001 : :
1002 : : /* And finally set the rest of the bits from SET in an efficient way. */
1003 : 75347555 : bitmap_ior_into (*expanded, set);
1004 : :
1005 : 75347555 : 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 : 84390778 : set_union_with_increment (bitmap to, bitmap delta, HOST_WIDE_INT inc,
1013 : : bitmap *expanded_delta)
1014 : : {
1015 : 84390778 : bool changed = false;
1016 : 84390778 : bitmap_iterator bi;
1017 : 84390778 : unsigned int i;
1018 : :
1019 : : /* If the solution of DELTA contains anything it is good enough to transfer
1020 : : this to TO. */
1021 : 84390778 : if (bitmap_bit_p (delta, anything_id))
1022 : 1294994 : 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 : 83095784 : if (inc == UNKNOWN_OFFSET)
1027 : : {
1028 : 82123288 : delta = solution_set_expand (delta, expanded_delta);
1029 : 82123288 : changed |= bitmap_ior_into (to, delta);
1030 : 82123288 : return changed;
1031 : : }
1032 : :
1033 : : /* For non-zero offset union the offsetted solution into the destination. */
1034 : 4228010 : EXECUTE_IF_SET_IN_BITMAP (delta, 0, i, bi)
1035 : : {
1036 : 3255514 : 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 : 3255514 : if (vi->is_artificial_var
1041 : 1951535 : || vi->is_unknown_size_var
1042 : 1817439 : || vi->is_full_var)
1043 : 1686668 : changed |= bitmap_set_bit (to, i);
1044 : : else
1045 : : {
1046 : 1568846 : HOST_WIDE_INT fieldoffset = vi->offset + inc;
1047 : 1568846 : 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 : 1568846 : if (fieldoffset < 0)
1052 : 32591 : vi = get_varinfo (vi->head);
1053 : : else
1054 : 1536255 : vi = first_or_preceding_vi_for_offset (vi, fieldoffset);
1055 : :
1056 : 1893042 : do
1057 : : {
1058 : 1893042 : changed |= bitmap_set_bit (to, vi->id);
1059 : 1893042 : if (vi->is_full_var
1060 : 1893002 : || vi->next == 0)
1061 : : break;
1062 : :
1063 : : /* We have to include all fields that overlap the current field
1064 : : shifted by inc. */
1065 : 894717 : vi = vi_next (vi);
1066 : : }
1067 : 894717 : 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 : 144776962 : insert_into_complex (constraint_graph_t graph,
1079 : : unsigned int var, constraint_t c)
1080 : : {
1081 : 144776962 : vec<constraint_t> complex = graph->complex[var];
1082 : 144776962 : unsigned int place = complex.lower_bound (c, constraint_less);
1083 : :
1084 : : /* Only insert constraints that do not already exist. */
1085 : 144776962 : if (place >= complex.length ()
1086 : 99662313 : || !constraint_equal (*c, *complex[place]))
1087 : 142746164 : graph->complex[var].safe_insert (place, c);
1088 : 144776962 : }
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 : 70404505 : merge_node_constraints (constraint_graph_t graph, unsigned int to,
1097 : : unsigned int from)
1098 : : {
1099 : 70404505 : unsigned int i;
1100 : 70404505 : constraint_t c;
1101 : 70404505 : bool any_change = false;
1102 : :
1103 : 70404505 : gcc_checking_assert (find (from) == to);
1104 : :
1105 : : /* Move all complex constraints from src node into to node */
1106 : 70683486 : 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 : 278981 : if (c->rhs.type == DEREF)
1113 : 91235 : c->rhs.var = to;
1114 : 187746 : else if (c->lhs.type == DEREF)
1115 : 92113 : c->lhs.var = to;
1116 : : else
1117 : 95633 : c->rhs.var = to;
1118 : :
1119 : : }
1120 : 70404505 : any_change = constraint_set_union (&graph->complex[to],
1121 : : &graph->complex[from]);
1122 : 70404505 : graph->complex[from].release ();
1123 : 70404505 : return any_change;
1124 : : }
1125 : :
1126 : :
1127 : : /* Remove edges involving NODE from GRAPH. */
1128 : :
1129 : : static void
1130 : 90054823 : clear_edges_for_node (constraint_graph_t graph, unsigned int node)
1131 : : {
1132 : 90054823 : if (graph->succs[node])
1133 : 2466337 : BITMAP_FREE (graph->succs[node]);
1134 : 90054823 : }
1135 : :
1136 : : /* Merge GRAPH nodes FROM and TO into node TO. */
1137 : :
1138 : : static void
1139 : 70404505 : merge_graph_nodes (constraint_graph_t graph, unsigned int to,
1140 : : unsigned int from)
1141 : : {
1142 : 70404505 : 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 : 104 : if (graph->indirect_cycles[to] == -1)
1151 : 49 : graph->indirect_cycles[to] = graph->indirect_cycles[from];
1152 : : }
1153 : :
1154 : : /* Merge all the successor edges. */
1155 : 70404505 : if (graph->succs[from])
1156 : : {
1157 : 2466337 : if (!graph->succs[to])
1158 : 1232915 : graph->succs[to] = BITMAP_ALLOC (&pta_obstack);
1159 : 2466337 : bitmap_ior_into (graph->succs[to],
1160 : 2466337 : graph->succs[from]);
1161 : : }
1162 : :
1163 : 70404505 : clear_edges_for_node (graph, from);
1164 : 70404505 : }
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 : 290057264 : add_implicit_graph_edge (constraint_graph_t graph, unsigned int to,
1172 : : unsigned int from)
1173 : : {
1174 : 290057264 : if (to == from)
1175 : : return;
1176 : :
1177 : 290057264 : if (!graph->implicit_preds[to])
1178 : 163237087 : graph->implicit_preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
1179 : :
1180 : 290057264 : if (bitmap_set_bit (graph->implicit_preds[to], from))
1181 : 272989111 : 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 : 245599392 : add_pred_graph_edge (constraint_graph_t graph, unsigned int to,
1190 : : unsigned int from)
1191 : : {
1192 : 245599392 : if (!graph->preds[to])
1193 : 145412889 : graph->preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
1194 : 245599392 : bitmap_set_bit (graph->preds[to], from);
1195 : 245599392 : }
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 : 792339821 : add_graph_edge (constraint_graph_t graph, unsigned int to,
1203 : : unsigned int from)
1204 : : {
1205 : 792339821 : if (to == from)
1206 : : {
1207 : : return false;
1208 : : }
1209 : : else
1210 : : {
1211 : 791588910 : bool r = false;
1212 : :
1213 : 791588910 : if (!graph->succs[from])
1214 : 91687654 : 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 : 791588910 : if (to < FIRST_REF_NODE
1227 : 759975587 : && bitmap_bit_p (graph->succs[from], find (escaped_id))
1228 : 1156860761 : && bitmap_bit_p (get_varinfo (find (to))->solution, escaped_id))
1229 : : {
1230 : 307413196 : stats.num_avoided_edges++;
1231 : 307413196 : return false;
1232 : : }
1233 : :
1234 : 484175714 : if (bitmap_set_bit (graph->succs[from], to))
1235 : : {
1236 : 338305998 : r = true;
1237 : 338305998 : if (to < FIRST_REF_NODE && from < FIRST_REF_NODE)
1238 : 294741714 : stats.num_edges++;
1239 : : }
1240 : 484175714 : return r;
1241 : : }
1242 : : }
1243 : :
1244 : :
1245 : : /* Initialize the constraint graph structure to contain SIZE nodes. */
1246 : :
1247 : : static void
1248 : 4408981 : init_graph (unsigned int size)
1249 : : {
1250 : 4408981 : unsigned int j;
1251 : :
1252 : 4408981 : graph = XCNEW (struct constraint_graph);
1253 : 4408981 : graph->size = size;
1254 : 4408981 : graph->succs = XCNEWVEC (bitmap, graph->size);
1255 : 4408981 : graph->indirect_cycles = XNEWVEC (int, graph->size);
1256 : 4408981 : 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 : 4408981 : typedef vec<constraint_t> vec_constraint_t_heap;
1260 : 4408981 : graph->complex = XCNEWVEC (vec_constraint_t_heap, size);
1261 : 4408981 : graph->pe = XCNEWVEC (unsigned int, graph->size);
1262 : 4408981 : graph->pe_rep = XNEWVEC (int, graph->size);
1263 : :
1264 : 456334521 : for (j = 0; j < graph->size; j++)
1265 : : {
1266 : 451925540 : graph->rep[j] = j;
1267 : 451925540 : graph->pe_rep[j] = -1;
1268 : 451925540 : graph->indirect_cycles[j] = -1;
1269 : : }
1270 : 4408981 : }
1271 : :
1272 : : /* Build the constraint graph, adding only predecessor edges right now. */
1273 : :
1274 : : static void
1275 : 4408981 : build_pred_graph (void)
1276 : : {
1277 : 4408981 : int i;
1278 : 4408981 : constraint_t c;
1279 : 4408981 : unsigned int j;
1280 : :
1281 : 4408981 : graph->implicit_preds = XCNEWVEC (bitmap, graph->size);
1282 : 4408981 : graph->preds = XCNEWVEC (bitmap, graph->size);
1283 : 4408981 : graph->pointer_label = XCNEWVEC (unsigned int, graph->size);
1284 : 4408981 : graph->loc_label = XCNEWVEC (unsigned int, graph->size);
1285 : 4408981 : graph->pointed_by = XCNEWVEC (bitmap, graph->size);
1286 : 4408981 : graph->points_to = XCNEWVEC (bitmap, graph->size);
1287 : 4408981 : graph->eq_rep = XNEWVEC (int, graph->size);
1288 : 4408981 : graph->direct_nodes = sbitmap_alloc (graph->size);
1289 : 4408981 : graph->address_taken = BITMAP_ALLOC (&predbitmap_obstack);
1290 : 4408981 : bitmap_clear (graph->direct_nodes);
1291 : :
1292 : 456334521 : for (j = 1; j < FIRST_REF_NODE; j++)
1293 : : {
1294 : 221553789 : if (!get_varinfo (j)->is_special_var)
1295 : 199508884 : bitmap_set_bit (graph->direct_nodes, j);
1296 : : }
1297 : :
1298 : 456334521 : for (j = 0; j < graph->size; j++)
1299 : 451925540 : graph->eq_rep[j] = -1;
1300 : :
1301 : 460743502 : for (j = 0; j < varmap.length (); j++)
1302 : 225962770 : graph->indirect_cycles[j] = -1;
1303 : :
1304 : 440477990 : FOR_EACH_VEC_ELT (constraints, i, c)
1305 : : {
1306 : 436069009 : struct constraint_expr lhs = c->lhs;
1307 : 436069009 : struct constraint_expr rhs = c->rhs;
1308 : 436069009 : unsigned int lhsvar = lhs.var;
1309 : 436069009 : unsigned int rhsvar = rhs.var;
1310 : :
1311 : 436069009 : if (lhs.type == DEREF)
1312 : : {
1313 : : /* *x = y. */
1314 : 35913271 : if (rhs.offset == 0 && lhs.offset == 0 && rhs.type == SCALAR)
1315 : : {
1316 : 31640601 : if (lhs.var == anything_id)
1317 : 0 : add_pred_graph_edge (graph, storedanything_id, rhsvar);
1318 : : else
1319 : 63281202 : add_pred_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
1320 : : }
1321 : : }
1322 : 400155738 : else if (rhs.type == DEREF)
1323 : : {
1324 : : /* x = *y */
1325 : 48861309 : if (rhs.offset == 0 && lhs.offset == 0 && lhs.type == SCALAR)
1326 : 25984998 : add_pred_graph_edge (graph, lhsvar, FIRST_REF_NODE + rhsvar);
1327 : : else
1328 : 35868810 : bitmap_clear_bit (graph->direct_nodes, lhsvar);
1329 : : }
1330 : 351294429 : else if (rhs.type == ADDRESSOF)
1331 : : {
1332 : 89090972 : varinfo_t v;
1333 : :
1334 : : /* x = &y */
1335 : 89090972 : if (graph->points_to[lhsvar] == NULL)
1336 : 66309789 : graph->points_to[lhsvar] = BITMAP_ALLOC (&predbitmap_obstack);
1337 : 89090972 : bitmap_set_bit (graph->points_to[lhsvar], rhsvar);
1338 : :
1339 : 89090972 : if (graph->pointed_by[rhsvar] == NULL)
1340 : 21403020 : graph->pointed_by[rhsvar] = BITMAP_ALLOC (&predbitmap_obstack);
1341 : 89090972 : bitmap_set_bit (graph->pointed_by[rhsvar], lhsvar);
1342 : :
1343 : : /* Implicitly, *x = y */
1344 : 178181944 : add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
1345 : :
1346 : : /* All related variables are no longer direct nodes. */
1347 : 89090972 : bitmap_clear_bit (graph->direct_nodes, rhsvar);
1348 : 89090972 : v = get_varinfo (rhsvar);
1349 : 89090972 : if (!v->is_full_var)
1350 : : {
1351 : 7294396 : v = get_varinfo (v->head);
1352 : 46308695 : do
1353 : : {
1354 : 46308695 : bitmap_clear_bit (graph->direct_nodes, v->id);
1355 : 46308695 : v = vi_next (v);
1356 : : }
1357 : 46308695 : while (v != NULL);
1358 : : }
1359 : 89090972 : bitmap_set_bit (graph->address_taken, rhsvar);
1360 : : }
1361 : 262203457 : else if (lhsvar > anything_id
1362 : 262203457 : && lhsvar != rhsvar && lhs.offset == 0 && rhs.offset == 0)
1363 : : {
1364 : : /* x = y */
1365 : 200966292 : add_pred_graph_edge (graph, lhsvar, rhsvar);
1366 : : /* Implicitly, *x = *y */
1367 : 200966292 : add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar,
1368 : 200966292 : FIRST_REF_NODE + rhsvar);
1369 : : }
1370 : 61237165 : else if (lhs.offset != 0 || rhs.offset != 0)
1371 : : {
1372 : 61045598 : if (rhs.offset != 0)
1373 : 61045598 : 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 : 4408981 : }
1379 : :
1380 : : /* Build the constraint graph, adding successor edges. */
1381 : :
1382 : : static void
1383 : 4408981 : build_succ_graph (void)
1384 : : {
1385 : 4408981 : unsigned i, t;
1386 : 4408981 : constraint_t c;
1387 : :
1388 : 440477990 : FOR_EACH_VEC_ELT (constraints, i, c)
1389 : : {
1390 : 436069009 : struct constraint_expr lhs;
1391 : 436069009 : struct constraint_expr rhs;
1392 : 436069009 : unsigned int lhsvar;
1393 : 436069009 : unsigned int rhsvar;
1394 : :
1395 : 436069009 : if (!c)
1396 : 2536189 : continue;
1397 : :
1398 : 433532820 : lhs = c->lhs;
1399 : 433532820 : rhs = c->rhs;
1400 : 433532820 : lhsvar = find (lhs.var);
1401 : 433532820 : rhsvar = find (rhs.var);
1402 : :
1403 : 433532820 : if (lhs.type == DEREF)
1404 : : {
1405 : 35867393 : if (rhs.offset == 0 && lhs.offset == 0 && rhs.type == SCALAR)
1406 : : {
1407 : 31613323 : if (lhs.var == anything_id)
1408 : 0 : add_graph_edge (graph, storedanything_id, rhsvar);
1409 : : else
1410 : 63226646 : add_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
1411 : : }
1412 : : }
1413 : 397665427 : else if (rhs.type == DEREF)
1414 : : {
1415 : 48860329 : if (rhs.offset == 0 && lhs.offset == 0 && lhs.type == SCALAR)
1416 : 25983426 : add_graph_edge (graph, lhsvar, FIRST_REF_NODE + rhsvar);
1417 : : }
1418 : 348805098 : else if (rhs.type == ADDRESSOF)
1419 : : {
1420 : : /* x = &y */
1421 : 89090972 : gcc_checking_assert (find (rhs.var) == rhs.var);
1422 : 89090972 : bitmap_set_bit (get_varinfo (lhsvar)->solution, rhsvar);
1423 : : }
1424 : 259714126 : else if (lhsvar > anything_id
1425 : 259714126 : && lhsvar != rhsvar && lhs.offset == 0 && rhs.offset == 0)
1426 : : {
1427 : 151801936 : add_graph_edge (graph, lhsvar, rhsvar);
1428 : : }
1429 : : }
1430 : :
1431 : : /* Add edges from STOREDANYTHING to all nodes that can receive pointers. */
1432 : 4408981 : t = find (storedanything_id);
1433 : 195099903 : for (i = integer_id + 1; i < FIRST_REF_NODE; ++i)
1434 : : {
1435 : 186281941 : if (get_varinfo (i)->may_have_pointers)
1436 : 186258570 : add_graph_edge (graph, find (i), t);
1437 : : }
1438 : :
1439 : : /* Everything stored to ANYTHING also potentially escapes. */
1440 : 4408981 : add_graph_edge (graph, find (escaped_id), t);
1441 : 4408981 : }
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 : 378299451 : scc_visit (constraint_graph_t graph, class scc_info *si, unsigned int n)
1477 : : {
1478 : 378299451 : unsigned int i;
1479 : 378299451 : bitmap_iterator bi;
1480 : 378299451 : unsigned int my_dfs;
1481 : :
1482 : 378299451 : bitmap_set_bit (si->visited, n);
1483 : 378299451 : si->dfs[n] = si->current_index ++;
1484 : 378299451 : my_dfs = si->dfs[n];
1485 : :
1486 : : /* Visit all the successors. */
1487 : 642186562 : EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[n], 0, i, bi)
1488 : : {
1489 : 263887111 : unsigned int w;
1490 : :
1491 : 527774222 : if (i > LAST_REF_NODE)
1492 : : break;
1493 : :
1494 : 263887111 : w = find (i);
1495 : 263887111 : if (bitmap_bit_p (si->deleted, w))
1496 : 114417798 : continue;
1497 : :
1498 : 149469313 : if (!bitmap_bit_p (si->visited, w))
1499 : 149201008 : scc_visit (graph, si, w);
1500 : :
1501 : 149469313 : unsigned int t = find (w);
1502 : 149469313 : gcc_checking_assert (find (n) == n);
1503 : 149469313 : if (si->dfs[t] < si->dfs[n])
1504 : 139838 : si->dfs[n] = si->dfs[t];
1505 : : }
1506 : :
1507 : : /* See if any components have been identified. */
1508 : 378299451 : if (si->dfs[n] == my_dfs)
1509 : : {
1510 : 378159919 : if (si->scc_stack.length () > 0
1511 : 378159919 : && si->dfs[si->scc_stack.last ()] >= my_dfs)
1512 : : {
1513 : 105921 : bitmap scc = BITMAP_ALLOC (NULL);
1514 : 105921 : unsigned int lowest_node;
1515 : 105921 : bitmap_iterator bi;
1516 : :
1517 : 105921 : bitmap_set_bit (scc, n);
1518 : :
1519 : 105921 : while (si->scc_stack.length () != 0
1520 : 245453 : && si->dfs[si->scc_stack.last ()] >= my_dfs)
1521 : : {
1522 : 139532 : unsigned int w = si->scc_stack.pop ();
1523 : :
1524 : 139532 : bitmap_set_bit (scc, w);
1525 : : }
1526 : :
1527 : 105921 : lowest_node = bitmap_first_set_bit (scc);
1528 : 105921 : gcc_assert (lowest_node < FIRST_REF_NODE);
1529 : :
1530 : : /* Collapse the SCC nodes into a single node, and mark the
1531 : : indirect cycles. */
1532 : 351374 : EXECUTE_IF_SET_IN_BITMAP (scc, 0, i, bi)
1533 : : {
1534 : 245453 : if (i < FIRST_REF_NODE)
1535 : : {
1536 : 125194 : if (unite (lowest_node, i))
1537 : 19273 : unify_nodes (graph, lowest_node, i, false);
1538 : : }
1539 : : else
1540 : : {
1541 : 120259 : unite (lowest_node, i);
1542 : 240518 : graph->indirect_cycles[i - FIRST_REF_NODE] = lowest_node;
1543 : : }
1544 : : }
1545 : 105921 : bitmap_set_bit (si->deleted, lowest_node);
1546 : : }
1547 : : else
1548 : 378053998 : bitmap_set_bit (si->deleted, n);
1549 : : }
1550 : : else
1551 : 139532 : si->scc_stack.safe_push (n);
1552 : 378299451 : }
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 : 70404505 : unify_nodes (constraint_graph_t graph, unsigned int to, unsigned int from,
1559 : : bool update_changed)
1560 : : {
1561 : 70404505 : gcc_checking_assert (to != from && find (to) == to);
1562 : :
1563 : 70404505 : if (dump_file && (dump_flags & TDF_DETAILS))
1564 : 1224 : fprintf (dump_file, "Unifying %s to %s\n",
1565 : 1224 : get_varinfo (from)->name,
1566 : 1224 : get_varinfo (to)->name);
1567 : :
1568 : 70404505 : if (update_changed)
1569 : 337297 : stats.unified_vars_dynamic++;
1570 : : else
1571 : 70067208 : stats.unified_vars_static++;
1572 : :
1573 : 70404505 : merge_graph_nodes (graph, to, from);
1574 : 70404505 : if (merge_node_constraints (graph, to, from))
1575 : : {
1576 : 94831 : if (update_changed)
1577 : 12048 : 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 : 70321722 : if (update_changed
1584 : 70321722 : && bitmap_clear_bit (changed, from))
1585 : 37175 : bitmap_set_bit (changed, to);
1586 : 70404505 : varinfo_t fromvi = get_varinfo (from);
1587 : 70404505 : if (fromvi->solution)
1588 : : {
1589 : : /* If the solution changes because of the merging, we need to mark
1590 : : the variable as changed. */
1591 : 70404505 : varinfo_t tovi = get_varinfo (to);
1592 : 70404505 : if (bitmap_ior_into (tovi->solution, fromvi->solution))
1593 : : {
1594 : 1940228 : if (update_changed)
1595 : 66302 : bitmap_set_bit (changed, to);
1596 : : }
1597 : :
1598 : 70404505 : BITMAP_FREE (fromvi->solution);
1599 : 70404505 : if (fromvi->oldsolution)
1600 : 210786 : BITMAP_FREE (fromvi->oldsolution);
1601 : :
1602 : 70404505 : if (stats.iterations > 0
1603 : 337297 : && tovi->oldsolution)
1604 : 19370 : BITMAP_FREE (tovi->oldsolution);
1605 : : }
1606 : 70404505 : if (graph->succs[to])
1607 : 2652486 : bitmap_clear_bit (graph->succs[to], to);
1608 : 70404505 : }
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 : 426751889 : 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 : 426751889 : if (get_varinfo (from)->is_special_var)
1620 : 30516459 : return bitmap_ior_into (get_varinfo (to)->solution,
1621 : 61032918 : get_varinfo (from)->solution);
1622 : : /* Merging the solution from ESCAPED needlessly increases
1623 : : the set. Use ESCAPED as representative instead. */
1624 : 396235430 : else if (from == find (escaped_id))
1625 : 35194980 : return bitmap_set_bit (get_varinfo (to)->solution, escaped_id);
1626 : 361040450 : else if (get_varinfo (from)->may_have_pointers
1627 : 361040450 : && add_graph_edge (graph, to, from))
1628 : 116729648 : return bitmap_ior_into (get_varinfo (to)->solution,
1629 : 116729648 : 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 : 69504150 : do_sd_constraint (constraint_graph_t graph, constraint_t c,
1638 : : bitmap delta, bitmap *expanded_delta)
1639 : : {
1640 : 69504150 : unsigned int lhs = c->lhs.var;
1641 : 69504150 : bool flag = false;
1642 : 69504150 : bitmap sol = get_varinfo (lhs)->solution;
1643 : 69504150 : unsigned int j;
1644 : 69504150 : bitmap_iterator bi;
1645 : 69504150 : HOST_WIDE_INT roffset = c->rhs.offset;
1646 : :
1647 : : /* Our IL does not allow this. */
1648 : 69504150 : 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 : 69504150 : if (bitmap_bit_p (delta, anything_id))
1653 : : {
1654 : 672417 : flag |= bitmap_set_bit (sol, anything_id);
1655 : 672417 : 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 : 68831733 : if (roffset == UNKNOWN_OFFSET)
1662 : : {
1663 : 51105759 : delta = solution_set_expand (delta, expanded_delta);
1664 : : /* No further offset processing is necessary. */
1665 : 51105759 : 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 : 312789503 : EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
1671 : : {
1672 : 243957770 : varinfo_t v = get_varinfo (j);
1673 : 243957770 : HOST_WIDE_INT fieldoffset = v->offset + roffset;
1674 : 243957770 : unsigned HOST_WIDE_INT size = v->size;
1675 : 243957770 : unsigned int t;
1676 : :
1677 : 243957770 : if (v->is_full_var)
1678 : : ;
1679 : 145480727 : else if (roffset != 0)
1680 : : {
1681 : 5706599 : if (fieldoffset < 0)
1682 : 131844 : v = get_varinfo (v->head);
1683 : : else
1684 : 5574755 : 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 : 245627459 : do
1690 : : {
1691 : 245627459 : t = find (v->id);
1692 : :
1693 : 245627459 : flag |= solve_add_graph_edge (graph, lhs, t);
1694 : :
1695 : 245627459 : if (v->is_full_var
1696 : 147150224 : || v->next == 0)
1697 : : break;
1698 : :
1699 : 119761913 : v = vi_next (v);
1700 : : }
1701 : 119761913 : while (v->offset < fieldoffset + size);
1702 : : }
1703 : :
1704 : 68831733 : done:
1705 : : /* If the LHS solution changed, mark the var as changed. */
1706 : 69504150 : if (flag)
1707 : 28067931 : bitmap_set_bit (changed, lhs);
1708 : 69504150 : }
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 : 55932223 : do_ds_constraint (constraint_t c, bitmap delta, bitmap *expanded_delta)
1715 : : {
1716 : 55932223 : unsigned int rhs = c->rhs.var;
1717 : 55932223 : bitmap sol = get_varinfo (rhs)->solution;
1718 : 55932223 : unsigned int j;
1719 : 55932223 : bitmap_iterator bi;
1720 : 55932223 : HOST_WIDE_INT loff = c->lhs.offset;
1721 : 55932223 : bool escaped_p = false;
1722 : :
1723 : : /* Our IL does not allow this. */
1724 : 55932223 : 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 : 55932223 : if (bitmap_bit_p (sol, anything_id))
1729 : 453837 : 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 : 55932223 : if (bitmap_bit_p (delta, anything_id))
1735 : : {
1736 : 503775 : unsigned t = find (storedanything_id);
1737 : 503775 : if (solve_add_graph_edge (graph, t, rhs))
1738 : 36697 : bitmap_set_bit (changed, t);
1739 : 503775 : 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 : 55428448 : if (loff == UNKNOWN_OFFSET)
1746 : : {
1747 : 2055546 : delta = solution_set_expand (delta, expanded_delta);
1748 : 2055546 : 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 : 272217937 : EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
1754 : : {
1755 : 216789489 : varinfo_t v = get_varinfo (j);
1756 : 216789489 : unsigned int t;
1757 : 216789489 : HOST_WIDE_INT fieldoffset = v->offset + loff;
1758 : 216789489 : unsigned HOST_WIDE_INT size = v->size;
1759 : :
1760 : 216789489 : if (v->is_full_var)
1761 : : ;
1762 : 132812282 : else if (loff != 0)
1763 : : {
1764 : 7931270 : if (fieldoffset < 0)
1765 : 4907 : v = get_varinfo (v->head);
1766 : : else
1767 : 7926363 : 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 : 219164699 : do
1773 : : {
1774 : 219164699 : if (v->may_have_pointers)
1775 : : {
1776 : : /* If v is a global variable then this is an escape point. */
1777 : 206618122 : if (v->is_global_var
1778 : 154352040 : && !escaped_p)
1779 : : {
1780 : 44225253 : t = find (escaped_id);
1781 : 44225253 : if (add_graph_edge (graph, t, rhs)
1782 : 57689448 : && bitmap_ior_into (get_varinfo (t)->solution, sol))
1783 : 1303368 : bitmap_set_bit (changed, t);
1784 : : /* Enough to let rhs escape once. */
1785 : : escaped_p = true;
1786 : : }
1787 : :
1788 : 206618122 : if (v->is_special_var)
1789 : : break;
1790 : :
1791 : 180620655 : t = find (v->id);
1792 : :
1793 : 180620655 : if (solve_add_graph_edge (graph, t, rhs))
1794 : 12216978 : bitmap_set_bit (changed, t);
1795 : : }
1796 : :
1797 : 193167232 : if (v->is_full_var
1798 : 135187350 : || v->next == 0)
1799 : : break;
1800 : :
1801 : 110306834 : v = vi_next (v);
1802 : : }
1803 : 110306834 : 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 : 209827151 : do_complex_constraint (constraint_graph_t graph, constraint_t c, bitmap delta,
1812 : : bitmap *expanded_delta)
1813 : : {
1814 : 209827151 : if (c->lhs.type == DEREF)
1815 : : {
1816 : 55932223 : if (c->rhs.type == ADDRESSOF)
1817 : : {
1818 : 0 : gcc_unreachable ();
1819 : : }
1820 : : else
1821 : : {
1822 : : /* *x = y */
1823 : 55932223 : do_ds_constraint (c, delta, expanded_delta);
1824 : : }
1825 : : }
1826 : 153894928 : else if (c->rhs.type == DEREF)
1827 : : {
1828 : : /* x = *y */
1829 : 69504150 : if (!(get_varinfo (c->lhs.var)->is_special_var))
1830 : 69504150 : do_sd_constraint (graph, c, delta, expanded_delta);
1831 : : }
1832 : : else
1833 : : {
1834 : 84390778 : bitmap tmp;
1835 : 84390778 : bool flag = false;
1836 : :
1837 : 84390778 : gcc_checking_assert (c->rhs.type == SCALAR && c->lhs.type == SCALAR
1838 : : && c->rhs.offset != 0 && c->lhs.offset == 0);
1839 : 84390778 : tmp = get_varinfo (c->lhs.var)->solution;
1840 : :
1841 : 84390778 : flag = set_union_with_increment (tmp, delta, c->rhs.offset,
1842 : : expanded_delta);
1843 : :
1844 : 84390778 : if (flag)
1845 : 20812081 : bitmap_set_bit (changed, c->lhs.var);
1846 : : }
1847 : 209827151 : }
1848 : :
1849 : : /* Initialize and return a new SCC info structure. */
1850 : :
1851 : 8817962 : scc_info::scc_info (size_t size) :
1852 : 8817962 : visited (size), deleted (size), current_index (0), scc_stack (1)
1853 : : {
1854 : 8817962 : bitmap_clear (visited);
1855 : 8817962 : bitmap_clear (deleted);
1856 : 8817962 : node_mapping = XNEWVEC (unsigned int, size);
1857 : 8817962 : dfs = XCNEWVEC (unsigned int, size);
1858 : :
1859 : 912669042 : for (size_t i = 0; i < size; i++)
1860 : 903851080 : node_mapping[i] = i;
1861 : 8817962 : }
1862 : :
1863 : : /* Free an SCC info structure pointed to by SI */
1864 : :
1865 : 8817962 : scc_info::~scc_info ()
1866 : : {
1867 : 8817962 : free (node_mapping);
1868 : 8817962 : free (dfs);
1869 : 8817962 : }
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 : 4408981 : find_indirect_cycles (constraint_graph_t graph)
1881 : : {
1882 : 4408981 : unsigned int i;
1883 : 4408981 : unsigned int size = graph->size;
1884 : 4408981 : scc_info si (size);
1885 : :
1886 : 908260061 : for (i = 0; i < MIN (LAST_REF_NODE, size); i ++ )
1887 : 447516559 : if (!bitmap_bit_p (si.visited, i) && find (i) == i)
1888 : 229098443 : scc_visit (graph, &si, i);
1889 : 4408981 : }
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 : 383173889 : topo_visit (constraint_graph_t graph, vec<unsigned> &topo_order,
1896 : : sbitmap visited, unsigned int n)
1897 : : {
1898 : 383173889 : bitmap_iterator bi;
1899 : 383173889 : unsigned int j;
1900 : :
1901 : 383173889 : bitmap_set_bit (visited, n);
1902 : :
1903 : 383173889 : if (graph->succs[n])
1904 : 931350936 : EXECUTE_IF_SET_IN_BITMAP (graph->succs[n], 0, j, bi)
1905 : : {
1906 : 735149551 : unsigned k = find (j);
1907 : 735149551 : if (!bitmap_bit_p (visited, k))
1908 : 280206057 : topo_visit (graph, topo_order, visited, k);
1909 : : }
1910 : :
1911 : : /* Also consider copy with offset complex constraints as implicit edges. */
1912 : 820179066 : for (auto c : graph->complex[n])
1913 : : {
1914 : : /* Constraints are ordered so that SCALAR = SCALAR appear first. */
1915 : 254110446 : if (c->lhs.type != SCALAR || c->rhs.type != SCALAR)
1916 : : break;
1917 : 141613181 : gcc_checking_assert (c->rhs.var == n);
1918 : 141613181 : unsigned k = find (c->lhs.var);
1919 : 141613181 : if (!bitmap_bit_p (visited, k))
1920 : 36419743 : topo_visit (graph, topo_order, visited, k);
1921 : : }
1922 : :
1923 : 383173889 : topo_order.quick_push (n);
1924 : 383173889 : }
1925 : :
1926 : : /* Compute a topological ordering for GRAPH, and return the result. */
1927 : :
1928 : : static auto_vec<unsigned>
1929 : 7785451 : compute_topo_order (constraint_graph_t graph)
1930 : : {
1931 : 7785451 : unsigned int i;
1932 : 7785451 : unsigned int size = graph->size;
1933 : :
1934 : 7785451 : auto_sbitmap visited (size);
1935 : 7785451 : 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 : 7785451 : auto_vec<unsigned> tail (size);
1943 : 7785451 : topo_visit (graph, tail, visited, find (escaped_id));
1944 : :
1945 : 7785451 : auto_vec<unsigned> topo_order (size);
1946 : :
1947 : 583874084 : for (i = 0; i != size; ++i)
1948 : 568303182 : if (!bitmap_bit_p (visited, i) && find (i) == i)
1949 : 58762638 : topo_visit (graph, topo_order, visited, i);
1950 : :
1951 : 7785451 : topo_order.splice (tail);
1952 : 7785451 : return topo_order;
1953 : 7785451 : }
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 : 183744779 : equiv_class_hasher::hash (const equiv_class_label *ecl)
1979 : : {
1980 : 183744779 : return ecl->hashcode;
1981 : : }
1982 : :
1983 : : /* Equality function for two equiv_class_label_t's. */
1984 : :
1985 : : inline bool
1986 : 237984692 : equiv_class_hasher::equal (const equiv_class_label *eql1,
1987 : : const equiv_class_label *eql2)
1988 : : {
1989 : 237984692 : return (eql1->hashcode == eql2->hashcode
1990 : 237984692 : && 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 : 191606034 : equiv_class_lookup_or_add (hash_table<equiv_class_hasher> *table,
2009 : : bitmap labels)
2010 : : {
2011 : 191606034 : equiv_class_label **slot;
2012 : 191606034 : equiv_class_label ecl;
2013 : :
2014 : 191606034 : ecl.labels = labels;
2015 : 191606034 : ecl.hashcode = bitmap_hash (labels);
2016 : 191606034 : slot = table->find_slot (&ecl, INSERT);
2017 : 191606034 : if (!*slot)
2018 : : {
2019 : 161048238 : *slot = XOBNEW (&equiv_class_obstack, struct equiv_class_label);
2020 : 161048238 : (*slot)->labels = labels;
2021 : 161048238 : (*slot)->hashcode = ecl.hashcode;
2022 : 161048238 : (*slot)->equivalence_class = 0;
2023 : : }
2024 : :
2025 : 191606034 : 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 : 264648420 : condense_visit (constraint_graph_t graph, class scc_info *si, unsigned int n)
2082 : : {
2083 : 264648420 : unsigned int i;
2084 : 264648420 : bitmap_iterator bi;
2085 : 264648420 : unsigned int my_dfs;
2086 : :
2087 : 264648420 : gcc_checking_assert (si->node_mapping[n] == n);
2088 : 264648420 : bitmap_set_bit (si->visited, n);
2089 : 264648420 : si->dfs[n] = si->current_index ++;
2090 : 264648420 : my_dfs = si->dfs[n];
2091 : :
2092 : : /* Visit all the successors. */
2093 : 485265279 : EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[n], 0, i, bi)
2094 : : {
2095 : 220616859 : unsigned int w = si->node_mapping[i];
2096 : :
2097 : 220616859 : if (bitmap_bit_p (si->deleted, w))
2098 : 139695478 : continue;
2099 : :
2100 : 80921381 : if (!bitmap_bit_p (si->visited, w))
2101 : 79525363 : condense_visit (graph, si, w);
2102 : :
2103 : 80921381 : unsigned int t = si->node_mapping[w];
2104 : 80921381 : gcc_checking_assert (si->node_mapping[n] == n);
2105 : 80921381 : if (si->dfs[t] < si->dfs[n])
2106 : 2659088 : si->dfs[n] = si->dfs[t];
2107 : : }
2108 : :
2109 : : /* Visit all the implicit predecessors. */
2110 : 322449699 : EXECUTE_IF_IN_NONNULL_BITMAP (graph->implicit_preds[n], 0, i, bi)
2111 : : {
2112 : 57801279 : unsigned int w = si->node_mapping[i];
2113 : :
2114 : 57801279 : if (bitmap_bit_p (si->deleted, w))
2115 : 18781736 : continue;
2116 : :
2117 : 39019543 : if (!bitmap_bit_p (si->visited, w))
2118 : 34413800 : condense_visit (graph, si, w);
2119 : :
2120 : 39019543 : unsigned int t = si->node_mapping[w];
2121 : 39019543 : gcc_assert (si->node_mapping[n] == n);
2122 : 39019543 : if (si->dfs[t] < si->dfs[n])
2123 : 8200332 : si->dfs[n] = si->dfs[t];
2124 : : }
2125 : :
2126 : : /* See if any components have been identified. */
2127 : 264648420 : if (si->dfs[n] == my_dfs)
2128 : : {
2129 : 253915499 : if (si->scc_stack.length () != 0
2130 : 253915499 : && 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 : 10732921 : do
2136 : : {
2137 : 10732921 : --first;
2138 : 10732921 : unsigned int w = si->scc_stack[first];
2139 : 10732921 : si->node_mapping[w] = n;
2140 : 10732921 : if (!bitmap_bit_p (graph->direct_nodes, w))
2141 : 8616319 : direct_p = false;
2142 : : }
2143 : : while (first > 0
2144 : 12098352 : && si->dfs[si->scc_stack[first - 1]] >= my_dfs);
2145 : 1365431 : if (!direct_p)
2146 : 875531 : bitmap_clear_bit (graph->direct_nodes, n);
2147 : :
2148 : : /* Want to reduce to node n, push that first. */
2149 : 1365431 : si->scc_stack.reserve (1);
2150 : 1365431 : si->scc_stack.quick_push (si->scc_stack[first]);
2151 : 1365431 : si->scc_stack[first] = n;
2152 : :
2153 : 1365431 : unsigned scc_size = si->scc_stack.length () - first;
2154 : 1365431 : unsigned split = scc_size / 2;
2155 : 1365431 : unsigned carry = scc_size - split * 2;
2156 : 4806980 : while (split > 0)
2157 : : {
2158 : 14174470 : for (unsigned i = 0; i < split; ++i)
2159 : : {
2160 : 10732921 : unsigned a = si->scc_stack[first + i];
2161 : 10732921 : unsigned b = si->scc_stack[first + split + carry + i];
2162 : :
2163 : : /* Unify our nodes. */
2164 : 10732921 : if (graph->preds[b])
2165 : : {
2166 : 4769175 : if (!graph->preds[a])
2167 : 948752 : std::swap (graph->preds[a], graph->preds[b]);
2168 : : else
2169 : 3820423 : bitmap_ior_into_and_free (graph->preds[a],
2170 : : &graph->preds[b]);
2171 : : }
2172 : 10732921 : if (graph->implicit_preds[b])
2173 : : {
2174 : 8483657 : if (!graph->implicit_preds[a])
2175 : 887034 : std::swap (graph->implicit_preds[a],
2176 : : graph->implicit_preds[b]);
2177 : : else
2178 : 7596623 : bitmap_ior_into_and_free (graph->implicit_preds[a],
2179 : : &graph->implicit_preds[b]);
2180 : : }
2181 : 10732921 : if (graph->points_to[b])
2182 : : {
2183 : 495060 : if (!graph->points_to[a])
2184 : 216235 : std::swap (graph->points_to[a], graph->points_to[b]);
2185 : : else
2186 : 278825 : bitmap_ior_into_and_free (graph->points_to[a],
2187 : : &graph->points_to[b]);
2188 : : }
2189 : : }
2190 : 3441549 : unsigned remain = split + carry;
2191 : 3441549 : split = remain / 2;
2192 : 3441549 : carry = remain - split * 2;
2193 : : }
2194 : : /* Actually pop the SCC. */
2195 : 1365431 : si->scc_stack.truncate (first);
2196 : : }
2197 : 253915499 : bitmap_set_bit (si->deleted, n);
2198 : : }
2199 : : else
2200 : 10732921 : si->scc_stack.safe_push (n);
2201 : 264648420 : }
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 : 230523584 : label_visit (constraint_graph_t graph, class scc_info *si, unsigned int n)
2224 : : {
2225 : 230523584 : unsigned int i, first_pred;
2226 : 230523584 : bitmap_iterator bi;
2227 : :
2228 : 230523584 : bitmap_set_bit (si->visited, n);
2229 : :
2230 : : /* Label and union our incoming edges's points to sets. */
2231 : 230523584 : first_pred = -1U;
2232 : 445863715 : EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[n], 0, i, bi)
2233 : : {
2234 : 215340131 : unsigned int w = si->node_mapping[i];
2235 : 215340131 : if (!bitmap_bit_p (si->visited, w))
2236 : 74806311 : label_visit (graph, si, w);
2237 : :
2238 : : /* Skip unused edges */
2239 : 215340131 : if (w == n || graph->pointer_label[w] == 0)
2240 : 5303532 : continue;
2241 : :
2242 : 210036599 : if (graph->points_to[w])
2243 : : {
2244 : 210036599 : if (!graph->points_to[n])
2245 : : {
2246 : 145701197 : if (first_pred == -1U)
2247 : : first_pred = w;
2248 : : else
2249 : : {
2250 : 39467169 : graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack);
2251 : 39467169 : bitmap_ior (graph->points_to[n],
2252 : 39467169 : graph->points_to[first_pred],
2253 : 39467169 : graph->points_to[w]);
2254 : : }
2255 : : }
2256 : : else
2257 : 64335402 : 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 : 230523584 : if (!bitmap_bit_p (graph->direct_nodes, n))
2263 : : {
2264 : 111846776 : if (!graph->points_to[n])
2265 : : {
2266 : 64704881 : graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack);
2267 : 64704881 : if (first_pred != -1U)
2268 : 26095149 : bitmap_copy (graph->points_to[n], graph->points_to[first_pred]);
2269 : : }
2270 : 223693552 : bitmap_set_bit (graph->points_to[n], FIRST_REF_NODE + n);
2271 : 111846776 : graph->pointer_label[n] = pointer_equiv_class++;
2272 : 111846776 : equiv_class_label_t ecl;
2273 : 223693552 : ecl = equiv_class_lookup_or_add (pointer_equiv_class_table,
2274 : 111846776 : graph->points_to[n]);
2275 : 111846776 : ecl->equivalence_class = graph->pointer_label[n];
2276 : 172167346 : return;
2277 : : }
2278 : :
2279 : : /* If there was only a single non-empty predecessor the pointer equiv
2280 : : class is the same. */
2281 : 118676808 : if (!graph->points_to[n])
2282 : : {
2283 : 60320570 : if (first_pred != -1U)
2284 : : {
2285 : 40671710 : graph->pointer_label[n] = graph->pointer_label[first_pred];
2286 : 40671710 : graph->points_to[n] = graph->points_to[first_pred];
2287 : : }
2288 : 60320570 : return;
2289 : : }
2290 : :
2291 : 58356238 : if (!bitmap_empty_p (graph->points_to[n]))
2292 : : {
2293 : 58356238 : equiv_class_label_t ecl;
2294 : 58356238 : ecl = equiv_class_lookup_or_add (pointer_equiv_class_table,
2295 : : graph->points_to[n]);
2296 : 58356238 : if (ecl->equivalence_class == 0)
2297 : 28237610 : ecl->equivalence_class = pointer_equiv_class++;
2298 : : else
2299 : : {
2300 : 30118628 : BITMAP_FREE (graph->points_to[n]);
2301 : 30118628 : graph->points_to[n] = ecl->labels;
2302 : : }
2303 : 58356238 : 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 : 4408981 : perform_var_substitution (constraint_graph_t graph)
2387 : : {
2388 : 4408981 : unsigned int i;
2389 : 4408981 : unsigned int size = graph->size;
2390 : 4408981 : scc_info *si = new scc_info (size);
2391 : :
2392 : 4408981 : bitmap_obstack_initialize (&iteration_obstack);
2393 : 4408981 : gcc_obstack_init (&equiv_class_obstack);
2394 : 4408981 : pointer_equiv_class_table = new hash_table<equiv_class_hasher> (511);
2395 : 4408981 : location_equiv_class_table
2396 : 4408981 : = new hash_table<equiv_class_hasher> (511);
2397 : 4408981 : pointer_equiv_class = 1;
2398 : 4408981 : 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 : 225962770 : for (i = 1; i < FIRST_REF_NODE; i++)
2403 : 221553789 : if (!bitmap_bit_p (si->visited, si->node_mapping[i]))
2404 : 150709257 : condense_visit (graph, si, si->node_mapping[i]);
2405 : :
2406 : 4408981 : 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 : 4408981 : bitmap_clear (si->visited);
2415 : : /* Actually the label the nodes for pointer equivalences */
2416 : 456334521 : for (i = 1; i < FIRST_REF_NODE; i++)
2417 : 221553789 : if (!bitmap_bit_p (si->visited, si->node_mapping[i]))
2418 : 155717273 : label_visit (graph, si, si->node_mapping[i]);
2419 : :
2420 : : /* Calculate location equivalence labels. */
2421 : 225962770 : for (i = 1; i < FIRST_REF_NODE; i++)
2422 : : {
2423 : 221553789 : bitmap pointed_by;
2424 : 221553789 : bitmap_iterator bi;
2425 : 221553789 : unsigned int j;
2426 : :
2427 : 221553789 : if (!graph->pointed_by[i])
2428 : 200150769 : continue;
2429 : 21403020 : pointed_by = BITMAP_ALLOC (&iteration_obstack);
2430 : :
2431 : : /* Translate the pointed-by mapping for pointer equivalence
2432 : : labels. */
2433 : 96504515 : EXECUTE_IF_SET_IN_BITMAP (graph->pointed_by[i], 0, j, bi)
2434 : : {
2435 : 75101495 : bitmap_set_bit (pointed_by,
2436 : 75101495 : graph->pointer_label[si->node_mapping[j]]);
2437 : : }
2438 : : /* The original pointed_by is now dead. */
2439 : 21403020 : BITMAP_FREE (graph->pointed_by[i]);
2440 : :
2441 : : /* Look up the location equivalence label if one exists, or make
2442 : : one otherwise. */
2443 : 21403020 : equiv_class_label_t ecl;
2444 : 21403020 : ecl = equiv_class_lookup_or_add (location_equiv_class_table, pointed_by);
2445 : 21403020 : if (ecl->equivalence_class == 0)
2446 : 20963852 : ecl->equivalence_class = location_equiv_class++;
2447 : : else
2448 : : {
2449 : 439168 : if (dump_file && (dump_flags & TDF_DETAILS))
2450 : 53 : fprintf (dump_file, "Found location equivalence for node %s\n",
2451 : 53 : get_varinfo (i)->name);
2452 : 439168 : BITMAP_FREE (pointed_by);
2453 : : }
2454 : 21403020 : graph->loc_label[i] = ecl->equivalence_class;
2455 : :
2456 : : }
2457 : :
2458 : 4408981 : if (dump_file && (dump_flags & TDF_DETAILS))
2459 : 6763 : for (i = 1; i < FIRST_REF_NODE; i++)
2460 : : {
2461 : 6464 : unsigned j = si->node_mapping[i];
2462 : 6464 : 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 : 9933 : fprintf (dump_file,
2482 : : "Equivalence classes for %s node id %d ",
2483 : 6443 : bitmap_bit_p (graph->direct_nodes, i)
2484 : : ? "direct" : "indirect", i);
2485 : 6443 : if (i < FIRST_REF_NODE)
2486 : 6443 : 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 : 6443 : fprintf (dump_file,
2491 : : ": pointer %d, location %d\n",
2492 : 6443 : graph->pointer_label[i], graph->loc_label[i]);
2493 : : }
2494 : : }
2495 : :
2496 : : /* Quickly eliminate our non-pointer variables. */
2497 : :
2498 : 225962770 : for (i = 1; i < FIRST_REF_NODE; i++)
2499 : : {
2500 : 221553789 : unsigned int node = si->node_mapping[i];
2501 : :
2502 : 221553789 : if (graph->pointer_label[node] == 0)
2503 : : {
2504 : 19650318 : if (dump_file && (dump_flags & TDF_DETAILS))
2505 : 913 : fprintf (dump_file,
2506 : : "%s is a non-pointer variable, eliminating edges.\n",
2507 : 913 : get_varinfo (node)->name);
2508 : 19650318 : stats.nonpointer_vars++;
2509 : 19650318 : clear_edges_for_node (graph, node);
2510 : : }
2511 : : }
2512 : :
2513 : 4408981 : return si;
2514 : : }
2515 : :
2516 : : /* Free information that was only necessary for variable
2517 : : substitution. */
2518 : :
2519 : : static void
2520 : 4408981 : free_var_substitution_info (class scc_info *si)
2521 : : {
2522 : 4408981 : delete si;
2523 : 4408981 : free (graph->pointer_label);
2524 : 4408981 : free (graph->loc_label);
2525 : 4408981 : free (graph->pointed_by);
2526 : 4408981 : free (graph->points_to);
2527 : 4408981 : free (graph->eq_rep);
2528 : 4408981 : sbitmap_free (graph->direct_nodes);
2529 : 4408981 : delete pointer_equiv_class_table;
2530 : 4408981 : pointer_equiv_class_table = NULL;
2531 : 4408981 : delete location_equiv_class_table;
2532 : 4408981 : location_equiv_class_table = NULL;
2533 : 4408981 : obstack_free (&equiv_class_obstack, NULL);
2534 : 4408981 : bitmap_obstack_release (&iteration_obstack);
2535 : 4408981 : }
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 : 867065640 : 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 : 867065640 : if (!bitmap_bit_p (graph->address_taken, node))
2550 : : {
2551 : 674164535 : gcc_checking_assert (label < graph->size);
2552 : :
2553 : 674164535 : if (graph->eq_rep[label] != -1)
2554 : : {
2555 : : /* Unify the two variables since we know they are equivalent. */
2556 : 570393018 : if (unite (graph->eq_rep[label], node))
2557 : 67728791 : unify_nodes (graph, graph->eq_rep[label], node, false);
2558 : 570393018 : return graph->eq_rep[label];
2559 : : }
2560 : : else
2561 : : {
2562 : 103771517 : graph->eq_rep[label] = node;
2563 : 103771517 : graph->pe_rep[label] = node;
2564 : : }
2565 : : }
2566 : : else
2567 : : {
2568 : 192901105 : gcc_checking_assert (label < graph->size);
2569 : 192901105 : graph->pe[node] = label;
2570 : 192901105 : if (graph->pe_rep[label] == -1)
2571 : 21308570 : 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 : 4408981 : unite_pointer_equivalences (constraint_graph_t graph)
2583 : : {
2584 : 4408981 : unsigned int i;
2585 : :
2586 : : /* Go through the pointer equivalences and unite them to their
2587 : : representative, if they aren't already. */
2588 : 225962770 : for (i = 1; i < FIRST_REF_NODE; i++)
2589 : : {
2590 : 221553789 : unsigned int label = graph->pe[i];
2591 : 221553789 : if (label)
2592 : : {
2593 : 21403020 : int label_rep = graph->pe_rep[label];
2594 : :
2595 : 21403020 : if (label_rep == -1)
2596 : 0 : continue;
2597 : :
2598 : 21403020 : label_rep = find (label_rep);
2599 : 21403020 : if (label_rep >= 0 && unite (label_rep, find (i)))
2600 : 2319144 : unify_nodes (graph, label_rep, i, false);
2601 : : }
2602 : : }
2603 : 4408981 : }
2604 : :
2605 : : /* Move complex constraints to the GRAPH nodes they belong to. */
2606 : :
2607 : : static void
2608 : 4408981 : move_complex_constraints (constraint_graph_t graph)
2609 : : {
2610 : 4408981 : int i;
2611 : 4408981 : constraint_t c;
2612 : :
2613 : 440477990 : FOR_EACH_VEC_ELT (constraints, i, c)
2614 : : {
2615 : 436069009 : if (c)
2616 : : {
2617 : 433532820 : struct constraint_expr lhs = c->lhs;
2618 : 433532820 : struct constraint_expr rhs = c->rhs;
2619 : :
2620 : 433532820 : if (lhs.type == DEREF)
2621 : : {
2622 : 35867393 : insert_into_complex (graph, lhs.var, c);
2623 : : }
2624 : 397665427 : else if (rhs.type == DEREF)
2625 : : {
2626 : 48860329 : if (!(get_varinfo (lhs.var)->is_special_var))
2627 : 48860326 : insert_into_complex (graph, rhs.var, c);
2628 : : }
2629 : 348805098 : else if (rhs.type != ADDRESSOF && lhs.var > anything_id
2630 : 259558729 : && (lhs.offset != 0 || rhs.offset != 0))
2631 : : {
2632 : 60049243 : insert_into_complex (graph, rhs.var, c);
2633 : : }
2634 : : }
2635 : : }
2636 : 4408981 : }
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 : 4408981 : rewrite_constraints (constraint_graph_t graph,
2645 : : class scc_info *si)
2646 : : {
2647 : 4408981 : int i;
2648 : 4408981 : constraint_t c;
2649 : :
2650 : 4408981 : if (flag_checking)
2651 : : {
2652 : 456331379 : for (unsigned int j = 0; j < graph->size; j++)
2653 : 451922458 : gcc_assert (find (j) == j);
2654 : : }
2655 : :
2656 : 440477990 : FOR_EACH_VEC_ELT (constraints, i, c)
2657 : : {
2658 : 436069009 : struct constraint_expr lhs = c->lhs;
2659 : 436069009 : struct constraint_expr rhs = c->rhs;
2660 : 436069009 : unsigned int lhsvar = find (lhs.var);
2661 : 436069009 : unsigned int rhsvar = find (rhs.var);
2662 : 436069009 : unsigned int lhsnode, rhsnode;
2663 : 436069009 : unsigned int lhslabel, rhslabel;
2664 : :
2665 : 436069009 : lhsnode = si->node_mapping[lhsvar];
2666 : 436069009 : rhsnode = si->node_mapping[rhsvar];
2667 : 436069009 : lhslabel = graph->pointer_label[lhsnode];
2668 : 436069009 : rhslabel = graph->pointer_label[rhsnode];
2669 : :
2670 : : /* See if it is really a non-pointer variable, and if so, ignore
2671 : : the constraint. */
2672 : 436069009 : if (lhslabel == 0)
2673 : : {
2674 : 789168 : 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 : 789168 : constraints[i] = NULL;
2684 : 2536189 : continue;
2685 : : }
2686 : :
2687 : 435279841 : if (rhslabel == 0)
2688 : : {
2689 : 1747021 : 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 : 1747021 : constraints[i] = NULL;
2699 : 1747021 : continue;
2700 : : }
2701 : :
2702 : 433532820 : lhsvar = find_equivalent_node (graph, lhsvar, lhslabel);
2703 : 433532820 : rhsvar = find_equivalent_node (graph, rhsvar, rhslabel);
2704 : 433532820 : c->lhs.var = lhsvar;
2705 : 433532820 : c->rhs.var = rhsvar;
2706 : : }
2707 : 4408981 : }
2708 : :
2709 : : /* Eliminate indirect cycles involving NODE. Return true if NODE was
2710 : : part of an SCC, false otherwise. */
2711 : :
2712 : : static bool
2713 : 382865322 : eliminate_indirect_cycles (unsigned int node)
2714 : : {
2715 : 382865322 : if (graph->indirect_cycles[node] != -1
2716 : 383188124 : && !bitmap_empty_p (get_varinfo (node)->solution))
2717 : : {
2718 : 290586 : unsigned int i;
2719 : 290586 : auto_vec<unsigned> queue;
2720 : 290586 : int queuepos;
2721 : 290586 : unsigned int to = find (graph->indirect_cycles[node]);
2722 : 290586 : 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 : 1560597 : EXECUTE_IF_SET_IN_BITMAP (get_varinfo (node)->solution, 0, i, bi)
2729 : : {
2730 : 1270011 : if (find (i) == i && i != to)
2731 : : {
2732 : 337297 : if (unite (to, i))
2733 : 337297 : queue.safe_push (i);
2734 : : }
2735 : : }
2736 : :
2737 : 337297 : for (queuepos = 0;
2738 : 627883 : queue.iterate (queuepos, &i);
2739 : : queuepos++)
2740 : : {
2741 : 337297 : unify_nodes (graph, to, i, true);
2742 : : }
2743 : 290586 : return true;
2744 : 290586 : }
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 : 4408981 : solve_graph (constraint_graph_t graph)
2757 : : {
2758 : 4408981 : unsigned int size = graph->size;
2759 : 4408981 : unsigned int i;
2760 : 4408981 : bitmap pts;
2761 : :
2762 : 4408981 : changed = BITMAP_ALLOC (NULL);
2763 : :
2764 : : /* Mark all initial non-collapsed nodes as changed. */
2765 : 225962770 : for (i = 1; i < size; i++)
2766 : : {
2767 : 221553789 : varinfo_t ivi = get_varinfo (i);
2768 : 373040370 : if (find (i) == i && !bitmap_empty_p (ivi->solution)
2769 : 274049140 : && ((graph->succs[i] && !bitmap_empty_p (graph->succs[i]))
2770 : 229391161 : || graph->complex[i].length () > 0))
2771 : 33434240 : bitmap_set_bit (changed, i);
2772 : : }
2773 : :
2774 : : /* Allocate a bitmap to be used to store the changed bits. */
2775 : 4408981 : pts = BITMAP_ALLOC (&pta_obstack);
2776 : :
2777 : 16603413 : while (!bitmap_empty_p (changed))
2778 : : {
2779 : 7785451 : unsigned int i;
2780 : 7785451 : stats.iterations++;
2781 : :
2782 : 7785451 : bitmap_obstack_initialize (&iteration_obstack);
2783 : :
2784 : 7785451 : auto_vec<unsigned> topo_order = compute_topo_order (graph);
2785 : 398744791 : while (topo_order.length () != 0)
2786 : : {
2787 : 383173889 : i = topo_order.pop ();
2788 : :
2789 : : /* If this variable is not a representative, skip it. */
2790 : 383173889 : if (find (i) != i)
2791 : 308567 : continue;
2792 : :
2793 : : /* In certain indirect cycle cases, we may merge this
2794 : : variable to another. */
2795 : 382865322 : if (eliminate_indirect_cycles (i) && find (i) != i)
2796 : 50 : 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 : 525019984 : while (bitmap_clear_bit (changed, i))
2808 : : {
2809 : 142458334 : bitmap solution;
2810 : 142458334 : vec<constraint_t> &complex = graph->complex[i];
2811 : 142458334 : varinfo_t vi = get_varinfo (i);
2812 : 142458334 : bool solution_empty;
2813 : :
2814 : : /* Compute the changed set of solution bits. If anything
2815 : : is in the solution just propagate that. */
2816 : 142458334 : 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 : 2730538 : if (vi->oldsolution
2822 : 2730538 : && bitmap_bit_p (vi->oldsolution, anything_id))
2823 : : break;
2824 : 2426916 : bitmap_copy (pts, get_varinfo (find (anything_id))->solution);
2825 : : }
2826 : 139727796 : else if (vi->oldsolution)
2827 : 36344015 : bitmap_and_compl (pts, vi->solution, vi->oldsolution);
2828 : : else
2829 : 103383781 : bitmap_copy (pts, vi->solution);
2830 : :
2831 : 142154712 : if (bitmap_empty_p (pts))
2832 : : break;
2833 : :
2834 : 142154712 : if (vi->oldsolution)
2835 : 37581240 : bitmap_ior_into (vi->oldsolution, pts);
2836 : : else
2837 : : {
2838 : 104573472 : vi->oldsolution = BITMAP_ALLOC (&oldpta_obstack);
2839 : 104573472 : bitmap_copy (vi->oldsolution, pts);
2840 : : }
2841 : :
2842 : 142154712 : solution = vi->solution;
2843 : 142154712 : solution_empty = bitmap_empty_p (solution);
2844 : :
2845 : : /* Process the complex constraints */
2846 : 142154712 : hash_set<constraint_t> *cvisited = nullptr;
2847 : 142154712 : if (flag_checking)
2848 : 142154027 : cvisited = new hash_set<constraint_t>;
2849 : 142154712 : bitmap expanded_pts = NULL;
2850 : 352287641 : for (unsigned j = 0; j < complex.length (); ++j)
2851 : : {
2852 : 210132929 : 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 : 210132929 : unsigned int new_lhs = find (c->lhs.var);
2859 : 210132929 : unsigned int new_rhs = find (c->rhs.var);
2860 : 210132929 : if (c->lhs.var != new_lhs || c->rhs.var != new_rhs)
2861 : : {
2862 : 1602942 : constraint tem = *c;
2863 : 1602942 : tem.lhs.var = new_lhs;
2864 : 1602942 : tem.rhs.var = new_rhs;
2865 : 1602942 : unsigned int place
2866 : 1602942 : = complex.lower_bound (&tem, constraint_less);
2867 : 1602942 : c->lhs.var = new_lhs;
2868 : 1602942 : c->rhs.var = new_rhs;
2869 : 1602942 : if (place != j)
2870 : : {
2871 : 1590341 : complex.ordered_remove (j);
2872 : 1590341 : if (j < place)
2873 : 1570709 : --place;
2874 : 1590341 : if (place < complex.length ())
2875 : : {
2876 : 387473 : if (constraint_equal (*complex[place], *c))
2877 : : {
2878 : 37976 : j--;
2879 : 305778 : continue;
2880 : : }
2881 : : else
2882 : 349497 : complex.safe_insert (place, c);
2883 : : }
2884 : : else
2885 : 1202868 : complex.quick_push (c);
2886 : 1552365 : if (place > j)
2887 : : {
2888 : 267802 : j--;
2889 : 267802 : 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 : 209827151 : if (cvisited && cvisited->add (c))
2899 : 0 : gcc_unreachable ();
2900 : 209827151 : if (!solution_empty || c->lhs.type != DEREF)
2901 : 209827151 : do_complex_constraint (graph, c, pts, &expanded_pts);
2902 : : }
2903 : 142154712 : if (cvisited)
2904 : : {
2905 : : /* When checking, verify the order of constraints is
2906 : : maintained and each constraint is evaluated exactly
2907 : : once. */
2908 : 270934486 : for (unsigned j = 1; j < complex.length (); ++j)
2909 : 128780459 : gcc_assert (constraint_less (complex[j-1], complex[j]));
2910 : 223199659 : gcc_assert (cvisited->elements () == complex.length ());
2911 : 142154027 : delete cvisited;
2912 : : }
2913 : 142154712 : BITMAP_FREE (expanded_pts);
2914 : :
2915 : 142154712 : solution_empty = bitmap_empty_p (solution);
2916 : :
2917 : 142154712 : if (!solution_empty)
2918 : : {
2919 : 142154712 : bitmap_iterator bi;
2920 : 142154712 : unsigned eff_escaped_id = find (escaped_id);
2921 : 142154712 : unsigned j;
2922 : :
2923 : : /* Propagate solution to all successors. */
2924 : 142154712 : unsigned to_remove = ~0U;
2925 : 359032860 : EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i],
2926 : : 0, j, bi)
2927 : : {
2928 : 216878148 : if (to_remove != ~0U)
2929 : : {
2930 : 2278288 : bitmap_clear_bit (graph->succs[i], to_remove);
2931 : 2278288 : to_remove = ~0U;
2932 : : }
2933 : 216878148 : unsigned int to = find (j);
2934 : 216878148 : if (to != j)
2935 : : {
2936 : : /* Update the succ graph, avoiding duplicate
2937 : : work. */
2938 : 2251126 : to_remove = j;
2939 : 2251126 : if (! bitmap_set_bit (graph->succs[i], to))
2940 : 910184 : 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 : 215967964 : if (to == i)
2948 : : {
2949 : 173094 : to_remove = j;
2950 : 173094 : continue;
2951 : : }
2952 : : /* Early node unification can lead to edges from
2953 : : escaped - remove them. */
2954 : 215794870 : if (i == eff_escaped_id)
2955 : : {
2956 : 169896 : to_remove = j;
2957 : 169896 : if (bitmap_set_bit (get_varinfo (to)->solution,
2958 : : escaped_id))
2959 : 93067 : bitmap_set_bit (changed, to);
2960 : 169896 : continue;
2961 : : }
2962 : :
2963 : 215624974 : if (bitmap_ior_into (get_varinfo (to)->solution, pts))
2964 : 95693865 : bitmap_set_bit (changed, to);
2965 : : }
2966 : 99444374 : if (to_remove != ~0U)
2967 : 216330 : bitmap_clear_bit (graph->succs[i], to_remove);
2968 : : }
2969 : : }
2970 : : }
2971 : 7785451 : bitmap_obstack_release (&iteration_obstack);
2972 : 7785451 : }
2973 : :
2974 : 4408981 : BITMAP_FREE (pts);
2975 : 4408981 : BITMAP_FREE (changed);
2976 : 4408981 : bitmap_obstack_release (&oldpta_obstack);
2977 : 4408981 : }
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 : 91680791 : insert_vi_for_tree (tree t, varinfo_t vi)
2987 : : {
2988 : 91680791 : gcc_assert (vi);
2989 : 91680791 : bool existed = vi_for_tree->put (t, vi);
2990 : 91680791 : gcc_assert (!existed);
2991 : 91680791 : }
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 : 52024508 : lookup_vi_for_tree (tree t)
2998 : : {
2999 : 52024508 : varinfo_t *slot = vi_for_tree->get (t);
3000 : 52024508 : if (slot == NULL)
3001 : : return NULL;
3002 : :
3003 : 50073080 : return *slot;
3004 : : }
3005 : :
3006 : : /* Return a printable name for DECL */
3007 : :
3008 : : static const char *
3009 : 90710788 : alias_get_name (tree decl)
3010 : : {
3011 : 90710788 : const char *res = "NULL";
3012 : 90710788 : if (dump_file)
3013 : : {
3014 : 3960 : char *temp = NULL;
3015 : 3960 : if (TREE_CODE (decl) == SSA_NAME)
3016 : : {
3017 : 2238 : res = get_name (decl);
3018 : 3669 : temp = xasprintf ("%s_%u", res ? res : "", SSA_NAME_VERSION (decl));
3019 : : }
3020 : 1722 : else if (HAS_DECL_ASSEMBLER_NAME_P (decl)
3021 : 1722 : && DECL_ASSEMBLER_NAME_SET_P (decl))
3022 : 756 : res = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME_RAW (decl));
3023 : 966 : else if (DECL_P (decl))
3024 : : {
3025 : 966 : res = get_name (decl);
3026 : 966 : if (!res)
3027 : 4 : temp = xasprintf ("D.%u", DECL_UID (decl));
3028 : : }
3029 : :
3030 : 2998 : if (temp)
3031 : : {
3032 : 2242 : res = ggc_strdup (temp);
3033 : 2242 : free (temp);
3034 : : }
3035 : : }
3036 : :
3037 : 90710788 : 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 : 241937475 : get_vi_for_tree (tree t)
3045 : : {
3046 : 241937475 : varinfo_t *slot = vi_for_tree->get (t);
3047 : 241937475 : if (slot == NULL)
3048 : : {
3049 : 81367809 : unsigned int id = create_variable_info_for (t, alias_get_name (t), false);
3050 : 81367809 : return get_varinfo (id);
3051 : : }
3052 : :
3053 : 160569666 : return *slot;
3054 : : }
3055 : :
3056 : : /* Get a scalar constraint expression for a new temporary variable. */
3057 : :
3058 : : static struct constraint_expr
3059 : 3048018 : new_scalar_tmp_constraint_exp (const char *name, bool add_id)
3060 : : {
3061 : 3048018 : struct constraint_expr tmp;
3062 : 3048018 : varinfo_t vi;
3063 : :
3064 : 3048018 : vi = new_var_info (NULL_TREE, name, add_id);
3065 : 3048018 : vi->offset = 0;
3066 : 3048018 : vi->size = -1;
3067 : 3048018 : vi->fullsize = -1;
3068 : 3048018 : vi->is_full_var = 1;
3069 : 3048018 : vi->is_reg_var = 1;
3070 : :
3071 : 3048018 : tmp.var = vi->id;
3072 : 3048018 : tmp.type = SCALAR;
3073 : 3048018 : tmp.offset = 0;
3074 : :
3075 : 3048018 : 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 : 221267839 : get_constraint_for_ssa_var (tree t, vec<ce_s> *results, bool address_p)
3083 : : {
3084 : 221267839 : struct constraint_expr cexpr;
3085 : 221267839 : varinfo_t vi;
3086 : :
3087 : : /* We allow FUNCTION_DECLs here even though it doesn't make much sense. */
3088 : 221267839 : gcc_assert (TREE_CODE (t) == SSA_NAME || DECL_P (t));
3089 : :
3090 : 221267839 : if (TREE_CODE (t) == SSA_NAME
3091 : 221267839 : && SSA_NAME_IS_DEFAULT_DEF (t))
3092 : : {
3093 : : /* For parameters, get at the points-to set for the actual parm
3094 : : decl. */
3095 : 18111967 : if (TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL
3096 : 18111967 : || TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL)
3097 : : {
3098 : 17856197 : get_constraint_for_ssa_var (SSA_NAME_VAR (t), results, address_p);
3099 : 42234173 : return;
3100 : : }
3101 : : /* For undefined SSA names return nothing. */
3102 : 255770 : else if (!ssa_defined_default_def_p (t))
3103 : : {
3104 : 255770 : cexpr.var = nothing_id;
3105 : 255770 : cexpr.type = SCALAR;
3106 : 255770 : cexpr.offset = 0;
3107 : 255770 : results->safe_push (cexpr);
3108 : 255770 : return;
3109 : : }
3110 : : }
3111 : :
3112 : : /* For global variables resort to the alias target. */
3113 : 203155872 : if (VAR_P (t) && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
3114 : : {
3115 : 11125567 : varpool_node *node = varpool_node::get (t);
3116 : 11125567 : if (node && node->alias && node->analyzed)
3117 : : {
3118 : 16959 : 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 : 16959 : 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 : 16959 : DECL_PT_UID (t) = DECL_UID (node->decl);
3127 : 16959 : t = node->decl;
3128 : : }
3129 : :
3130 : : /* If this is decl may bind to NULL note that. */
3131 : 11125567 : if (address_p
3132 : 11125567 : && (! node || ! node->nonzero_address ()))
3133 : : {
3134 : 8721 : cexpr.var = nothing_id;
3135 : 8721 : cexpr.type = SCALAR;
3136 : 8721 : cexpr.offset = 0;
3137 : 8721 : results->safe_push (cexpr);
3138 : : }
3139 : : }
3140 : :
3141 : 203155872 : vi = get_vi_for_tree (t);
3142 : 203155872 : cexpr.var = vi->id;
3143 : 203155872 : cexpr.type = SCALAR;
3144 : 203155872 : 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 : 203155872 : if (!address_p
3149 : 166050267 : && !vi->is_full_var)
3150 : : {
3151 : 21118669 : for (; vi; vi = vi_next (vi))
3152 : : {
3153 : 14852660 : cexpr.var = vi->id;
3154 : 14852660 : results->safe_push (cexpr);
3155 : : }
3156 : : return;
3157 : : }
3158 : :
3159 : 196889863 : 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 : 434264356 : process_constraint (constraint_t t)
3167 : : {
3168 : 434264356 : struct constraint_expr rhs = t->rhs;
3169 : 434264356 : struct constraint_expr lhs = t->lhs;
3170 : :
3171 : 434264356 : gcc_assert (rhs.var < varmap.length ());
3172 : 434264356 : 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 : 434264356 : if (lhs.type == ADDRESSOF
3178 : 0 : && lhs.var == anything_id)
3179 : 0 : t->lhs.type = lhs.type = DEREF;
3180 : :
3181 : : /* ADDRESSOF on the lhs is invalid. */
3182 : 434264356 : 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 : 434264356 : if (rhs.type != ADDRESSOF
3187 : 434264356 : && !get_varinfo (rhs.var)->may_have_pointers)
3188 : 434264356 : return;
3189 : :
3190 : : /* Likewise adding to the solution of a non-pointer var isn't useful. */
3191 : 433894537 : 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 : 433892779 : if (rhs.type == DEREF && lhs.type == DEREF && rhs.var != anything_id)
3196 : : {
3197 : : /* Split into tmp = *rhs, *lhs = tmp */
3198 : 279737 : struct constraint_expr tmplhs;
3199 : 279737 : tmplhs = new_scalar_tmp_constraint_exp ("doubledereftmp", true);
3200 : 279737 : process_constraint (new_constraint (tmplhs, rhs));
3201 : 279737 : process_constraint (new_constraint (lhs, tmplhs));
3202 : 279737 : }
3203 : 433613042 : else if ((rhs.type != SCALAR || rhs.offset != 0) && lhs.type == DEREF)
3204 : : {
3205 : : /* Split into tmp = &rhs, *lhs = tmp */
3206 : 1953014 : struct constraint_expr tmplhs;
3207 : 1953014 : tmplhs = new_scalar_tmp_constraint_exp ("derefaddrtmp", true);
3208 : 1953014 : process_constraint (new_constraint (tmplhs, rhs));
3209 : 1953014 : process_constraint (new_constraint (lhs, tmplhs));
3210 : 1953014 : }
3211 : : else
3212 : : {
3213 : 431660028 : gcc_assert (rhs.type != ADDRESSOF || rhs.offset == 0);
3214 : 431660028 : if (rhs.type == ADDRESSOF)
3215 : 84681991 : get_varinfo (get_varinfo (rhs.var)->head)->address_taken = true;
3216 : 431660028 : 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 : 40299653 : bitpos_of_field (const tree fdecl)
3226 : : {
3227 : 40299653 : if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fdecl))
3228 : 40299653 : || !tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (fdecl)))
3229 : : return -1;
3230 : :
3231 : 40299653 : return (tree_to_uhwi (DECL_FIELD_OFFSET (fdecl)) * BITS_PER_UNIT
3232 : 40299653 : + 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 : 40350702 : get_constraint_for_ptr_offset (tree ptr, tree offset,
3241 : : vec<ce_s> *results)
3242 : : {
3243 : 40350702 : struct constraint_expr c;
3244 : 40350702 : unsigned int j, n;
3245 : 40350702 : 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 : 40350702 : if (!use_field_sensitive)
3250 : : {
3251 : 1921352 : get_constraint_for_rhs (ptr, results);
3252 : 1921352 : 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 : 38429350 : if (offset == NULL_TREE
3260 : 13679152 : || TREE_CODE (offset) != INTEGER_CST)
3261 : : rhsoffset = UNKNOWN_OFFSET;
3262 : : else
3263 : : {
3264 : : /* Sign-extend the offset. */
3265 : 11748105 : offset_int soffset = offset_int::from (wi::to_wide (offset), SIGNED);
3266 : 11748105 : if (!wi::fits_shwi_p (soffset))
3267 : : rhsoffset = UNKNOWN_OFFSET;
3268 : : else
3269 : : {
3270 : : /* Make sure the bit-offset also fits. */
3271 : 11748105 : HOST_WIDE_INT rhsunitoffset = soffset.to_shwi ();
3272 : 11748105 : rhsoffset = rhsunitoffset * (unsigned HOST_WIDE_INT) BITS_PER_UNIT;
3273 : 11748105 : if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
3274 : 358 : rhsoffset = UNKNOWN_OFFSET;
3275 : : }
3276 : : }
3277 : :
3278 : 38429350 : get_constraint_for_rhs (ptr, results);
3279 : 38429350 : if (rhsoffset == 0)
3280 : : return;
3281 : :
3282 : : /* As we are eventually appending to the solution do not use
3283 : : vec::iterate here. */
3284 : 32237138 : n = results->length ();
3285 : 64474462 : for (j = 0; j < n; j++)
3286 : : {
3287 : 32237324 : varinfo_t curr;
3288 : 32237324 : c = (*results)[j];
3289 : 32237324 : curr = get_varinfo (c.var);
3290 : :
3291 : 32237324 : if (c.type == ADDRESSOF
3292 : : /* If this varinfo represents a full variable just use it. */
3293 : 10621492 : && curr->is_full_var)
3294 : : ;
3295 : 23969960 : else if (c.type == ADDRESSOF
3296 : : /* If we do not know the offset add all subfields. */
3297 : 2354128 : && rhsoffset == UNKNOWN_OFFSET)
3298 : : {
3299 : 28115 : varinfo_t temp = get_varinfo (curr->head);
3300 : 152302 : do
3301 : : {
3302 : 152302 : struct constraint_expr c2;
3303 : 152302 : c2.var = temp->id;
3304 : 152302 : c2.type = ADDRESSOF;
3305 : 152302 : c2.offset = 0;
3306 : 152302 : if (c2.var != c.var)
3307 : 124187 : results->safe_push (c2);
3308 : 152302 : temp = vi_next (temp);
3309 : : }
3310 : 152302 : while (temp);
3311 : : }
3312 : 23941845 : else if (c.type == ADDRESSOF)
3313 : : {
3314 : 2326013 : varinfo_t temp;
3315 : 2326013 : unsigned HOST_WIDE_INT offset = curr->offset + rhsoffset;
3316 : :
3317 : : /* If curr->offset + rhsoffset is less than zero adjust it. */
3318 : 2326013 : if (rhsoffset < 0
3319 : 0 : && curr->offset < offset)
3320 : 2326013 : 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 : 2326013 : temp = first_or_preceding_vi_for_offset (curr, offset);
3328 : 2326013 : c.var = temp->id;
3329 : 2326013 : c.offset = 0;
3330 : 2326013 : temp = vi_next (temp);
3331 : 2326013 : while (temp
3332 : 2431211 : && temp->offset < offset + curr->size)
3333 : : {
3334 : 105198 : struct constraint_expr c2;
3335 : 105198 : c2.var = temp->id;
3336 : 105198 : c2.type = ADDRESSOF;
3337 : 105198 : c2.offset = 0;
3338 : 105198 : results->safe_push (c2);
3339 : 105198 : temp = vi_next (temp);
3340 : : }
3341 : : }
3342 : 21615832 : else if (c.type == SCALAR)
3343 : : {
3344 : 21615832 : 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 : 32237324 : (*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 : 31920886 : get_constraint_for_component_ref (tree t, vec<ce_s> *results,
3363 : : bool address_p, bool lhs_p)
3364 : : {
3365 : 31920886 : tree orig_t = t;
3366 : 31920886 : poly_int64 bitsize = -1;
3367 : 31920886 : poly_int64 bitmaxsize = -1;
3368 : 31920886 : poly_int64 bitpos;
3369 : 31920886 : bool reverse;
3370 : 31920886 : tree forzero;
3371 : :
3372 : : /* Some people like to do cute things like take the address of
3373 : : &0->a.b */
3374 : 31920886 : forzero = t;
3375 : 31920886 : while (handled_component_p (forzero)
3376 : 47078134 : || INDIRECT_REF_P (forzero)
3377 : 140222331 : || TREE_CODE (forzero) == MEM_REF)
3378 : 61223311 : forzero = TREE_OPERAND (forzero, 0);
3379 : :
3380 : 31920886 : 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 : 31919184 : 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 : 31919184 : 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 : 31919142 : if (TREE_CODE (t) == MEM_REF
3411 : 31919142 : && !integer_zerop (TREE_OPERAND (t, 0)))
3412 : : {
3413 : 11925341 : poly_offset_int off = mem_ref_offset (t);
3414 : 11925341 : off <<= LOG2_BITS_PER_UNIT;
3415 : 11925341 : off += bitpos;
3416 : 11925341 : poly_int64 off_hwi;
3417 : 11925341 : if (off.to_shwi (&off_hwi))
3418 : 11925339 : bitpos = off_hwi;
3419 : : else
3420 : : {
3421 : 2 : bitpos = 0;
3422 : 2 : bitmaxsize = -1;
3423 : : }
3424 : 11925341 : get_constraint_for_1 (TREE_OPERAND (t, 0), results, false, lhs_p);
3425 : 11925341 : do_deref (results);
3426 : : }
3427 : : else
3428 : 19993801 : get_constraint_for_1 (t, results, true, lhs_p);
3429 : :
3430 : : /* Strip off nothing_id. */
3431 : 31919142 : if (results->length () == 2)
3432 : : {
3433 : 7748 : gcc_assert ((*results)[0].var == nothing_id);
3434 : 7748 : results->unordered_remove (0);
3435 : : }
3436 : 31919142 : gcc_assert (results->length () == 1);
3437 : 31919142 : struct constraint_expr &result = results->last ();
3438 : :
3439 : 31919142 : if (result.type == SCALAR
3440 : 31919142 : && get_varinfo (result.var)->is_full_var)
3441 : : /* For single-field vars do not bother about the offset. */
3442 : 8256262 : result.offset = 0;
3443 : 23662880 : 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 : 11737628 : if (maybe_lt (poly_uint64 (bitpos), get_varinfo (result.var)->fullsize)
3451 : 11737628 : && 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 : 11728063 : struct constraint_expr cexpr = result;
3458 : 11728063 : varinfo_t curr;
3459 : 11728063 : results->pop ();
3460 : 11728063 : cexpr.offset = 0;
3461 : 61413776 : for (curr = get_varinfo (cexpr.var); curr; curr = vi_next (curr))
3462 : : {
3463 : 50538816 : if (ranges_maybe_overlap_p (poly_int64 (curr->offset),
3464 : 50538816 : curr->size, bitpos, bitmaxsize))
3465 : : {
3466 : 11939802 : cexpr.var = curr->id;
3467 : 11939802 : results->safe_push (cexpr);
3468 : 11939802 : 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 : 12581190 : 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 : 11728039 : 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 : 9565 : else if (known_eq (bitmaxsize, 0))
3498 : : {
3499 : 9346 : 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 : 219 : if (dump_file && (dump_flags & TDF_DETAILS))
3505 : 0 : fprintf (dump_file, "Access to past the end of variable, ignoring\n");
3506 : : }
3507 : 11925252 : 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 : 11925201 : HOST_WIDE_INT const_bitpos;
3513 : 11925201 : if (!bitpos.is_constant (&const_bitpos)
3514 : 11925201 : || const_bitpos == -1
3515 : 11925201 : || maybe_ne (bitsize, bitmaxsize)
3516 : 11243569 : || AGGREGATE_TYPE_P (TREE_TYPE (orig_t))
3517 : 9517626 : || result.offset == UNKNOWN_OFFSET)
3518 : 2407575 : result.offset = UNKNOWN_OFFSET;
3519 : : else
3520 : 9517626 : result.offset += const_bitpos;
3521 : : }
3522 : 51 : 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 : 51 : result.type = SCALAR;
3527 : 51 : result.var = anything_id;
3528 : 51 : 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 : 23886706 : do_deref (vec<ce_s> *constraints)
3543 : : {
3544 : 23886706 : struct constraint_expr *c;
3545 : 23886706 : unsigned int i = 0;
3546 : :
3547 : 47915033 : FOR_EACH_VEC_ELT (*constraints, i, c)
3548 : : {
3549 : 24028327 : if (c->type == SCALAR)
3550 : 18209925 : c->type = DEREF;
3551 : 5818402 : else if (c->type == ADDRESSOF)
3552 : 5818396 : 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 : 23886706 : }
3564 : :
3565 : : /* Given a tree T, return the constraint expression for taking the
3566 : : address of it. */
3567 : :
3568 : : static void
3569 : 27947382 : get_constraint_for_address_of (tree t, vec<ce_s> *results)
3570 : : {
3571 : 27947382 : struct constraint_expr *c;
3572 : 27947382 : unsigned int i;
3573 : :
3574 : 27947382 : get_constraint_for_1 (t, results, true, true);
3575 : :
3576 : 83845404 : FOR_EACH_VEC_ELT (*results, i, c)
3577 : : {
3578 : 27950640 : if (c->type == DEREF)
3579 : 1623092 : c->type = SCALAR;
3580 : : else
3581 : 26327548 : c->type = ADDRESSOF;
3582 : : }
3583 : 27947382 : }
3584 : :
3585 : : /* Given a tree T, return the constraint expression for it. */
3586 : :
3587 : : static void
3588 : 316746249 : get_constraint_for_1 (tree t, vec<ce_s> *results, bool address_p,
3589 : : bool lhs_p)
3590 : : {
3591 : 316746249 : 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 : 316746249 : if ((TREE_CODE (t) == INTEGER_CST
3607 : 32070211 : && 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 : 338352122 : || (TREE_CODE (t) == CONSTRUCTOR
3612 : 592804 : && CONSTRUCTOR_NELTS (t) == 0))
3613 : : {
3614 : 11010101 : if (flag_delete_null_pointer_checks)
3615 : 10991468 : temp.var = nothing_id;
3616 : : else
3617 : 18633 : temp.var = nonlocal_id;
3618 : 11010101 : temp.type = ADDRESSOF;
3619 : 11010101 : temp.offset = 0;
3620 : 11010101 : results->safe_push (temp);
3621 : 326939866 : return;
3622 : : }
3623 : :
3624 : : /* String constants are read-only, ideally we'd have a CONST_DECL
3625 : : for those. */
3626 : 305736148 : if (TREE_CODE (t) == STRING_CST)
3627 : : {
3628 : 6362682 : temp.var = string_id;
3629 : 6362682 : temp.type = SCALAR;
3630 : 6362682 : temp.offset = 0;
3631 : 6362682 : results->safe_push (temp);
3632 : 6362682 : return;
3633 : : }
3634 : :
3635 : 299373466 : switch (TREE_CODE_CLASS (TREE_CODE (t)))
3636 : : {
3637 : 27726017 : case tcc_expression:
3638 : 27726017 : {
3639 : 27726017 : switch (TREE_CODE (t))
3640 : : {
3641 : 27701475 : case ADDR_EXPR:
3642 : 27701475 : get_constraint_for_address_of (TREE_OPERAND (t, 0), results);
3643 : 27701475 : return;
3644 : : default:;
3645 : : }
3646 : : break;
3647 : : }
3648 : 44140041 : case tcc_reference:
3649 : 44140041 : {
3650 : 44140041 : if (!lhs_p && TREE_THIS_VOLATILE (t))
3651 : : /* Fall back to anything. */
3652 : : break;
3653 : :
3654 : 44035302 : switch (TREE_CODE (t))
3655 : : {
3656 : 11312423 : case MEM_REF:
3657 : 11312423 : {
3658 : 11312423 : struct constraint_expr cs;
3659 : 11312423 : varinfo_t vi, curr;
3660 : 11312423 : get_constraint_for_ptr_offset (TREE_OPERAND (t, 0),
3661 : 11312423 : TREE_OPERAND (t, 1), results);
3662 : 11312423 : do_deref (results);
3663 : :
3664 : : /* If we are not taking the address then make sure to process
3665 : : all subvariables we might access. */
3666 : 11312423 : if (address_p)
3667 : : return;
3668 : :
3669 : 10623726 : cs = results->last ();
3670 : 10623726 : if (cs.type == DEREF
3671 : 10623726 : && type_can_have_subvars (TREE_TYPE (t)))
3672 : : {
3673 : : /* For dereferences this means we have to defer it
3674 : : to solving time. */
3675 : 658659 : results->last ().offset = UNKNOWN_OFFSET;
3676 : 658659 : return;
3677 : : }
3678 : 9965067 : if (cs.type != SCALAR)
3679 : : return;
3680 : :
3681 : 4832723 : vi = get_varinfo (cs.var);
3682 : 4832723 : curr = vi_next (vi);
3683 : 4832723 : if (!vi->is_full_var
3684 : 3770212 : && curr)
3685 : : {
3686 : 2473405 : unsigned HOST_WIDE_INT size;
3687 : 2473405 : if (tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (t))))
3688 : 2473405 : size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (t)));
3689 : : else
3690 : 2473405 : size = -1;
3691 : 2562799 : for (; curr; curr = vi_next (curr))
3692 : : {
3693 : 2542132 : if (curr->offset - vi->offset < size)
3694 : : {
3695 : 89394 : cs.var = curr->id;
3696 : 89394 : results->safe_push (cs);
3697 : : }
3698 : : else
3699 : : break;
3700 : : }
3701 : : }
3702 : : return;
3703 : : }
3704 : 31920886 : case ARRAY_REF:
3705 : 31920886 : case ARRAY_RANGE_REF:
3706 : 31920886 : case COMPONENT_REF:
3707 : 31920886 : case IMAGPART_EXPR:
3708 : 31920886 : case REALPART_EXPR:
3709 : 31920886 : case BIT_FIELD_REF:
3710 : 31920886 : get_constraint_for_component_ref (t, results, address_p, lhs_p);
3711 : 31920886 : return;
3712 : 801993 : case VIEW_CONVERT_EXPR:
3713 : 801993 : get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p,
3714 : : lhs_p);
3715 : 801993 : return;
3716 : : /* We are missing handling for TARGET_MEM_REF here. */
3717 : : default:;
3718 : : }
3719 : : break;
3720 : : }
3721 : 154986573 : case tcc_exceptional:
3722 : 154986573 : {
3723 : 154986573 : switch (TREE_CODE (t))
3724 : : {
3725 : 154939332 : case SSA_NAME:
3726 : 154939332 : {
3727 : 154939332 : get_constraint_for_ssa_var (t, results, address_p);
3728 : 154939332 : return;
3729 : : }
3730 : 47041 : case CONSTRUCTOR:
3731 : 47041 : {
3732 : 47041 : unsigned int i;
3733 : 47041 : tree val;
3734 : 47041 : auto_vec<ce_s> tmp;
3735 : 269560 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, val)
3736 : : {
3737 : 222519 : struct constraint_expr *rhsp;
3738 : 222519 : unsigned j;
3739 : 222519 : get_constraint_for_1 (val, &tmp, address_p, lhs_p);
3740 : 445255 : FOR_EACH_VEC_ELT (tmp, j, rhsp)
3741 : 222736 : results->safe_push (*rhsp);
3742 : 222519 : 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 : 47041 : return;
3748 : 47041 : }
3749 : : default:;
3750 : : }
3751 : : break;
3752 : : }
3753 : 49159276 : case tcc_declaration:
3754 : 49159276 : {
3755 : 49159276 : if (!lhs_p && VAR_P (t) && TREE_THIS_VOLATILE (t))
3756 : : /* Fall back to anything. */
3757 : : break;
3758 : 48472310 : get_constraint_for_ssa_var (t, results, address_p);
3759 : 48472310 : return;
3760 : : }
3761 : 23361522 : case tcc_constant:
3762 : 23361522 : {
3763 : : /* We cannot refer to automatic variables through constants. */
3764 : 23361522 : temp.type = ADDRESSOF;
3765 : 23361522 : temp.var = nonlocal_id;
3766 : 23361522 : temp.offset = 0;
3767 : 23361522 : results->safe_push (temp);
3768 : 23361522 : return;
3769 : : }
3770 : 791705 : default:;
3771 : : }
3772 : :
3773 : : /* The default fallback is a constraint from anything. */
3774 : 816484 : temp.type = ADDRESSOF;
3775 : 816484 : temp.var = anything_id;
3776 : 816484 : temp.offset = 0;
3777 : 816484 : results->safe_push (temp);
3778 : : }
3779 : :
3780 : : /* Given a gimple tree T, return the constraint expression vector for it. */
3781 : :
3782 : : static void
3783 : 87365087 : get_constraint_for (tree t, vec<ce_s> *results)
3784 : : {
3785 : 87365087 : gcc_assert (results->length () == 0);
3786 : :
3787 : 87365087 : get_constraint_for_1 (t, results, false, true);
3788 : 87365087 : }
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 : 168490126 : get_constraint_for_rhs (tree t, vec<ce_s> *results)
3795 : : {
3796 : 168490126 : gcc_assert (results->length () == 0);
3797 : :
3798 : 168490126 : get_constraint_for_1 (t, results, false, false);
3799 : 168490126 : }
3800 : :
3801 : :
3802 : : /* Efficiently generates constraints from all entries in *RHSC to all
3803 : : entries in *LHSC. */
3804 : :
3805 : : static void
3806 : 93896776 : process_all_all_constraints (const vec<ce_s> &lhsc,
3807 : : const vec<ce_s> &rhsc)
3808 : : {
3809 : 93896776 : struct constraint_expr *lhsp, *rhsp;
3810 : 93896776 : unsigned i, j;
3811 : :
3812 : 95189529 : if (lhsc.length () <= 1 || rhsc.length () <= 1)
3813 : : {
3814 : 280742573 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
3815 : 301412882 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
3816 : 113751824 : process_constraint (new_constraint (*lhsp, *rhsp));
3817 : : }
3818 : : else
3819 : : {
3820 : 815261 : struct constraint_expr tmp;
3821 : 815261 : tmp = new_scalar_tmp_constraint_exp ("allalltmp", true);
3822 : 4289600 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
3823 : 2659078 : process_constraint (new_constraint (tmp, *rhsp));
3824 : 3605111 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
3825 : 1974589 : process_constraint (new_constraint (*lhsp, tmp));
3826 : : }
3827 : 93896776 : }
3828 : :
3829 : : /* Handle aggregate copies by expanding into copies of the respective
3830 : : fields of the structures. */
3831 : :
3832 : : static void
3833 : 2805965 : do_structure_copy (tree lhsop, tree rhsop)
3834 : : {
3835 : 2805965 : struct constraint_expr *lhsp, *rhsp;
3836 : 2805965 : auto_vec<ce_s> lhsc;
3837 : 2805965 : auto_vec<ce_s> rhsc;
3838 : 2805965 : unsigned j;
3839 : :
3840 : 2805965 : get_constraint_for (lhsop, &lhsc);
3841 : 2805965 : get_constraint_for_rhs (rhsop, &rhsc);
3842 : 2805965 : lhsp = &lhsc[0];
3843 : 2805965 : rhsp = &rhsc[0];
3844 : 2805965 : if (lhsp->type == DEREF
3845 : 2240038 : || (lhsp->type == ADDRESSOF && lhsp->var == anything_id)
3846 : 2240038 : || rhsp->type == DEREF)
3847 : : {
3848 : 1083824 : if (lhsp->type == DEREF)
3849 : : {
3850 : 565927 : gcc_assert (lhsc.length () == 1);
3851 : 565927 : lhsp->offset = UNKNOWN_OFFSET;
3852 : : }
3853 : 1083824 : if (rhsp->type == DEREF)
3854 : : {
3855 : 625629 : gcc_assert (rhsc.length () == 1);
3856 : 625629 : rhsp->offset = UNKNOWN_OFFSET;
3857 : : }
3858 : 1083824 : process_all_all_constraints (lhsc, rhsc);
3859 : : }
3860 : 1722141 : else if (lhsp->type == SCALAR
3861 : 1722141 : && (rhsp->type == SCALAR
3862 : 452510 : || rhsp->type == ADDRESSOF))
3863 : : {
3864 : 1722141 : HOST_WIDE_INT lhssize, lhsoffset;
3865 : 1722141 : HOST_WIDE_INT rhssize, rhsoffset;
3866 : 1722141 : bool reverse;
3867 : 1722141 : unsigned k = 0;
3868 : 1722141 : if (!get_ref_base_and_extent_hwi (lhsop, &lhsoffset, &lhssize, &reverse)
3869 : 1722141 : || !get_ref_base_and_extent_hwi (rhsop, &rhsoffset, &rhssize,
3870 : : &reverse))
3871 : : {
3872 : 5607 : process_all_all_constraints (lhsc, rhsc);
3873 : 5607 : return;
3874 : : }
3875 : 6339031 : for (j = 0; lhsc.iterate (j, &lhsp);)
3876 : : {
3877 : 4698775 : varinfo_t lhsv, rhsv;
3878 : 4698775 : rhsp = &rhsc[k];
3879 : 4698775 : lhsv = get_varinfo (lhsp->var);
3880 : 4698775 : rhsv = get_varinfo (rhsp->var);
3881 : 4698775 : if (lhsv->may_have_pointers
3882 : 4698775 : && (lhsv->is_full_var
3883 : 4091626 : || rhsv->is_full_var
3884 : 3183730 : || ranges_overlap_p (lhsv->offset + rhsoffset, lhsv->size,
3885 : 3183730 : rhsv->offset + lhsoffset, rhsv->size)))
3886 : 3519689 : process_constraint (new_constraint (*lhsp, *rhsp));
3887 : 4698775 : if (!rhsv->is_full_var
3888 : 3321968 : && (lhsv->is_full_var
3889 : 3183730 : || (lhsv->offset + rhsoffset + lhsv->size
3890 : 3183730 : > rhsv->offset + lhsoffset + rhsv->size)))
3891 : : {
3892 : 1325342 : ++k;
3893 : 1325342 : if (k >= rhsc.length ())
3894 : : break;
3895 : : }
3896 : : else
3897 : 3373433 : ++j;
3898 : : }
3899 : 1716534 : }
3900 : : else
3901 : 0 : gcc_unreachable ();
3902 : 2805965 : }
3903 : :
3904 : : /* Create constraints ID = { rhsc }. */
3905 : :
3906 : : static void
3907 : 56244720 : make_constraints_to (unsigned id, const vec<ce_s> &rhsc)
3908 : : {
3909 : 56244720 : struct constraint_expr *c;
3910 : 56244720 : struct constraint_expr includes;
3911 : 56244720 : unsigned int j;
3912 : :
3913 : 56244720 : includes.var = id;
3914 : 56244720 : includes.offset = 0;
3915 : 56244720 : includes.type = SCALAR;
3916 : :
3917 : 115857920 : FOR_EACH_VEC_ELT (rhsc, j, c)
3918 : 59613200 : process_constraint (new_constraint (includes, *c));
3919 : 56244720 : }
3920 : :
3921 : : /* Create a constraint ID = OP. */
3922 : :
3923 : : static void
3924 : 56062005 : make_constraint_to (unsigned id, tree op)
3925 : : {
3926 : 56062005 : auto_vec<ce_s> rhsc;
3927 : 56062005 : get_constraint_for_rhs (op, &rhsc);
3928 : 56062005 : make_constraints_to (id, rhsc);
3929 : 56062005 : }
3930 : :
3931 : : /* Create a constraint ID = &FROM. */
3932 : :
3933 : : static void
3934 : 11376123 : make_constraint_from (varinfo_t vi, int from)
3935 : : {
3936 : 11376123 : struct constraint_expr lhs, rhs;
3937 : :
3938 : 11376123 : lhs.var = vi->id;
3939 : 11376123 : lhs.offset = 0;
3940 : 11376123 : lhs.type = SCALAR;
3941 : :
3942 : 11376123 : rhs.var = from;
3943 : 11376123 : rhs.offset = 0;
3944 : 11376123 : rhs.type = ADDRESSOF;
3945 : 11376123 : process_constraint (new_constraint (lhs, rhs));
3946 : 11376123 : }
3947 : :
3948 : : /* Create a constraint ID = FROM. */
3949 : :
3950 : : static void
3951 : 76511870 : make_copy_constraint (varinfo_t vi, int from)
3952 : : {
3953 : 76511870 : struct constraint_expr lhs, rhs;
3954 : :
3955 : 76511870 : lhs.var = vi->id;
3956 : 76511870 : lhs.offset = 0;
3957 : 76511870 : lhs.type = SCALAR;
3958 : :
3959 : 76511870 : rhs.var = from;
3960 : 76511870 : rhs.offset = 0;
3961 : 76511870 : rhs.type = SCALAR;
3962 : 76511870 : process_constraint (new_constraint (lhs, rhs));
3963 : 76511870 : }
3964 : :
3965 : : /* Make constraints necessary to make OP escape. */
3966 : :
3967 : : static void
3968 : 23435925 : make_escape_constraint (tree op)
3969 : : {
3970 : 0 : make_constraint_to (escaped_id, op);
3971 : 23435925 : }
3972 : :
3973 : : /* Make constraint necessary to make all indirect references
3974 : : from VI escape. */
3975 : :
3976 : : static void
3977 : 1142889 : make_indirect_escape_constraint (varinfo_t vi)
3978 : : {
3979 : 1142889 : struct constraint_expr lhs, rhs;
3980 : : /* escaped = *(VAR + UNKNOWN); */
3981 : 1142889 : lhs.type = SCALAR;
3982 : 1142889 : lhs.var = escaped_id;
3983 : 1142889 : lhs.offset = 0;
3984 : 1142889 : rhs.type = DEREF;
3985 : 1142889 : rhs.var = vi->id;
3986 : 1142889 : rhs.offset = UNKNOWN_OFFSET;
3987 : 1142889 : process_constraint (new_constraint (lhs, rhs));
3988 : 1142889 : }
3989 : :
3990 : : /* Add constraints to that the solution of VI is transitively closed. */
3991 : :
3992 : : static void
3993 : 25660623 : make_transitive_closure_constraints (varinfo_t vi)
3994 : : {
3995 : 25660623 : struct constraint_expr lhs, rhs;
3996 : :
3997 : : /* VAR = *(VAR + UNKNOWN); */
3998 : 25660623 : lhs.type = SCALAR;
3999 : 25660623 : lhs.var = vi->id;
4000 : 25660623 : lhs.offset = 0;
4001 : 25660623 : rhs.type = DEREF;
4002 : 25660623 : rhs.var = vi->id;
4003 : 25660623 : rhs.offset = UNKNOWN_OFFSET;
4004 : 25660623 : process_constraint (new_constraint (lhs, rhs));
4005 : 25660623 : }
4006 : :
4007 : : /* Add constraints to that the solution of VI has all subvariables added. */
4008 : :
4009 : : static void
4010 : 31115794 : make_any_offset_constraints (varinfo_t vi)
4011 : : {
4012 : 31115794 : struct constraint_expr lhs, rhs;
4013 : :
4014 : : /* VAR = VAR + UNKNOWN; */
4015 : 31115794 : lhs.type = SCALAR;
4016 : 31115794 : lhs.var = vi->id;
4017 : 31115794 : lhs.offset = 0;
4018 : 31115794 : rhs.type = SCALAR;
4019 : 31115794 : rhs.var = vi->id;
4020 : 31115794 : rhs.offset = UNKNOWN_OFFSET;
4021 : 31115794 : process_constraint (new_constraint (lhs, rhs));
4022 : 31115794 : }
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 : 921354 : build_fake_var_decl (tree type)
4031 : : {
4032 : 921354 : tree decl = (tree) XOBNEW (&fake_var_decl_obstack, struct tree_var_decl);
4033 : 921354 : memset (decl, 0, sizeof (struct tree_var_decl));
4034 : 921354 : TREE_SET_CODE (decl, VAR_DECL);
4035 : 921354 : TREE_TYPE (decl) = type;
4036 : 921354 : DECL_UID (decl) = allocate_decl_uid ();
4037 : 921354 : SET_DECL_PT_UID (decl, -1);
4038 : 921354 : layout_decl (decl, 0);
4039 : 921354 : return decl;
4040 : : }
4041 : :
4042 : : /* Create a new artificial heap variable with NAME.
4043 : : Return the created variable. */
4044 : :
4045 : : static varinfo_t
4046 : 335425 : make_heapvar (const char *name, bool add_id)
4047 : : {
4048 : 335425 : varinfo_t vi;
4049 : 335425 : tree heapvar;
4050 : :
4051 : 335425 : heapvar = build_fake_var_decl (ptr_type_node);
4052 : 335425 : DECL_EXTERNAL (heapvar) = 1;
4053 : :
4054 : 335425 : vi = new_var_info (heapvar, name, add_id);
4055 : 335425 : vi->is_heap_var = true;
4056 : 335425 : vi->is_unknown_size_var = true;
4057 : 335425 : vi->offset = 0;
4058 : 335425 : vi->fullsize = ~0;
4059 : 335425 : vi->size = ~0;
4060 : 335425 : vi->is_full_var = true;
4061 : 335425 : insert_vi_for_tree (heapvar, vi);
4062 : :
4063 : 335425 : 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 : 11179 : make_constraint_from_restrict (varinfo_t lhs, const char *name, bool add_id)
4072 : : {
4073 : 11179 : varinfo_t vi = make_heapvar (name, add_id);
4074 : 11179 : vi->is_restrict_var = 1;
4075 : 11179 : vi->is_global_var = 1;
4076 : 11179 : vi->may_have_pointers = 1;
4077 : 11179 : make_constraint_from (lhs, vi->id);
4078 : 11179 : 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 : 11179 : make_constraint_from_global_restrict (varinfo_t lhs, const char *name,
4088 : : bool add_id)
4089 : : {
4090 : 11179 : varinfo_t vi = make_constraint_from_restrict (lhs, name, add_id);
4091 : 11179 : make_copy_constraint (vi, nonlocal_id);
4092 : 11179 : 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 : 1435203 : get_function_part_constraint (varinfo_t fi, unsigned part)
4109 : : {
4110 : 1435203 : struct constraint_expr c;
4111 : :
4112 : 1435203 : gcc_assert (in_ipa_mode);
4113 : :
4114 : 1435203 : 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 : 493059 : else if (fi->decl && TREE_CODE (fi->decl) == FUNCTION_DECL)
4122 : : {
4123 : 489676 : varinfo_t ai = first_vi_for_offset (fi, part);
4124 : 489676 : if (ai)
4125 : 489676 : c.var = ai->id;
4126 : : else
4127 : : c.var = anything_id;
4128 : : c.offset = 0;
4129 : : c.type = SCALAR;
4130 : : }
4131 : : else
4132 : : {
4133 : 3383 : c.var = fi->id;
4134 : 3383 : c.offset = part;
4135 : 3383 : c.type = DEREF;
4136 : : }
4137 : :
4138 : 1435203 : 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 : 30033883 : handle_call_arg (gcall *stmt, tree arg, vec<ce_s> *results, int flags,
4148 : : int callescape_id, bool writes_global_memory)
4149 : : {
4150 : 30033883 : int relevant_indirect_flags = EAF_NO_INDIRECT_CLOBBER | EAF_NO_INDIRECT_READ
4151 : : | EAF_NO_INDIRECT_ESCAPE;
4152 : 30033883 : int relevant_flags = relevant_indirect_flags
4153 : : | EAF_NO_DIRECT_CLOBBER
4154 : : | EAF_NO_DIRECT_READ
4155 : : | EAF_NO_DIRECT_ESCAPE;
4156 : 30033883 : if (gimple_call_lhs (stmt))
4157 : : {
4158 : 11477132 : relevant_flags |= EAF_NOT_RETURNED_DIRECTLY | EAF_NOT_RETURNED_INDIRECTLY;
4159 : 11477132 : 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 : 11477132 : if (flags & EAF_NO_DIRECT_READ)
4167 : 1970937 : 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 : 30033883 : if ((flags & EAF_UNUSED) || ((flags & relevant_flags) == relevant_flags))
4174 : : return;
4175 : :
4176 : : /* Produce varinfo for direct accesses to ARG. */
4177 : 28794724 : varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
4178 : 28794724 : tem->is_reg_var = true;
4179 : 28794724 : make_constraint_to (tem->id, arg);
4180 : 28794724 : make_any_offset_constraints (tem);
4181 : :
4182 : 28794724 : 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 : 28794724 : if (((flags & EAF_NO_INDIRECT_CLOBBER) != 0)
4188 : 28794724 : == ((flags & EAF_NO_DIRECT_CLOBBER) != 0)
4189 : 27465910 : && (((flags & EAF_NO_INDIRECT_READ) != 0)
4190 : 27465910 : == ((flags & EAF_NO_DIRECT_READ) != 0))
4191 : 26523475 : && (((flags & EAF_NO_INDIRECT_ESCAPE) != 0)
4192 : 26523475 : == ((flags & EAF_NO_DIRECT_ESCAPE) != 0))
4193 : 26009037 : && (((flags & EAF_NOT_RETURNED_INDIRECTLY) != 0)
4194 : 26009037 : == ((flags & EAF_NOT_RETURNED_DIRECTLY) != 0)))
4195 : : {
4196 : 24165935 : make_transitive_closure_constraints (tem);
4197 : 24165935 : callarg_transitive = true;
4198 : : }
4199 : :
4200 : : /* If necessary, produce varinfo for indirect accesses to ARG. */
4201 : 28794724 : varinfo_t indir_tem = NULL;
4202 : 24165935 : if (!callarg_transitive
4203 : 4628789 : && (flags & relevant_indirect_flags) != relevant_indirect_flags)
4204 : : {
4205 : 1610649 : struct constraint_expr lhs, rhs;
4206 : 1610649 : indir_tem = new_var_info (NULL_TREE, "indircallarg", true);
4207 : 1610649 : indir_tem->is_reg_var = true;
4208 : :
4209 : : /* indir_term = *tem. */
4210 : 1610649 : lhs.type = SCALAR;
4211 : 1610649 : lhs.var = indir_tem->id;
4212 : 1610649 : lhs.offset = 0;
4213 : :
4214 : 1610649 : rhs.type = DEREF;
4215 : 1610649 : rhs.var = tem->id;
4216 : 1610649 : rhs.offset = UNKNOWN_OFFSET;
4217 : 1610649 : process_constraint (new_constraint (lhs, rhs));
4218 : :
4219 : 1610649 : 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 : 1610649 : if (!(flags & EAF_NO_INDIRECT_READ))
4224 : 1494688 : make_transitive_closure_constraints (indir_tem);
4225 : 1610649 : gcc_checking_assert (!(flags & EAF_NO_DIRECT_READ));
4226 : : }
4227 : :
4228 : 28794724 : if (gimple_call_lhs (stmt))
4229 : : {
4230 : 11252471 : if (!(flags & EAF_NOT_RETURNED_DIRECTLY))
4231 : : {
4232 : 10256631 : struct constraint_expr cexpr;
4233 : 10256631 : cexpr.var = tem->id;
4234 : 10256631 : cexpr.type = SCALAR;
4235 : 10256631 : cexpr.offset = 0;
4236 : 10256631 : results->safe_push (cexpr);
4237 : : }
4238 : 11252471 : if (!callarg_transitive & !(flags & EAF_NOT_RETURNED_INDIRECTLY))
4239 : : {
4240 : 637568 : struct constraint_expr cexpr;
4241 : 637568 : cexpr.var = indir_tem->id;
4242 : 637568 : cexpr.type = SCALAR;
4243 : 637568 : cexpr.offset = 0;
4244 : 637568 : results->safe_push (cexpr);
4245 : : }
4246 : : }
4247 : :
4248 : 28794724 : if (!(flags & EAF_NO_DIRECT_READ))
4249 : : {
4250 : 26652040 : varinfo_t uses = get_call_use_vi (stmt);
4251 : 26652040 : make_copy_constraint (uses, tem->id);
4252 : 26652040 : if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_READ))
4253 : 1494688 : make_copy_constraint (uses, indir_tem->id);
4254 : : }
4255 : : else
4256 : : /* To read indirectly we need to read directly. */
4257 : 2142684 : gcc_checking_assert (flags & EAF_NO_INDIRECT_READ);
4258 : :
4259 : 28794724 : if (!(flags & EAF_NO_DIRECT_CLOBBER))
4260 : : {
4261 : 23910622 : struct constraint_expr lhs, rhs;
4262 : :
4263 : : /* *arg = callescape. */
4264 : 23910622 : lhs.type = DEREF;
4265 : 23910622 : lhs.var = tem->id;
4266 : 23910622 : lhs.offset = 0;
4267 : :
4268 : 23910622 : rhs.type = SCALAR;
4269 : 23910622 : rhs.var = callescape_id;
4270 : 23910622 : rhs.offset = 0;
4271 : 23910622 : process_constraint (new_constraint (lhs, rhs));
4272 : :
4273 : : /* callclobbered = arg. */
4274 : 23910622 : make_copy_constraint (get_call_clobber_vi (stmt), tem->id);
4275 : : }
4276 : 28794724 : if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_CLOBBER))
4277 : : {
4278 : 1315473 : struct constraint_expr lhs, rhs;
4279 : :
4280 : : /* *indir_arg = callescape. */
4281 : 1315473 : lhs.type = DEREF;
4282 : 1315473 : lhs.var = indir_tem->id;
4283 : 1315473 : lhs.offset = 0;
4284 : :
4285 : 1315473 : rhs.type = SCALAR;
4286 : 1315473 : rhs.var = callescape_id;
4287 : 1315473 : rhs.offset = 0;
4288 : 1315473 : process_constraint (new_constraint (lhs, rhs));
4289 : :
4290 : : /* callclobbered = indir_arg. */
4291 : 1315473 : make_copy_constraint (get_call_clobber_vi (stmt), indir_tem->id);
4292 : : }
4293 : :
4294 : 28794724 : if (!(flags & (EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE)))
4295 : : {
4296 : 22430400 : struct constraint_expr lhs, rhs;
4297 : :
4298 : : /* callescape = arg; */
4299 : 22430400 : lhs.var = callescape_id;
4300 : 22430400 : lhs.offset = 0;
4301 : 22430400 : lhs.type = SCALAR;
4302 : :
4303 : 22430400 : rhs.var = tem->id;
4304 : 22430400 : rhs.offset = 0;
4305 : 22430400 : rhs.type = SCALAR;
4306 : 22430400 : process_constraint (new_constraint (lhs, rhs));
4307 : :
4308 : 22430400 : if (writes_global_memory)
4309 : 21710378 : make_escape_constraint (arg);
4310 : : }
4311 : 6364324 : else if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_ESCAPE))
4312 : : {
4313 : 1255247 : struct constraint_expr lhs, rhs;
4314 : :
4315 : : /* callescape = *(indir_arg + UNKNOWN); */
4316 : 1255247 : lhs.var = callescape_id;
4317 : 1255247 : lhs.offset = 0;
4318 : 1255247 : lhs.type = SCALAR;
4319 : :
4320 : 1255247 : rhs.var = indir_tem->id;
4321 : 1255247 : rhs.offset = 0;
4322 : 1255247 : rhs.type = SCALAR;
4323 : 1255247 : process_constraint (new_constraint (lhs, rhs));
4324 : :
4325 : 1255247 : if (writes_global_memory)
4326 : 1142889 : 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 : 45118720 : determine_global_memory_access (gcall *stmt,
4335 : : bool *writes_global_memory,
4336 : : bool *reads_global_memory,
4337 : : bool *uses_global_memory)
4338 : : {
4339 : 45118720 : tree callee;
4340 : 45118720 : cgraph_node *node;
4341 : 45118720 : modref_summary *summary;
4342 : :
4343 : : /* We need to detrmine reads to set uses. */
4344 : 45118720 : gcc_assert (!uses_global_memory || reads_global_memory);
4345 : :
4346 : 45118720 : if ((callee = gimple_call_fndecl (stmt)) != NULL_TREE
4347 : 42974581 : && (node = cgraph_node::get (callee)) != NULL
4348 : 88063463 : && (summary = get_modref_function_summary (node)))
4349 : : {
4350 : 8325417 : if (writes_global_memory && *writes_global_memory)
4351 : 5158450 : *writes_global_memory = summary->global_memory_written;
4352 : 8325417 : if (reads_global_memory && *reads_global_memory)
4353 : 5715837 : *reads_global_memory = summary->global_memory_read;
4354 : 8325417 : if (reads_global_memory && uses_global_memory
4355 : 2862934 : && !summary->calls_interposable
4356 : 10559801 : && !*reads_global_memory && node->binds_to_current_def_p ())
4357 : 441141 : *uses_global_memory = false;
4358 : : }
4359 : 45118720 : if ((writes_global_memory && *writes_global_memory)
4360 : 18121924 : || (uses_global_memory && *uses_global_memory)
4361 : 2891370 : || (reads_global_memory && *reads_global_memory))
4362 : : {
4363 : 42748319 : attr_fnspec fnspec = gimple_call_fnspec (stmt);
4364 : 42748319 : if (fnspec.known_p ())
4365 : : {
4366 : 5695623 : if (writes_global_memory
4367 : 5695623 : && !fnspec.global_memory_written_p ())
4368 : 1433481 : *writes_global_memory = false;
4369 : 5695623 : if (reads_global_memory && !fnspec.global_memory_read_p ())
4370 : : {
4371 : 2205207 : *reads_global_memory = false;
4372 : 2205207 : if (uses_global_memory)
4373 : 1881836 : *uses_global_memory = false;
4374 : : }
4375 : : }
4376 : : }
4377 : 45118720 : }
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 : 15048542 : 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 : 15048542 : determine_global_memory_access (stmt, &writes_global_memory,
4394 : : &reads_global_memory,
4395 : : NULL);
4396 : :
4397 : 15048542 : 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 : 15048542 : struct constraint_expr lhs, rhs;
4403 : :
4404 : 15048542 : lhs.type = SCALAR;
4405 : 15048542 : lhs.var = callescape->id;
4406 : 15048542 : lhs.offset = 0;
4407 : :
4408 : 15048542 : rhs.type = reads_global_memory ? SCALAR : ADDRESSOF;
4409 : 15048542 : rhs.var = nonlocal_id;
4410 : 15048542 : rhs.offset = 0;
4411 : :
4412 : 15048542 : process_constraint (new_constraint (lhs, rhs));
4413 : 15048542 : results->safe_push (rhs);
4414 : :
4415 : 15048542 : varinfo_t uses = get_call_use_vi (stmt);
4416 : 15048542 : make_copy_constraint (uses, callescape->id);
4417 : :
4418 : 44998644 : for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
4419 : : {
4420 : 29950102 : tree arg = gimple_call_arg (stmt, i);
4421 : 29950102 : int flags = gimple_call_arg_flags (stmt, i);
4422 : 29950102 : handle_call_arg (stmt, arg, results,
4423 : : flags | implicit_eaf_flags,
4424 : 29950102 : callescape->id, writes_global_memory);
4425 : : }
4426 : :
4427 : : /* The static chain escapes as well. */
4428 : 15048542 : if (gimple_call_chain (stmt))
4429 : 83781 : handle_call_arg (stmt, gimple_call_chain (stmt), results,
4430 : : implicit_eaf_flags
4431 : 83781 : | gimple_call_static_chain_flags (stmt),
4432 : 83781 : callescape->id, writes_global_memory);
4433 : :
4434 : : /* And if we applied NRV the address of the return slot escapes as well. */
4435 : 15048542 : if (gimple_call_return_slot_opt_p (stmt)
4436 : 647818 : && gimple_call_lhs (stmt) != NULL_TREE
4437 : 15668233 : && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
4438 : : {
4439 : 97472 : int flags = gimple_call_retslot_flags (stmt);
4440 : 97472 : const int relevant_flags = EAF_NO_DIRECT_ESCAPE
4441 : : | EAF_NOT_RETURNED_DIRECTLY;
4442 : :
4443 : 97472 : if (!(flags & EAF_UNUSED) && (flags & relevant_flags) != relevant_flags)
4444 : : {
4445 : 80401 : auto_vec<ce_s> tmpc;
4446 : :
4447 : 80401 : get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
4448 : :
4449 : 80401 : if (!(flags & EAF_NO_DIRECT_ESCAPE))
4450 : : {
4451 : 80397 : make_constraints_to (callescape->id, tmpc);
4452 : 80397 : if (writes_global_memory)
4453 : 79306 : make_constraints_to (escaped_id, tmpc);
4454 : : }
4455 : 80401 : if (!(flags & EAF_NOT_RETURNED_DIRECTLY))
4456 : : {
4457 : : struct constraint_expr *c;
4458 : : unsigned i;
4459 : 239621 : FOR_EACH_VEC_ELT (tmpc, i, c)
4460 : 79610 : results->safe_push (*c);
4461 : : }
4462 : 80401 : }
4463 : : }
4464 : 15048542 : }
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 : 5815578 : handle_lhs_call (gcall *stmt, tree lhs, int flags, vec<ce_s> &rhsc,
4472 : : tree fndecl)
4473 : : {
4474 : 5815578 : auto_vec<ce_s> lhsc;
4475 : :
4476 : 5815578 : get_constraint_for (lhs, &lhsc);
4477 : : /* If the store is to a global decl make sure to
4478 : : add proper escape constraints. */
4479 : 5815578 : lhs = get_base_address (lhs);
4480 : 5815578 : if (lhs
4481 : 5815578 : && DECL_P (lhs)
4482 : 6934482 : && is_global_var (lhs))
4483 : : {
4484 : 3271 : struct constraint_expr tmpc;
4485 : 3271 : tmpc.var = escaped_id;
4486 : 3271 : tmpc.offset = 0;
4487 : 3271 : tmpc.type = SCALAR;
4488 : 3271 : lhsc.safe_push (tmpc);
4489 : : }
4490 : :
4491 : : /* If the call returns an argument unmodified override the rhs
4492 : : constraints. */
4493 : 5815578 : if (flags & ERF_RETURNS_ARG
4494 : 5815578 : && (flags & ERF_RETURN_ARG_MASK) < gimple_call_num_args (stmt))
4495 : : {
4496 : 76918 : tree arg;
4497 : 76918 : rhsc.truncate (0);
4498 : 76918 : arg = gimple_call_arg (stmt, flags & ERF_RETURN_ARG_MASK);
4499 : 76918 : get_constraint_for (arg, &rhsc);
4500 : 76918 : process_all_all_constraints (lhsc, rhsc);
4501 : 76918 : rhsc.truncate (0);
4502 : : }
4503 : 5738660 : else if (flags & ERF_NOALIAS)
4504 : : {
4505 : 291229 : varinfo_t vi;
4506 : 291229 : struct constraint_expr tmpc;
4507 : 291229 : rhsc.truncate (0);
4508 : 291229 : 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 : 291229 : DECL_EXTERNAL (vi->decl) = 0;
4512 : 291229 : 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 : 291229 : if (!fndecl
4517 : 291229 : || !fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
4518 : 151631 : make_constraint_from (vi, nonlocal_id);
4519 : 291229 : tmpc.var = vi->id;
4520 : 291229 : tmpc.offset = 0;
4521 : 291229 : tmpc.type = ADDRESSOF;
4522 : 291229 : rhsc.safe_push (tmpc);
4523 : 291229 : process_all_all_constraints (lhsc, rhsc);
4524 : 291229 : rhsc.truncate (0);
4525 : : }
4526 : : else
4527 : 5447431 : process_all_all_constraints (lhsc, rhsc);
4528 : 5815578 : }
4529 : :
4530 : :
4531 : : /* Return the varinfo for the callee of CALL. */
4532 : :
4533 : : static varinfo_t
4534 : 16551204 : get_fi_for_callee (gcall *call)
4535 : : {
4536 : 16551204 : tree decl, fn = gimple_call_fn (call);
4537 : :
4538 : 16551204 : if (fn && TREE_CODE (fn) == OBJ_TYPE_REF)
4539 : 146472 : 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 : 16551204 : decl = gimple_call_addr_fndecl (fn);
4545 : 16551204 : if (decl)
4546 : 15147000 : 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 : 1404204 : if (!fn || TREE_CODE (fn) != SSA_NAME)
4551 : 923143 : return get_varinfo (anything_id);
4552 : :
4553 : 481061 : if (SSA_NAME_IS_DEFAULT_DEF (fn)
4554 : 481061 : && (TREE_CODE (SSA_NAME_VAR (fn)) == PARM_DECL
4555 : 15 : || TREE_CODE (SSA_NAME_VAR (fn)) == RESULT_DECL))
4556 : 12097 : fn = SSA_NAME_VAR (fn);
4557 : :
4558 : 481061 : 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 : 804682 : find_func_aliases_for_call_arg (varinfo_t fi, unsigned index, tree arg)
4566 : : {
4567 : 804682 : struct constraint_expr lhs;
4568 : 804682 : lhs = get_function_part_constraint (fi, fi_parm_base + index);
4569 : :
4570 : 804682 : auto_vec<ce_s, 2> rhsc;
4571 : 804682 : get_constraint_for_rhs (arg, &rhsc);
4572 : :
4573 : 804682 : unsigned j;
4574 : 804682 : struct constraint_expr *rhsp;
4575 : 3218729 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
4576 : 804683 : process_constraint (new_constraint (lhs, *rhsp));
4577 : 804682 : }
4578 : :
4579 : : /* Return true if FNDECL may be part of another lto partition. */
4580 : :
4581 : : static bool
4582 : 41286 : fndecl_maybe_in_other_partition (tree fndecl)
4583 : : {
4584 : 41286 : cgraph_node *fn_node = cgraph_node::get (fndecl);
4585 : 41286 : if (fn_node == NULL)
4586 : : return true;
4587 : :
4588 : 41286 : 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 : 4972931 : find_func_aliases_for_builtin_call (struct function *fn, gcall *t)
4596 : : {
4597 : 4972931 : tree fndecl = gimple_call_fndecl (t);
4598 : 4972931 : auto_vec<ce_s, 2> lhsc;
4599 : 4972931 : auto_vec<ce_s, 4> rhsc;
4600 : 4972931 : varinfo_t fi;
4601 : :
4602 : 4972931 : 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 : 4525942 : 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 : 262570 : case BUILT_IN_STRCPY:
4613 : 262570 : case BUILT_IN_STRNCPY:
4614 : 262570 : case BUILT_IN_BCOPY:
4615 : 262570 : case BUILT_IN_MEMCPY:
4616 : 262570 : case BUILT_IN_MEMMOVE:
4617 : 262570 : case BUILT_IN_MEMPCPY:
4618 : 262570 : case BUILT_IN_STPCPY:
4619 : 262570 : case BUILT_IN_STPNCPY:
4620 : 262570 : case BUILT_IN_STRCAT:
4621 : 262570 : case BUILT_IN_STRNCAT:
4622 : 262570 : case BUILT_IN_STRCPY_CHK:
4623 : 262570 : case BUILT_IN_STRNCPY_CHK:
4624 : 262570 : case BUILT_IN_MEMCPY_CHK:
4625 : 262570 : case BUILT_IN_MEMMOVE_CHK:
4626 : 262570 : case BUILT_IN_MEMPCPY_CHK:
4627 : 262570 : case BUILT_IN_STPCPY_CHK:
4628 : 262570 : case BUILT_IN_STPNCPY_CHK:
4629 : 262570 : case BUILT_IN_STRCAT_CHK:
4630 : 262570 : case BUILT_IN_STRNCAT_CHK:
4631 : 262570 : case BUILT_IN_TM_MEMCPY:
4632 : 262570 : case BUILT_IN_TM_MEMMOVE:
4633 : 262570 : {
4634 : 262570 : tree res = gimple_call_lhs (t);
4635 : 525140 : tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
4636 : : == BUILT_IN_BCOPY ? 1 : 0));
4637 : 525140 : tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
4638 : 262570 : == BUILT_IN_BCOPY ? 0 : 1));
4639 : 262570 : if (res != NULL_TREE)
4640 : : {
4641 : 25354 : get_constraint_for (res, &lhsc);
4642 : 25354 : if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY
4643 : 22217 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY
4644 : 21042 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY
4645 : 19286 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY_CHK
4646 : 18949 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY_CHK
4647 : 44022 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY_CHK)
4648 : 6961 : get_constraint_for_ptr_offset (dest, NULL_TREE, &rhsc);
4649 : : else
4650 : 18393 : get_constraint_for (dest, &rhsc);
4651 : 25354 : process_all_all_constraints (lhsc, rhsc);
4652 : 25354 : lhsc.truncate (0);
4653 : 25354 : rhsc.truncate (0);
4654 : : }
4655 : 262570 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
4656 : 262570 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
4657 : 262570 : do_deref (&lhsc);
4658 : 262570 : do_deref (&rhsc);
4659 : 262570 : process_all_all_constraints (lhsc, rhsc);
4660 : 262570 : return true;
4661 : : }
4662 : 72866 : case BUILT_IN_MEMSET:
4663 : 72866 : case BUILT_IN_MEMSET_CHK:
4664 : 72866 : case BUILT_IN_TM_MEMSET:
4665 : 72866 : {
4666 : 72866 : tree res = gimple_call_lhs (t);
4667 : 72866 : tree dest = gimple_call_arg (t, 0);
4668 : 72866 : unsigned i;
4669 : 72866 : ce_s *lhsp;
4670 : 72866 : struct constraint_expr ac;
4671 : 72866 : if (res != NULL_TREE)
4672 : : {
4673 : 5547 : get_constraint_for (res, &lhsc);
4674 : 5547 : get_constraint_for (dest, &rhsc);
4675 : 5547 : process_all_all_constraints (lhsc, rhsc);
4676 : 5547 : lhsc.truncate (0);
4677 : : }
4678 : 72866 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
4679 : 72866 : do_deref (&lhsc);
4680 : 72866 : if (flag_delete_null_pointer_checks
4681 : 145591 : && 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 : 72866 : ac.offset = 0;
4692 : 1453759 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
4693 : 78951 : 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 : 32886 : case BUILT_IN_ALLOCA:
4701 : 32886 : case BUILT_IN_ALLOCA_WITH_ALIGN:
4702 : 32886 : case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX:
4703 : 32886 : {
4704 : 32886 : tree ptr = gimple_call_lhs (t);
4705 : 32886 : if (ptr == NULL_TREE)
4706 : : return true;
4707 : 32885 : get_constraint_for (ptr, &lhsc);
4708 : 32885 : 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 : 32885 : DECL_EXTERNAL (vi->decl) = 0;
4712 : 32885 : vi->is_global_var = 0;
4713 : 32885 : vi->is_heap_var = 0;
4714 : 32885 : struct constraint_expr tmpc;
4715 : 32885 : tmpc.var = vi->id;
4716 : 32885 : tmpc.offset = 0;
4717 : 32885 : tmpc.type = ADDRESSOF;
4718 : 32885 : rhsc.safe_push (tmpc);
4719 : 32885 : process_all_all_constraints (lhsc, rhsc);
4720 : 32885 : 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 : 1670 : case BUILT_IN_ASSUME_ALIGNED:
4741 : 1670 : {
4742 : 1670 : tree res = gimple_call_lhs (t);
4743 : 1670 : tree dest = gimple_call_arg (t, 0);
4744 : 1670 : if (res != NULL_TREE)
4745 : : {
4746 : 1670 : get_constraint_for (res, &lhsc);
4747 : 1670 : get_constraint_for (dest, &rhsc);
4748 : 1670 : process_all_all_constraints (lhsc, rhsc);
4749 : : }
4750 : 1670 : 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 : 15518 : case BUILT_IN_STRDUP:
4776 : 15518 : case BUILT_IN_STRNDUP:
4777 : 15518 : case BUILT_IN_REALLOC:
4778 : 15518 : if (gimple_call_lhs (t))
4779 : : {
4780 : 15482 : auto_vec<ce_s> rhsc;
4781 : 15482 : handle_lhs_call (t, gimple_call_lhs (t),
4782 : 15482 : gimple_call_return_flags (t) | ERF_NOALIAS,
4783 : : rhsc, fndecl);
4784 : 15482 : get_constraint_for_ptr_offset (gimple_call_lhs (t),
4785 : : NULL_TREE, &lhsc);
4786 : 15482 : get_constraint_for_ptr_offset (gimple_call_arg (t, 0),
4787 : : NULL_TREE, &rhsc);
4788 : 15482 : do_deref (&lhsc);
4789 : 15482 : do_deref (&rhsc);
4790 : 15482 : process_all_all_constraints (lhsc, rhsc);
4791 : 15482 : lhsc.truncate (0);
4792 : 15482 : 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 : 15482 : if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_REALLOC)
4797 : : {
4798 : 13834 : get_constraint_for (gimple_call_lhs (t), &lhsc);
4799 : 13834 : get_constraint_for (gimple_call_arg (t, 0), &rhsc);
4800 : 13834 : process_all_all_constraints (lhsc, rhsc);
4801 : : }
4802 : 15482 : return true;
4803 : 15482 : }
4804 : : break;
4805 : : /* String / character search functions return a pointer into the
4806 : : source string or NULL. */
4807 : 10758 : case BUILT_IN_INDEX:
4808 : 10758 : case BUILT_IN_STRCHR:
4809 : 10758 : case BUILT_IN_STRRCHR:
4810 : 10758 : case BUILT_IN_MEMCHR:
4811 : 10758 : case BUILT_IN_STRSTR:
4812 : 10758 : case BUILT_IN_STRPBRK:
4813 : 10758 : if (gimple_call_lhs (t))
4814 : : {
4815 : 10758 : tree src = gimple_call_arg (t, 0);
4816 : 10758 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
4817 : 10758 : constraint_expr nul;
4818 : 10758 : nul.var = nothing_id;
4819 : 10758 : nul.offset = 0;
4820 : 10758 : nul.type = ADDRESSOF;
4821 : 10758 : rhsc.safe_push (nul);
4822 : 10758 : get_constraint_for (gimple_call_lhs (t), &lhsc);
4823 : 10758 : process_all_all_constraints (lhsc, rhsc);
4824 : : }
4825 : 10758 : 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 : 662643 : case BUILT_IN_STRCMP:
4830 : 662643 : case BUILT_IN_STRCMP_EQ:
4831 : 662643 : case BUILT_IN_STRNCMP:
4832 : 662643 : case BUILT_IN_STRNCMP_EQ:
4833 : 662643 : case BUILT_IN_STRCASECMP:
4834 : 662643 : case BUILT_IN_STRNCASECMP:
4835 : 662643 : case BUILT_IN_MEMCMP:
4836 : 662643 : case BUILT_IN_BCMP:
4837 : 662643 : case BUILT_IN_STRSPN:
4838 : 662643 : case BUILT_IN_STRCSPN:
4839 : 662643 : {
4840 : 662643 : varinfo_t uses = get_call_use_vi (t);
4841 : 662643 : make_any_offset_constraints (uses);
4842 : 662643 : make_constraint_to (uses->id, gimple_call_arg (t, 0));
4843 : 662643 : make_constraint_to (uses->id, gimple_call_arg (t, 1));
4844 : : /* No constraints are necessary for the return value. */
4845 : 662643 : return true;
4846 : : }
4847 : 47778 : case BUILT_IN_STRLEN:
4848 : 47778 : {
4849 : 47778 : varinfo_t uses = get_call_use_vi (t);
4850 : 47778 : make_any_offset_constraints (uses);
4851 : 47778 : make_constraint_to (uses->id, gimple_call_arg (t, 0));
4852 : : /* No constraints are necessary for the return value. */
4853 : 47778 : 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 : 498 : case BUILT_IN_INIT_TRAMPOLINE:
4865 : 498 : {
4866 : 498 : tree tramp = gimple_call_arg (t, 0);
4867 : 498 : tree nfunc = gimple_call_arg (t, 1);
4868 : 498 : tree frame = gimple_call_arg (t, 2);
4869 : 498 : unsigned i;
4870 : 498 : struct constraint_expr lhs, *rhsp;
4871 : 498 : 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 : 491 : break;
4897 : : }
4898 : 533 : case BUILT_IN_ADJUST_TRAMPOLINE:
4899 : 533 : {
4900 : 533 : tree tramp = gimple_call_arg (t, 0);
4901 : 533 : tree res = gimple_call_lhs (t);
4902 : 533 : 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 : 533 : 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 : 19802 : case BUILT_IN_VA_START:
4954 : 19802 : {
4955 : 19802 : tree valist = gimple_call_arg (t, 0);
4956 : 19802 : struct constraint_expr rhs, *lhsp;
4957 : 19802 : unsigned i;
4958 : 19802 : get_constraint_for_ptr_offset (valist, NULL_TREE, &lhsc);
4959 : 19802 : 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 : 19802 : 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 : 39771 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
4976 : 19969 : process_constraint (new_constraint (*lhsp, rhs));
4977 : : /* va_list is clobbered. */
4978 : 19802 : make_constraint_to (get_call_clobber_vi (t)->id, valist);
4979 : 19802 : 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 : 940 : case BUILT_IN_RETURN:
4986 : 940 : {
4987 : 940 : fi = NULL;
4988 : 940 : if (!in_ipa_mode
4989 : 940 : || !(fi = get_vi_for_tree (fn->decl)))
4990 : 940 : 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 : 940 : return true;
5002 : : }
5003 : 54706 : case BUILT_IN_GOMP_PARALLEL:
5004 : 54706 : case BUILT_IN_GOACC_PARALLEL:
5005 : 54706 : {
5006 : 54706 : if (in_ipa_mode)
5007 : : {
5008 : 13762 : unsigned int fnpos, argpos;
5009 : 13762 : 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 : 13749 : case BUILT_IN_GOACC_PARALLEL:
5017 : : /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs,
5018 : : sizes, kinds, ...). */
5019 : 13749 : fnpos = 1;
5020 : 13749 : argpos = 3;
5021 : 13749 : break;
5022 : 0 : default:
5023 : 0 : gcc_unreachable ();
5024 : : }
5025 : :
5026 : 13762 : tree fnarg = gimple_call_arg (t, fnpos);
5027 : 13762 : gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR);
5028 : 13762 : tree fndecl = TREE_OPERAND (fnarg, 0);
5029 : 13762 : if (fndecl_maybe_in_other_partition (fndecl))
5030 : : /* Fallthru to general call handling. */
5031 : : break;
5032 : :
5033 : 13719 : tree arg = gimple_call_arg (t, argpos);
5034 : :
5035 : 13719 : varinfo_t fi = get_vi_for_tree (fndecl);
5036 : 13719 : find_func_aliases_for_call_arg (fi, 0, arg);
5037 : 13719 : 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 : 4972931 : }
5051 : :
5052 : : /* Create constraints for the call T. */
5053 : :
5054 : : static void
5055 : 17444735 : find_func_aliases_for_call (struct function *fn, gcall *t)
5056 : : {
5057 : 17444735 : tree fndecl = gimple_call_fndecl (t);
5058 : 17444735 : varinfo_t fi;
5059 : :
5060 : 17444735 : if (fndecl != NULL_TREE
5061 : 16390314 : && fndecl_built_in_p (fndecl)
5062 : 22417666 : && find_func_aliases_for_builtin_call (fn, t))
5063 : : return;
5064 : :
5065 : 16142793 : if (gimple_call_internal_p (t, IFN_DEFERRED_INIT))
5066 : : return;
5067 : :
5068 : 16142258 : fi = get_fi_for_callee (t);
5069 : 16142258 : if (!in_ipa_mode
5070 : 236018 : || (fi->decl && fndecl && !fi->is_fn_info))
5071 : : {
5072 : 15959941 : auto_vec<ce_s, 16> rhsc;
5073 : 15959941 : 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 : 15959941 : if (flags & (ECF_CONST|ECF_NOVOPS))
5078 : : {
5079 : 1517584 : if (gimple_call_lhs (t))
5080 : 918652 : 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 : 14442357 : else if (flags & (ECF_PURE|ECF_LOOPING_CONST_OR_PURE))
5086 : 535336 : 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 : 13907021 : else if (fndecl
5092 : 13291973 : && DECL_IS_OPERATOR_DELETE_P (fndecl)
5093 : 14224443 : && gimple_call_from_new_or_delete (t))
5094 : : ;
5095 : : else
5096 : 13594554 : handle_rhs_call (t, &rhsc, 0, true, true);
5097 : 15959941 : if (gimple_call_lhs (t))
5098 : 5800096 : handle_lhs_call (t, gimple_call_lhs (t),
5099 : : gimple_call_return_flags (t), rhsc, fndecl);
5100 : 15959941 : }
5101 : : else
5102 : : {
5103 : 182317 : auto_vec<ce_s, 2> rhsc;
5104 : 182317 : tree lhsop;
5105 : 182317 : unsigned j;
5106 : :
5107 : : /* Assign all the passed arguments to the appropriate incoming
5108 : : parameters of the function. */
5109 : 973280 : for (j = 0; j < gimple_call_num_args (t); j++)
5110 : : {
5111 : 790963 : tree arg = gimple_call_arg (t, j);
5112 : 790963 : find_func_aliases_for_call_arg (fi, j, arg);
5113 : : }
5114 : :
5115 : : /* If we are returning a value, assign it to the result. */
5116 : 182317 : lhsop = gimple_call_lhs (t);
5117 : 182317 : if (lhsop)
5118 : : {
5119 : 162281 : auto_vec<ce_s, 2> lhsc;
5120 : 162281 : struct constraint_expr rhs;
5121 : 162281 : struct constraint_expr *lhsp;
5122 : 163133 : bool aggr_p = aggregate_value_p (lhsop, gimple_call_fntype (t));
5123 : :
5124 : 162281 : get_constraint_for (lhsop, &lhsc);
5125 : 162281 : rhs = get_function_part_constraint (fi, fi_result);
5126 : 162281 : if (aggr_p)
5127 : : {
5128 : 10 : auto_vec<ce_s, 2> tem;
5129 : 10 : tem.quick_push (rhs);
5130 : 10 : do_deref (&tem);
5131 : 10 : gcc_checking_assert (tem.length () == 1);
5132 : 10 : rhs = tem[0];
5133 : 10 : }
5134 : 324565 : FOR_EACH_VEC_ELT (lhsc, j, lhsp)
5135 : 162284 : process_constraint (new_constraint (*lhsp, rhs));
5136 : :
5137 : : /* If we pass the result decl by reference, honor that. */
5138 : 162281 : if (aggr_p)
5139 : : {
5140 : 10 : struct constraint_expr lhs;
5141 : 10 : struct constraint_expr *rhsp;
5142 : :
5143 : 10 : get_constraint_for_address_of (lhsop, &rhsc);
5144 : 10 : lhs = get_function_part_constraint (fi, fi_result);
5145 : 30 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
5146 : 10 : process_constraint (new_constraint (lhs, *rhsp));
5147 : 10 : rhsc.truncate (0);
5148 : : }
5149 : 162281 : }
5150 : :
5151 : : /* If we use a static chain, pass it along. */
5152 : 182317 : if (gimple_call_chain (t))
5153 : : {
5154 : 278 : struct constraint_expr lhs;
5155 : 278 : struct constraint_expr *rhsp;
5156 : :
5157 : 278 : get_constraint_for (gimple_call_chain (t), &rhsc);
5158 : 278 : lhs = get_function_part_constraint (fi, fi_static_chain);
5159 : 1112 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
5160 : 278 : process_constraint (new_constraint (lhs, *rhsp));
5161 : : }
5162 : 182317 : }
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 : 256184524 : find_func_aliases (struct function *fn, gimple *origt)
5172 : : {
5173 : 256184524 : gimple *t = origt;
5174 : 256184524 : auto_vec<ce_s, 16> lhsc;
5175 : 256184524 : auto_vec<ce_s, 16> rhsc;
5176 : 256184524 : varinfo_t fi;
5177 : :
5178 : : /* Now build constraints expressions. */
5179 : 256184524 : if (gimple_code (t) == GIMPLE_PHI)
5180 : : {
5181 : : /* For a phi node, assign all the arguments to
5182 : : the result. */
5183 : 6381863 : get_constraint_for (gimple_phi_result (t), &lhsc);
5184 : 21312015 : for (unsigned i = 0; i < gimple_phi_num_args (t); i++)
5185 : : {
5186 : 14930152 : get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc);
5187 : 14930152 : process_all_all_constraints (lhsc, rhsc);
5188 : 14930152 : 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 : 249802661 : else if (is_gimple_call (t))
5199 : 17444735 : 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 : 232357926 : else if (is_gimple_assign (t))
5205 : : {
5206 : : /* Otherwise, just a regular assignment statement. */
5207 : 80647964 : tree lhsop = gimple_assign_lhs (t);
5208 : 80647964 : tree rhsop = (gimple_num_ops (t) == 2) ? gimple_assign_rhs1 (t) : NULL;
5209 : :
5210 : 63164159 : if (rhsop && TREE_CLOBBER_P (rhsop))
5211 : : /* Ignore clobbers, they don't actually store anything into
5212 : : the LHS. */
5213 : : ;
5214 : 57015515 : else if (rhsop && AGGREGATE_TYPE_P (TREE_TYPE (lhsop)))
5215 : 2805965 : do_structure_copy (lhsop, rhsop);
5216 : : else
5217 : : {
5218 : 71693355 : enum tree_code code = gimple_assign_rhs_code (t);
5219 : :
5220 : 71693355 : get_constraint_for (lhsop, &lhsc);
5221 : :
5222 : 71693355 : if (code == POINTER_PLUS_EXPR)
5223 : 2653209 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
5224 : : gimple_assign_rhs2 (t), &rhsc);
5225 : 69040146 : else if (code == POINTER_DIFF_EXPR)
5226 : : /* The result is not a pointer (part). */
5227 : : ;
5228 : 68698175 : else if (code == BIT_AND_EXPR
5229 : 68698175 : && 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 : 646799 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
5234 : : NULL_TREE, &rhsc);
5235 : : }
5236 : 68051376 : else if (code == TRUNC_DIV_EXPR
5237 : : || code == CEIL_DIV_EXPR
5238 : : || code == FLOOR_DIV_EXPR
5239 : 68051376 : || code == ROUND_DIV_EXPR
5240 : 68051376 : || code == EXACT_DIV_EXPR
5241 : : || code == TRUNC_MOD_EXPR
5242 : 67657027 : || code == CEIL_MOD_EXPR
5243 : : || code == FLOOR_MOD_EXPR
5244 : 67474834 : || code == ROUND_MOD_EXPR)
5245 : : /* Division and modulo transfer the pointer from the LHS. */
5246 : 577678 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
5247 : : NULL_TREE, &rhsc);
5248 : 67473698 : else if (CONVERT_EXPR_CODE_P (code)
5249 : 67473698 : || gimple_assign_single_p (t))
5250 : : /* See through conversions, single RHS are handled by
5251 : : get_constraint_for_rhs. */
5252 : 53512560 : get_constraint_for_rhs (rhsop, &rhsc);
5253 : 13961138 : else if (code == COND_EXPR)
5254 : : {
5255 : : /* The result is a merge of both COND_EXPR arms. */
5256 : 9908 : auto_vec<ce_s, 2> tmp;
5257 : 9908 : struct constraint_expr *rhsp;
5258 : 9908 : unsigned i;
5259 : 9908 : get_constraint_for_rhs (gimple_assign_rhs2 (t), &rhsc);
5260 : 9908 : get_constraint_for_rhs (gimple_assign_rhs3 (t), &tmp);
5261 : 39632 : FOR_EACH_VEC_ELT (tmp, i, rhsp)
5262 : 9908 : rhsc.safe_push (*rhsp);
5263 : 9908 : }
5264 : 13951230 : 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 : 12551015 : auto_vec<ce_s, 4> tmp;
5272 : 12551015 : struct constraint_expr *rhsp;
5273 : 12551015 : unsigned i, j;
5274 : 12551015 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
5275 : : NULL_TREE, &rhsc);
5276 : 37043821 : for (i = 2; i < gimple_num_ops (t); ++i)
5277 : : {
5278 : 11941791 : get_constraint_for_ptr_offset (gimple_op (t, i),
5279 : : NULL_TREE, &tmp);
5280 : 35825373 : FOR_EACH_VEC_ELT (tmp, j, rhsp)
5281 : 11941791 : rhsc.safe_push (*rhsp);
5282 : 11941791 : tmp.truncate (0);
5283 : : }
5284 : 12551015 : }
5285 : 71693355 : process_all_all_constraints (lhsc, rhsc);
5286 : : }
5287 : : /* If there is a store to a global variable the rhs escapes. */
5288 : 80647964 : if ((lhsop = get_base_address (lhsop)) != NULL_TREE
5289 : 80647964 : && DECL_P (lhsop))
5290 : : {
5291 : 22984802 : varinfo_t vi = get_vi_for_tree (lhsop);
5292 : 22984802 : if ((! in_ipa_mode && vi->is_global_var)
5293 : 21389374 : || vi->is_ipa_escape_point)
5294 : 1598040 : make_escape_constraint (rhsop);
5295 : : }
5296 : : }
5297 : : /* Handle escapes through return. */
5298 : 151709962 : else if (gimple_code (t) == GIMPLE_RETURN
5299 : 151709962 : && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE)
5300 : : {
5301 : 2442734 : greturn *return_stmt = as_a <greturn *> (t);
5302 : 2442734 : tree retval = gimple_return_retval (return_stmt);
5303 : 2442734 : if (!in_ipa_mode)
5304 : 2438490 : make_constraint_to (escaped_return_id, retval);
5305 : : else
5306 : : {
5307 : 4244 : struct constraint_expr lhs ;
5308 : 4244 : struct constraint_expr *rhsp;
5309 : 4244 : unsigned i;
5310 : :
5311 : 4244 : fi = lookup_vi_for_tree (fn->decl);
5312 : 4244 : lhs = get_function_part_constraint (fi, fi_result);
5313 : 4244 : get_constraint_for_rhs (retval, &rhsc);
5314 : 16976 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
5315 : 4244 : process_constraint (new_constraint (lhs, *rhsp));
5316 : : }
5317 : : }
5318 : : /* Handle asms conservatively by adding escape constraints to everything. */
5319 : 256418164 : else if (gasm *asm_stmt = dyn_cast <gasm *> (t))
5320 : : {
5321 : 233640 : unsigned i, noutputs;
5322 : 233640 : const char **oconstraints;
5323 : 233640 : const char *constraint;
5324 : 233640 : bool allows_mem, allows_reg, is_inout;
5325 : :
5326 : 233640 : noutputs = gimple_asm_noutputs (asm_stmt);
5327 : 233640 : oconstraints = XALLOCAVEC (const char *, noutputs);
5328 : :
5329 : 456239 : for (i = 0; i < noutputs; ++i)
5330 : : {
5331 : 222599 : tree link = gimple_asm_output_op (asm_stmt, i);
5332 : 222599 : tree op = TREE_VALUE (link);
5333 : :
5334 : 222599 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
5335 : 222599 : oconstraints[i] = constraint;
5336 : 222599 : 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 : 222599 : if (!allows_reg && allows_mem)
5341 : : {
5342 : 10911 : auto_vec<ce_s> tmpc;
5343 : 10911 : get_constraint_for_address_of (op, &tmpc);
5344 : 10911 : make_constraints_to (escaped_id, tmpc);
5345 : 10911 : }
5346 : :
5347 : : /* The asm may read global memory, so outputs may point to
5348 : : any global memory. */
5349 : 222599 : if (op)
5350 : : {
5351 : 222599 : auto_vec<ce_s, 2> lhsc;
5352 : 222599 : struct constraint_expr rhsc, *lhsp;
5353 : 222599 : unsigned j;
5354 : 222599 : get_constraint_for (op, &lhsc);
5355 : 222599 : rhsc.var = nonlocal_id;
5356 : 222599 : rhsc.offset = 0;
5357 : 222599 : rhsc.type = SCALAR;
5358 : 890399 : FOR_EACH_VEC_ELT (lhsc, j, lhsp)
5359 : 222602 : process_constraint (new_constraint (*lhsp, rhsc));
5360 : 222599 : }
5361 : : }
5362 : 373248 : for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
5363 : : {
5364 : 139608 : tree link = gimple_asm_input_op (asm_stmt, i);
5365 : 139608 : tree op = TREE_VALUE (link);
5366 : :
5367 : 139608 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
5368 : :
5369 : 139608 : 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 : 139608 : if (!allows_reg && allows_mem)
5374 : : {
5375 : 12101 : auto_vec<ce_s> tmpc;
5376 : 12101 : get_constraint_for_address_of (op, &tmpc);
5377 : 12101 : make_constraints_to (escaped_id, tmpc);
5378 : 12101 : }
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 : 127507 : else if (op)
5383 : 127507 : make_escape_constraint (op);
5384 : : }
5385 : : }
5386 : 256184524 : }
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 : 953808 : find_func_clobbers (struct function *fn, gimple *origt)
5411 : : {
5412 : 953808 : gimple *t = origt;
5413 : 953808 : auto_vec<ce_s, 16> lhsc;
5414 : 953808 : auto_vec<ce_s, 16> rhsc;
5415 : 953808 : 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 : 953808 : gcc_assert (in_ipa_mode);
5422 : :
5423 : : /* If the stmt refers to memory in any way it better had a VUSE. */
5424 : 2035160 : if (gimple_vuse (t) == NULL_TREE)
5425 : : return;
5426 : :
5427 : : /* We'd better have function information for the current function. */
5428 : 624115 : fi = lookup_vi_for_tree (fn->decl);
5429 : 624115 : gcc_assert (fi != NULL);
5430 : :
5431 : : /* Account for stores in assignments and calls. */
5432 : 624115 : if (gimple_vdef (t) != NULL_TREE
5433 : 820459 : && gimple_has_lhs (t))
5434 : : {
5435 : 327992 : tree lhs = gimple_get_lhs (t);
5436 : 327992 : tree tem = lhs;
5437 : 828752 : while (handled_component_p (tem))
5438 : 172768 : tem = TREE_OPERAND (tem, 0);
5439 : 327992 : if ((DECL_P (tem)
5440 : 186241 : && !auto_var_in_fn_p (tem, fn->decl))
5441 : 323029 : || INDIRECT_REF_P (tem)
5442 : 651021 : || (TREE_CODE (tem) == MEM_REF
5443 : 29544 : && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
5444 : : && auto_var_in_fn_p
5445 : 4069 : (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl))))
5446 : : {
5447 : 27161 : struct constraint_expr lhsc, *rhsp;
5448 : 27161 : unsigned i;
5449 : 27161 : lhsc = get_function_part_constraint (fi, fi_clobbers);
5450 : 27161 : get_constraint_for_address_of (lhs, &rhsc);
5451 : 81483 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
5452 : 27161 : process_constraint (new_constraint (lhsc, *rhsp));
5453 : 27161 : rhsc.truncate (0);
5454 : : }
5455 : : }
5456 : :
5457 : : /* Account for uses in assigments and returns. */
5458 : 624115 : if (gimple_assign_single_p (t)
5459 : 624115 : || (gimple_code (t) == GIMPLE_RETURN
5460 : 22969 : && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE))
5461 : : {
5462 : 355895 : tree rhs = (gimple_assign_single_p (t)
5463 : 355895 : ? gimple_assign_rhs1 (t)
5464 : 4244 : : gimple_return_retval (as_a <greturn *> (t)));
5465 : 355895 : tree tem = rhs;
5466 : 510124 : while (handled_component_p (tem))
5467 : 154229 : tem = TREE_OPERAND (tem, 0);
5468 : 355895 : if ((DECL_P (tem)
5469 : 53069 : && !auto_var_in_fn_p (tem, fn->decl))
5470 : 347270 : || INDIRECT_REF_P (tem)
5471 : 703165 : || (TREE_CODE (tem) == MEM_REF
5472 : 88583 : && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
5473 : : && auto_var_in_fn_p
5474 : 1184 : (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl))))
5475 : : {
5476 : 95402 : struct constraint_expr lhs, *rhsp;
5477 : 95402 : unsigned i;
5478 : 95402 : lhs = get_function_part_constraint (fi, fi_uses);
5479 : 95402 : get_constraint_for_address_of (rhs, &rhsc);
5480 : 286206 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
5481 : 95402 : process_constraint (new_constraint (lhs, *rhsp));
5482 : 95402 : rhsc.truncate (0);
5483 : : }
5484 : : }
5485 : :
5486 : 624115 : if (gcall *call_stmt = dyn_cast <gcall *> (t))
5487 : : {
5488 : 249453 : varinfo_t cfi = NULL;
5489 : 249453 : tree decl = gimple_call_fndecl (t);
5490 : 249453 : struct constraint_expr lhs, rhs;
5491 : 249453 : 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 : 249453 : if (gimple_call_builtin_p (t, BUILT_IN_NORMAL))
5496 : 36152 : 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 : 890 : case BUILT_IN_MEMSET:
5539 : 890 : case BUILT_IN_MEMSET_CHK:
5540 : 890 : case BUILT_IN_POSIX_MEMALIGN:
5541 : 890 : {
5542 : 890 : tree dest = gimple_call_arg (t, 0);
5543 : 890 : unsigned i;
5544 : 890 : ce_s *lhsp;
5545 : 890 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
5546 : 890 : lhs = get_function_part_constraint (fi, fi_clobbers);
5547 : 2670 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
5548 : 890 : 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 use what their first argument
5587 : : points to. */
5588 : 50 : case BUILT_IN_STRDUP:
5589 : 50 : case BUILT_IN_STRNDUP:
5590 : 50 : case BUILT_IN_REALLOC:
5591 : 50 : case BUILT_IN_INDEX:
5592 : 50 : case BUILT_IN_STRCHR:
5593 : 50 : case BUILT_IN_STRRCHR:
5594 : 50 : case BUILT_IN_MEMCHR:
5595 : 50 : {
5596 : 50 : tree src = gimple_call_arg (t, 0);
5597 : 50 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
5598 : 50 : lhs = get_function_part_constraint (fi, fi_uses);
5599 : 50 : struct constraint_expr *rhsp;
5600 : 150 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
5601 : 50 : process_constraint (new_constraint (lhs, *rhsp));
5602 : : return;
5603 : : }
5604 : : /* The following functions use what their first and second argument
5605 : : point to. */
5606 : 16 : case BUILT_IN_STRSTR:
5607 : 16 : case BUILT_IN_STRPBRK:
5608 : 16 : {
5609 : 16 : tree src = gimple_call_arg (t, 0);
5610 : 16 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
5611 : 16 : lhs = get_function_part_constraint (fi, fi_uses);
5612 : 16 : struct constraint_expr *rhsp;
5613 : 48 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
5614 : 16 : process_constraint (new_constraint (lhs, *rhsp));
5615 : 16 : rhsc.truncate (0);
5616 : 16 : src = gimple_call_arg (t, 1);
5617 : 16 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
5618 : 242784 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
5619 : 16 : process_constraint (new_constraint (lhs, *rhsp));
5620 : : return;
5621 : : }
5622 : : /* The following functions neither read nor clobber memory. */
5623 : : case BUILT_IN_ASSUME_ALIGNED:
5624 : : case BUILT_IN_FREE:
5625 : : return;
5626 : : /* Trampolines are of no interest to us. */
5627 : : case BUILT_IN_INIT_TRAMPOLINE:
5628 : : case BUILT_IN_ADJUST_TRAMPOLINE:
5629 : : return;
5630 : : case BUILT_IN_VA_START:
5631 : : case BUILT_IN_VA_END:
5632 : : return;
5633 : 13762 : case BUILT_IN_GOMP_PARALLEL:
5634 : 13762 : case BUILT_IN_GOACC_PARALLEL:
5635 : 13762 : {
5636 : 13762 : unsigned int fnpos, argpos;
5637 : 13762 : unsigned int implicit_use_args[2];
5638 : 13762 : unsigned int num_implicit_use_args = 0;
5639 : 13762 : switch (DECL_FUNCTION_CODE (decl))
5640 : : {
5641 : : case BUILT_IN_GOMP_PARALLEL:
5642 : : /* __builtin_GOMP_parallel (fn, data, num_threads, flags). */
5643 : : fnpos = 0;
5644 : : argpos = 1;
5645 : : break;
5646 : 13749 : case BUILT_IN_GOACC_PARALLEL:
5647 : : /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs,
5648 : : sizes, kinds, ...). */
5649 : 13749 : fnpos = 1;
5650 : 13749 : argpos = 3;
5651 : 13749 : implicit_use_args[num_implicit_use_args++] = 4;
5652 : 13749 : implicit_use_args[num_implicit_use_args++] = 5;
5653 : 13749 : break;
5654 : 0 : default:
5655 : 0 : gcc_unreachable ();
5656 : : }
5657 : :
5658 : 13762 : tree fnarg = gimple_call_arg (t, fnpos);
5659 : 13762 : gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR);
5660 : 13762 : tree fndecl = TREE_OPERAND (fnarg, 0);
5661 : 13762 : if (fndecl_maybe_in_other_partition (fndecl))
5662 : : /* Fallthru to general call handling. */
5663 : : break;
5664 : :
5665 : 13719 : varinfo_t cfi = get_vi_for_tree (fndecl);
5666 : :
5667 : 13719 : tree arg = gimple_call_arg (t, argpos);
5668 : :
5669 : : /* Parameter passed by value is used. */
5670 : 13719 : lhs = get_function_part_constraint (fi, fi_uses);
5671 : 13719 : struct constraint_expr *rhsp;
5672 : 13719 : get_constraint_for (arg, &rhsc);
5673 : 41157 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
5674 : 13719 : process_constraint (new_constraint (lhs, *rhsp));
5675 : 13719 : rhsc.truncate (0);
5676 : :
5677 : : /* Handle parameters used by the call, but not used in cfi, as
5678 : : implicitly used by cfi. */
5679 : 13719 : lhs = get_function_part_constraint (cfi, fi_uses);
5680 : 41137 : for (unsigned i = 0; i < num_implicit_use_args; ++i)
5681 : : {
5682 : 27418 : tree arg = gimple_call_arg (t, implicit_use_args[i]);
5683 : 27418 : get_constraint_for (arg, &rhsc);
5684 : 82254 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
5685 : 27418 : process_constraint (new_constraint (lhs, *rhsp));
5686 : 27418 : rhsc.truncate (0);
5687 : : }
5688 : :
5689 : : /* The caller clobbers what the callee does. */
5690 : 13719 : lhs = get_function_part_constraint (fi, fi_clobbers);
5691 : 13719 : rhs = get_function_part_constraint (cfi, fi_clobbers);
5692 : 13719 : process_constraint (new_constraint (lhs, rhs));
5693 : :
5694 : : /* The caller uses what the callee does. */
5695 : 13719 : lhs = get_function_part_constraint (fi, fi_uses);
5696 : 13719 : rhs = get_function_part_constraint (cfi, fi_uses);
5697 : 13719 : process_constraint (new_constraint (lhs, rhs));
5698 : :
5699 : 13719 : return;
5700 : : }
5701 : : /* printf-style functions may have hooks to set pointers to
5702 : : point to somewhere into the generated string. Leave them
5703 : : for a later exercise... */
5704 : : default:
5705 : : /* Fallthru to general call handling. */;
5706 : : }
5707 : :
5708 : : /* Parameters passed by value are used. */
5709 : 232696 : lhs = get_function_part_constraint (fi, fi_uses);
5710 : 1142970 : for (i = 0; i < gimple_call_num_args (t); i++)
5711 : : {
5712 : 910274 : struct constraint_expr *rhsp;
5713 : 910274 : tree arg = gimple_call_arg (t, i);
5714 : :
5715 : 1800627 : if (TREE_CODE (arg) == SSA_NAME
5716 : 910274 : || is_gimple_min_invariant (arg))
5717 : 890353 : continue;
5718 : :
5719 : 19921 : get_constraint_for_address_of (arg, &rhsc);
5720 : 59764 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
5721 : 19922 : process_constraint (new_constraint (lhs, *rhsp));
5722 : 19921 : rhsc.truncate (0);
5723 : : }
5724 : :
5725 : : /* Build constraints for propagating clobbers/uses along the
5726 : : callgraph edges. */
5727 : 232696 : cfi = get_fi_for_callee (call_stmt);
5728 : 232696 : if (cfi->id == anything_id)
5729 : : {
5730 : 346782 : if (gimple_vdef (t))
5731 : 121547 : make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
5732 : : anything_id);
5733 : 173391 : make_constraint_from (first_vi_for_offset (fi, fi_uses),
5734 : : anything_id);
5735 : 173391 : return;
5736 : : }
5737 : :
5738 : : /* For callees without function info (that's external functions),
5739 : : ESCAPED is clobbered and used. */
5740 : 59305 : if (cfi->decl
5741 : 59304 : && TREE_CODE (cfi->decl) == FUNCTION_DECL
5742 : 58626 : && !cfi->is_fn_info)
5743 : : {
5744 : 52588 : varinfo_t vi;
5745 : :
5746 : 105176 : if (gimple_vdef (t))
5747 : 52353 : make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
5748 : : escaped_id);
5749 : 52588 : make_copy_constraint (first_vi_for_offset (fi, fi_uses), escaped_id);
5750 : :
5751 : : /* Also honor the call statement use/clobber info. */
5752 : 52588 : if ((vi = lookup_call_clobber_vi (call_stmt)) != NULL)
5753 : 52312 : make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
5754 : 52312 : vi->id);
5755 : 52588 : if ((vi = lookup_call_use_vi (call_stmt)) != NULL)
5756 : 52312 : make_copy_constraint (first_vi_for_offset (fi, fi_uses),
5757 : 52312 : vi->id);
5758 : 52588 : return;
5759 : : }
5760 : :
5761 : : /* Otherwise the caller clobbers and uses what the callee does.
5762 : : ??? This should use a new complex constraint that filters
5763 : : local variables of the callee. */
5764 : 13434 : if (gimple_vdef (t))
5765 : : {
5766 : 5703 : lhs = get_function_part_constraint (fi, fi_clobbers);
5767 : 5703 : rhs = get_function_part_constraint (cfi, fi_clobbers);
5768 : 5703 : process_constraint (new_constraint (lhs, rhs));
5769 : : }
5770 : 6717 : lhs = get_function_part_constraint (fi, fi_uses);
5771 : 6717 : rhs = get_function_part_constraint (cfi, fi_uses);
5772 : 6717 : process_constraint (new_constraint (lhs, rhs));
5773 : : }
5774 : 374662 : else if (gimple_code (t) == GIMPLE_ASM)
5775 : : {
5776 : : /* ??? Ick. We can do better. */
5777 : 42 : if (gimple_vdef (t))
5778 : 42 : make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
5779 : : anything_id);
5780 : 42 : make_constraint_from (first_vi_for_offset (fi, fi_uses),
5781 : : anything_id);
5782 : : }
5783 : 953808 : }
5784 : :
5785 : :
5786 : : /* Find the first varinfo in the same variable as START that overlaps with
5787 : : OFFSET. Return NULL if we can't find one. */
5788 : :
5789 : : static varinfo_t
5790 : 1060704 : first_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset)
5791 : : {
5792 : : /* If the offset is outside of the variable, bail out. */
5793 : 1060704 : if (offset >= start->fullsize)
5794 : : return NULL;
5795 : :
5796 : : /* If we cannot reach offset from start, lookup the first field
5797 : : and start from there. */
5798 : 1055961 : if (start->offset > offset)
5799 : 0 : start = get_varinfo (start->head);
5800 : :
5801 : 2959577 : while (start)
5802 : : {
5803 : : /* We may not find a variable in the field list with the actual
5804 : : offset when we have glommed a structure to a variable.
5805 : : In that case, however, offset should still be within the size
5806 : : of the variable. */
5807 : 2959577 : if (offset >= start->offset
5808 : 2959577 : && (offset - start->offset) < start->size)
5809 : : return start;
5810 : :
5811 : 1903616 : start = vi_next (start);
5812 : : }
5813 : :
5814 : : return NULL;
5815 : : }
5816 : :
5817 : : /* Find the first varinfo in the same variable as START that overlaps with
5818 : : OFFSET. If there is no such varinfo the varinfo directly preceding
5819 : : OFFSET is returned. */
5820 : :
5821 : : static varinfo_t
5822 : 17363386 : first_or_preceding_vi_for_offset (varinfo_t start,
5823 : : unsigned HOST_WIDE_INT offset)
5824 : : {
5825 : : /* If we cannot reach offset from start, lookup the first field
5826 : : and start from there. */
5827 : 17363386 : if (start->offset > offset)
5828 : 292309 : start = get_varinfo (start->head);
5829 : :
5830 : : /* We may not find a variable in the field list with the actual
5831 : : offset when we have glommed a structure to a variable.
5832 : : In that case, however, offset should still be within the size
5833 : : of the variable.
5834 : : If we got beyond the offset we look for return the field
5835 : : directly preceding offset which may be the last field. */
5836 : 64999024 : while (start->next
5837 : 55397811 : && offset >= start->offset
5838 : 120390795 : && !((offset - start->offset) < start->size))
5839 : 47635638 : start = vi_next (start);
5840 : :
5841 : 17363386 : return start;
5842 : : }
5843 : :
5844 : :
5845 : : /* This structure is used during pushing fields onto the fieldstack
5846 : : to track the offset of the field, since bitpos_of_field gives it
5847 : : relative to its immediate containing type, and we want it relative
5848 : : to the ultimate containing object. */
5849 : :
5850 : : struct fieldoff
5851 : : {
5852 : : /* Offset from the base of the base containing object to this field. */
5853 : : HOST_WIDE_INT offset;
5854 : :
5855 : : /* Size, in bits, of the field. */
5856 : : unsigned HOST_WIDE_INT size;
5857 : :
5858 : : unsigned has_unknown_size : 1;
5859 : :
5860 : : unsigned must_have_pointers : 1;
5861 : :
5862 : : unsigned may_have_pointers : 1;
5863 : :
5864 : : unsigned only_restrict_pointers : 1;
5865 : :
5866 : : tree restrict_pointed_type;
5867 : : };
5868 : : typedef struct fieldoff fieldoff_s;
5869 : :
5870 : :
5871 : : /* qsort comparison function for two fieldoff's PA and PB */
5872 : :
5873 : : static int
5874 : 188226412 : fieldoff_compare (const void *pa, const void *pb)
5875 : : {
5876 : 188226412 : const fieldoff_s *foa = (const fieldoff_s *)pa;
5877 : 188226412 : const fieldoff_s *fob = (const fieldoff_s *)pb;
5878 : 188226412 : unsigned HOST_WIDE_INT foasize, fobsize;
5879 : :
5880 : 188226412 : if (foa->offset < fob->offset)
5881 : : return -1;
5882 : 98178433 : else if (foa->offset > fob->offset)
5883 : : return 1;
5884 : :
5885 : 1332836 : foasize = foa->size;
5886 : 1332836 : fobsize = fob->size;
5887 : 1332836 : if (foasize < fobsize)
5888 : : return -1;
5889 : 1111891 : else if (foasize > fobsize)
5890 : 127431 : return 1;
5891 : : return 0;
5892 : : }
5893 : :
5894 : : /* Sort a fieldstack according to the field offset and sizes. */
5895 : : static void
5896 : 7722520 : sort_fieldstack (vec<fieldoff_s> &fieldstack)
5897 : : {
5898 : 7722520 : fieldstack.qsort (fieldoff_compare);
5899 : 7722520 : }
5900 : :
5901 : : /* Return true if T is a type that can have subvars. */
5902 : :
5903 : : static inline bool
5904 : 66111347 : type_can_have_subvars (const_tree t)
5905 : : {
5906 : : /* Aggregates without overlapping fields can have subvars. */
5907 : 5791003 : return TREE_CODE (t) == RECORD_TYPE;
5908 : : }
5909 : :
5910 : : /* Return true if V is a tree that we can have subvars for.
5911 : : Normally, this is any aggregate type. Also complex
5912 : : types which are not gimple registers can have subvars. */
5913 : :
5914 : : static inline bool
5915 : 120646244 : var_can_have_subvars (const_tree v)
5916 : : {
5917 : : /* Volatile variables should never have subvars. */
5918 : 120646244 : if (TREE_THIS_VOLATILE (v))
5919 : : return false;
5920 : :
5921 : : /* Non decls or memory tags can never have subvars. */
5922 : 120355686 : if (!DECL_P (v))
5923 : : return false;
5924 : :
5925 : 60320344 : return type_can_have_subvars (TREE_TYPE (v));
5926 : : }
5927 : :
5928 : : /* Return true if T is a type that does contain pointers. */
5929 : :
5930 : : static bool
5931 : 34017640 : type_must_have_pointers (tree type)
5932 : : {
5933 : 34748279 : if (POINTER_TYPE_P (type))
5934 : : return true;
5935 : :
5936 : 19521212 : if (TREE_CODE (type) == ARRAY_TYPE)
5937 : 730639 : return type_must_have_pointers (TREE_TYPE (type));
5938 : :
5939 : : /* A function or method can have pointers as arguments, so track
5940 : : those separately. */
5941 : 18790573 : if (FUNC_OR_METHOD_TYPE_P (type))
5942 : 0 : return true;
5943 : :
5944 : : return false;
5945 : : }
5946 : :
5947 : : static bool
5948 : 34017640 : field_must_have_pointers (tree t)
5949 : : {
5950 : 34017640 : return type_must_have_pointers (TREE_TYPE (t));
5951 : : }
5952 : :
5953 : : /* Given a TYPE, and a vector of field offsets FIELDSTACK, push all
5954 : : the fields of TYPE onto fieldstack, recording their offsets along
5955 : : the way.
5956 : :
5957 : : OFFSET is used to keep track of the offset in this entire
5958 : : structure, rather than just the immediately containing structure.
5959 : : Returns false if the caller is supposed to handle the field we
5960 : : recursed for. */
5961 : :
5962 : : static bool
5963 : 14250470 : push_fields_onto_fieldstack (tree type, vec<fieldoff_s> *fieldstack,
5964 : : unsigned HOST_WIDE_INT offset)
5965 : : {
5966 : 14250470 : tree field;
5967 : 14250470 : bool empty_p = true;
5968 : :
5969 : 14250470 : if (TREE_CODE (type) != RECORD_TYPE)
5970 : : return false;
5971 : :
5972 : : /* If the vector of fields is growing too big, bail out early.
5973 : : Callers check for vec::length <= param_max_fields_for_field_sensitive, make
5974 : : sure this fails. */
5975 : 14250470 : if (fieldstack->length () > (unsigned)param_max_fields_for_field_sensitive)
5976 : : return false;
5977 : :
5978 : 324473246 : for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
5979 : 310410729 : if (TREE_CODE (field) == FIELD_DECL)
5980 : : {
5981 : 40299653 : bool push = false;
5982 : 40299653 : unsigned HOST_WIDE_INT foff = bitpos_of_field (field);
5983 : 40299653 : tree field_type = TREE_TYPE (field);
5984 : :
5985 : 40299653 : if (!var_can_have_subvars (field)
5986 : 6497071 : || TREE_CODE (field_type) == QUAL_UNION_TYPE
5987 : 46796724 : || TREE_CODE (field_type) == UNION_TYPE)
5988 : : push = true;
5989 : 6497071 : else if (!push_fields_onto_fieldstack
5990 : 6497071 : (field_type, fieldstack, offset + foff)
5991 : 6497071 : && (DECL_SIZE (field)
5992 : 1087136 : && !integer_zerop (DECL_SIZE (field))))
5993 : : /* Empty structures may have actual size, like in C++. So
5994 : : see if we didn't push any subfields and the size is
5995 : : nonzero, push the field onto the stack. */
5996 : : push = true;
5997 : :
5998 : : if (push)
5999 : : {
6000 : 34017640 : fieldoff_s *pair = NULL;
6001 : 34017640 : bool has_unknown_size = false;
6002 : 34017640 : bool must_have_pointers_p;
6003 : :
6004 : 34017640 : if (!fieldstack->is_empty ())
6005 : 26521652 : pair = &fieldstack->last ();
6006 : :
6007 : : /* If there isn't anything at offset zero, create sth. */
6008 : 26521652 : if (!pair
6009 : 7495988 : && offset + foff != 0)
6010 : : {
6011 : 8958 : fieldoff_s e
6012 : 8958 : = {0, offset + foff, false, false, true, false, NULL_TREE};
6013 : 8958 : pair = fieldstack->safe_push (e);
6014 : : }
6015 : :
6016 : 34017640 : if (!DECL_SIZE (field)
6017 : 34017640 : || !tree_fits_uhwi_p (DECL_SIZE (field)))
6018 : : has_unknown_size = true;
6019 : :
6020 : : /* If adjacent fields do not contain pointers merge them. */
6021 : 34017640 : must_have_pointers_p = field_must_have_pointers (field);
6022 : 34017640 : if (pair
6023 : 34017640 : && !has_unknown_size
6024 : 26499758 : && !must_have_pointers_p
6025 : 16503023 : && !pair->must_have_pointers
6026 : 11807679 : && !pair->has_unknown_size
6027 : 11807676 : && pair->offset + pair->size == offset + foff)
6028 : : {
6029 : 11205492 : pair->size += tree_to_uhwi (DECL_SIZE (field));
6030 : : }
6031 : : else
6032 : : {
6033 : 22812148 : fieldoff_s e;
6034 : 22812148 : e.offset = offset + foff;
6035 : 22812148 : e.has_unknown_size = has_unknown_size;
6036 : 22812148 : if (!has_unknown_size)
6037 : 22781269 : e.size = tree_to_uhwi (DECL_SIZE (field));
6038 : : else
6039 : 30879 : e.size = -1;
6040 : 22812148 : e.must_have_pointers = must_have_pointers_p;
6041 : 22812148 : e.may_have_pointers = true;
6042 : 22812148 : e.only_restrict_pointers
6043 : 22812148 : = (!has_unknown_size
6044 : 22781269 : && POINTER_TYPE_P (field_type)
6045 : 38030816 : && TYPE_RESTRICT (field_type));
6046 : 22812148 : if (e.only_restrict_pointers)
6047 : 104387 : e.restrict_pointed_type = TREE_TYPE (field_type);
6048 : 22812148 : fieldstack->safe_push (e);
6049 : : }
6050 : : }
6051 : :
6052 : : empty_p = false;
6053 : : }
6054 : :
6055 : 14062517 : return !empty_p;
6056 : : }
6057 : :
6058 : : /* Count the number of arguments DECL has, and set IS_VARARGS to true
6059 : : if it is a varargs function. */
6060 : :
6061 : : static unsigned int
6062 : 23371 : count_num_arguments (tree decl, bool *is_varargs)
6063 : : {
6064 : 23371 : unsigned int num = 0;
6065 : 23371 : tree t;
6066 : :
6067 : : /* Capture named arguments for K&R functions. They do not
6068 : : have a prototype and thus no TYPE_ARG_TYPES. */
6069 : 48465 : for (t = DECL_ARGUMENTS (decl); t; t = DECL_CHAIN (t))
6070 : 25094 : ++num;
6071 : :
6072 : : /* Check if the function has variadic arguments. */
6073 : 48465 : for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
6074 : 48458 : if (TREE_VALUE (t) == void_type_node)
6075 : : break;
6076 : 23371 : if (!t)
6077 : 7 : *is_varargs = true;
6078 : :
6079 : 23371 : return num;
6080 : : }
6081 : :
6082 : : /* Creation function node for DECL, using NAME, and return the index
6083 : : of the variable we've created for the function. If NONLOCAL_p, create
6084 : : initial constraints. */
6085 : :
6086 : : static varinfo_t
6087 : 23371 : create_function_info_for (tree decl, const char *name, bool add_id,
6088 : : bool nonlocal_p)
6089 : : {
6090 : 23371 : struct function *fn = DECL_STRUCT_FUNCTION (decl);
6091 : 23371 : varinfo_t vi, prev_vi;
6092 : 23371 : tree arg;
6093 : 23371 : unsigned int i;
6094 : 23371 : bool is_varargs = false;
6095 : 23371 : unsigned int num_args = count_num_arguments (decl, &is_varargs);
6096 : :
6097 : : /* Create the variable info. */
6098 : :
6099 : 23371 : vi = new_var_info (decl, name, add_id);
6100 : 23371 : vi->offset = 0;
6101 : 23371 : vi->size = 1;
6102 : 23371 : vi->fullsize = fi_parm_base + num_args;
6103 : 23371 : vi->is_fn_info = 1;
6104 : 23371 : vi->may_have_pointers = false;
6105 : 23371 : if (is_varargs)
6106 : 7 : vi->fullsize = ~0;
6107 : 23371 : insert_vi_for_tree (vi->decl, vi);
6108 : :
6109 : 23371 : prev_vi = vi;
6110 : :
6111 : : /* Create a variable for things the function clobbers and one for
6112 : : things the function uses. */
6113 : 23371 : {
6114 : 23371 : varinfo_t clobbervi, usevi;
6115 : 23371 : const char *newname;
6116 : 23371 : char *tempname;
6117 : :
6118 : 23371 : tempname = xasprintf ("%s.clobber", name);
6119 : 23371 : newname = ggc_strdup (tempname);
6120 : 23371 : free (tempname);
6121 : :
6122 : 23371 : clobbervi = new_var_info (NULL, newname, false);
6123 : 23371 : clobbervi->offset = fi_clobbers;
6124 : 23371 : clobbervi->size = 1;
6125 : 23371 : clobbervi->fullsize = vi->fullsize;
6126 : 23371 : clobbervi->is_full_var = true;
6127 : 23371 : clobbervi->is_global_var = false;
6128 : 23371 : clobbervi->is_reg_var = true;
6129 : :
6130 : 23371 : gcc_assert (prev_vi->offset < clobbervi->offset);
6131 : 23371 : prev_vi->next = clobbervi->id;
6132 : 23371 : prev_vi = clobbervi;
6133 : :
6134 : 23371 : tempname = xasprintf ("%s.use", name);
6135 : 23371 : newname = ggc_strdup (tempname);
6136 : 23371 : free (tempname);
6137 : :
6138 : 23371 : usevi = new_var_info (NULL, newname, false);
6139 : 23371 : usevi->offset = fi_uses;
6140 : 23371 : usevi->size = 1;
6141 : 23371 : usevi->fullsize = vi->fullsize;
6142 : 23371 : usevi->is_full_var = true;
6143 : 23371 : usevi->is_global_var = false;
6144 : 23371 : usevi->is_reg_var = true;
6145 : :
6146 : 23371 : gcc_assert (prev_vi->offset < usevi->offset);
6147 : 23371 : prev_vi->next = usevi->id;
6148 : 23371 : prev_vi = usevi;
6149 : : }
6150 : :
6151 : : /* And one for the static chain. */
6152 : 23371 : if (fn->static_chain_decl != NULL_TREE)
6153 : : {
6154 : 139 : varinfo_t chainvi;
6155 : 139 : const char *newname;
6156 : 139 : char *tempname;
6157 : :
6158 : 139 : tempname = xasprintf ("%s.chain", name);
6159 : 139 : newname = ggc_strdup (tempname);
6160 : 139 : free (tempname);
6161 : :
6162 : 139 : chainvi = new_var_info (fn->static_chain_decl, newname, false);
6163 : 139 : chainvi->offset = fi_static_chain;
6164 : 139 : chainvi->size = 1;
6165 : 139 : chainvi->fullsize = vi->fullsize;
6166 : 139 : chainvi->is_full_var = true;
6167 : 139 : chainvi->is_global_var = false;
6168 : :
6169 : 139 : insert_vi_for_tree (fn->static_chain_decl, chainvi);
6170 : :
6171 : 139 : if (nonlocal_p
6172 : 0 : && chainvi->may_have_pointers)
6173 : 0 : make_constraint_from (chainvi, nonlocal_id);
6174 : :
6175 : 139 : gcc_assert (prev_vi->offset < chainvi->offset);
6176 : 139 : prev_vi->next = chainvi->id;
6177 : 139 : prev_vi = chainvi;
6178 : : }
6179 : :
6180 : : /* Create a variable for the return var. */
6181 : 23371 : if (DECL_RESULT (decl) != NULL
6182 : 23371 : || !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
6183 : : {
6184 : 23371 : varinfo_t resultvi;
6185 : 23371 : const char *newname;
6186 : 23371 : char *tempname;
6187 : 23371 : tree resultdecl = decl;
6188 : :
6189 : 23371 : if (DECL_RESULT (decl))
6190 : 23371 : resultdecl = DECL_RESULT (decl);
6191 : :
6192 : 23371 : tempname = xasprintf ("%s.result", name);
6193 : 23371 : newname = ggc_strdup (tempname);
6194 : 23371 : free (tempname);
6195 : :
6196 : 23371 : resultvi = new_var_info (resultdecl, newname, false);
6197 : 23371 : resultvi->offset = fi_result;
6198 : 23371 : resultvi->size = 1;
6199 : 23371 : resultvi->fullsize = vi->fullsize;
6200 : 23371 : resultvi->is_full_var = true;
6201 : 23371 : if (DECL_RESULT (decl))
6202 : 23371 : resultvi->may_have_pointers = true;
6203 : :
6204 : 23371 : if (DECL_RESULT (decl))
6205 : 23371 : insert_vi_for_tree (DECL_RESULT (decl), resultvi);
6206 : :
6207 : 23371 : if (nonlocal_p
6208 : 6961 : && DECL_RESULT (decl)
6209 : 30332 : && DECL_BY_REFERENCE (DECL_RESULT (decl)))
6210 : 6 : make_constraint_from (resultvi, nonlocal_id);
6211 : :
6212 : 23371 : gcc_assert (prev_vi->offset < resultvi->offset);
6213 : 23371 : prev_vi->next = resultvi->id;
6214 : 23371 : prev_vi = resultvi;
6215 : : }
6216 : :
6217 : : /* We also need to make function return values escape. Nothing
6218 : : escapes by returning from main though. */
6219 : 23371 : if (nonlocal_p
6220 : 23371 : && !MAIN_NAME_P (DECL_NAME (decl)))
6221 : : {
6222 : 3464 : varinfo_t fi, rvi;
6223 : 3464 : fi = lookup_vi_for_tree (decl);
6224 : 3464 : rvi = first_vi_for_offset (fi, fi_result);
6225 : 3464 : if (rvi && rvi->offset == fi_result)
6226 : 3464 : make_copy_constraint (get_varinfo (escaped_id), rvi->id);
6227 : : }
6228 : :
6229 : : /* Set up variables for each argument. */
6230 : 23371 : arg = DECL_ARGUMENTS (decl);
6231 : 48465 : for (i = 0; i < num_args; i++)
6232 : : {
6233 : 25094 : varinfo_t argvi;
6234 : 25094 : const char *newname;
6235 : 25094 : char *tempname;
6236 : 25094 : tree argdecl = decl;
6237 : :
6238 : 25094 : if (arg)
6239 : 25094 : argdecl = arg;
6240 : :
6241 : 25094 : tempname = xasprintf ("%s.arg%d", name, i);
6242 : 25094 : newname = ggc_strdup (tempname);
6243 : 25094 : free (tempname);
6244 : :
6245 : 25094 : argvi = new_var_info (argdecl, newname, false);
6246 : 25094 : argvi->offset = fi_parm_base + i;
6247 : 25094 : argvi->size = 1;
6248 : 25094 : argvi->is_full_var = true;
6249 : 25094 : argvi->fullsize = vi->fullsize;
6250 : 25094 : if (arg)
6251 : 25094 : argvi->may_have_pointers = true;
6252 : :
6253 : 25094 : if (arg)
6254 : 25094 : insert_vi_for_tree (arg, argvi);
6255 : :
6256 : 25094 : if (nonlocal_p
6257 : 9092 : && argvi->may_have_pointers)
6258 : 9092 : make_constraint_from (argvi, nonlocal_id);
6259 : :
6260 : 25094 : gcc_assert (prev_vi->offset < argvi->offset);
6261 : 25094 : prev_vi->next = argvi->id;
6262 : 25094 : prev_vi = argvi;
6263 : 25094 : if (arg)
6264 : 25094 : arg = DECL_CHAIN (arg);
6265 : : }
6266 : :
6267 : : /* Add one representative for all further args. */
6268 : 23371 : if (is_varargs)
6269 : : {
6270 : 7 : varinfo_t argvi;
6271 : 7 : const char *newname;
6272 : 7 : char *tempname;
6273 : 7 : tree decl;
6274 : :
6275 : 7 : tempname = xasprintf ("%s.varargs", name);
6276 : 7 : newname = ggc_strdup (tempname);
6277 : 7 : free (tempname);
6278 : :
6279 : : /* We need sth that can be pointed to for va_start. */
6280 : 7 : decl = build_fake_var_decl (ptr_type_node);
6281 : :
6282 : 7 : argvi = new_var_info (decl, newname, false);
6283 : 7 : argvi->offset = fi_parm_base + num_args;
6284 : 7 : argvi->size = ~0;
6285 : 7 : argvi->is_full_var = true;
6286 : 7 : argvi->is_heap_var = true;
6287 : 7 : argvi->fullsize = vi->fullsize;
6288 : :
6289 : 7 : if (nonlocal_p
6290 : 6 : && argvi->may_have_pointers)
6291 : 6 : make_constraint_from (argvi, nonlocal_id);
6292 : :
6293 : 7 : gcc_assert (prev_vi->offset < argvi->offset);
6294 : 7 : prev_vi->next = argvi->id;
6295 : : }
6296 : :
6297 : 23371 : return vi;
6298 : : }
6299 : :
6300 : :
6301 : : /* Return true if FIELDSTACK contains fields that overlap.
6302 : : FIELDSTACK is assumed to be sorted by offset. */
6303 : :
6304 : : static bool
6305 : 7722520 : check_for_overlaps (const vec<fieldoff_s> &fieldstack)
6306 : : {
6307 : 7722520 : fieldoff_s *fo = NULL;
6308 : 7722520 : unsigned int i;
6309 : 7722520 : HOST_WIDE_INT lastoffset = -1;
6310 : :
6311 : 29752698 : FOR_EACH_VEC_ELT (fieldstack, i, fo)
6312 : : {
6313 : 22048179 : if (fo->offset == lastoffset)
6314 : : return true;
6315 : 22030178 : lastoffset = fo->offset;
6316 : : }
6317 : : return false;
6318 : : }
6319 : :
6320 : : /* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
6321 : : This will also create any varinfo structures necessary for fields
6322 : : of DECL. DECL is a function parameter if HANDLE_PARAM is set.
6323 : : HANDLED_STRUCT_TYPE is used to register struct types reached by following
6324 : : restrict pointers. This is needed to prevent infinite recursion.
6325 : : If ADD_RESTRICT, pretend that the pointer NAME is restrict even if DECL
6326 : : does not advertise it. */
6327 : :
6328 : : static varinfo_t
6329 : 91273338 : create_variable_info_for_1 (tree decl, const char *name, bool add_id,
6330 : : bool handle_param, bitmap handled_struct_type,
6331 : : bool add_restrict = false)
6332 : : {
6333 : 91273338 : varinfo_t vi, newvi;
6334 : 91273338 : tree decl_type = TREE_TYPE (decl);
6335 : 91273338 : tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type);
6336 : 91273338 : auto_vec<fieldoff_s> fieldstack;
6337 : 91273338 : fieldoff_s *fo;
6338 : 91273338 : unsigned int i;
6339 : :
6340 : 91273338 : if (!declsize
6341 : 83025230 : || !tree_fits_uhwi_p (declsize))
6342 : : {
6343 : 8261594 : vi = new_var_info (decl, name, add_id);
6344 : 8261594 : vi->offset = 0;
6345 : 8261594 : vi->size = ~0;
6346 : 8261594 : vi->fullsize = ~0;
6347 : 8261594 : vi->is_unknown_size_var = true;
6348 : 8261594 : vi->is_full_var = true;
6349 : 8261594 : vi->may_have_pointers = true;
6350 : 8261594 : return vi;
6351 : : }
6352 : :
6353 : : /* Collect field information. */
6354 : 83011744 : if (use_field_sensitive
6355 : 79174747 : && var_can_have_subvars (decl)
6356 : : /* ??? Force us to not use subfields for globals in IPA mode.
6357 : : Else we'd have to parse arbitrary initializers. */
6358 : 90785187 : && !(in_ipa_mode
6359 : 19589 : && is_global_var (decl)))
6360 : : {
6361 : 7753399 : fieldoff_s *fo = NULL;
6362 : 7753399 : bool notokay = false;
6363 : 7753399 : unsigned int i;
6364 : :
6365 : 7753399 : push_fields_onto_fieldstack (decl_type, &fieldstack, 0);
6366 : :
6367 : 38297022 : for (i = 0; !notokay && fieldstack.iterate (i, &fo); i++)
6368 : 22821103 : if (fo->has_unknown_size
6369 : 22790224 : || fo->offset < 0)
6370 : : {
6371 : : notokay = true;
6372 : : break;
6373 : : }
6374 : :
6375 : : /* We can't sort them if we have a field with a variable sized type,
6376 : : which will make notokay = true. In that case, we are going to return
6377 : : without creating varinfos for the fields anyway, so sorting them is a
6378 : : waste to boot. */
6379 : 7753399 : if (!notokay)
6380 : : {
6381 : 7722520 : sort_fieldstack (fieldstack);
6382 : : /* Due to some C++ FE issues, like PR 22488, we might end up
6383 : : what appear to be overlapping fields even though they,
6384 : : in reality, do not overlap. Until the C++ FE is fixed,
6385 : : we will simply disable field-sensitivity for these cases. */
6386 : 7722520 : notokay = check_for_overlaps (fieldstack);
6387 : : }
6388 : :
6389 : 7722520 : if (notokay)
6390 : 48880 : fieldstack.release ();
6391 : : }
6392 : :
6393 : : /* If we didn't end up collecting sub-variables create a full
6394 : : variable for the decl. */
6395 : 83011744 : if (fieldstack.length () == 0
6396 : 7447108 : || fieldstack.length () > (unsigned)param_max_fields_for_field_sensitive)
6397 : : {
6398 : 75565054 : vi = new_var_info (decl, name, add_id);
6399 : 75565054 : vi->offset = 0;
6400 : 75565054 : vi->may_have_pointers = true;
6401 : 75565054 : vi->fullsize = tree_to_uhwi (declsize);
6402 : 75565054 : vi->size = vi->fullsize;
6403 : 75565054 : vi->is_full_var = true;
6404 : 75565054 : if (POINTER_TYPE_P (decl_type)
6405 : 75565054 : && (TYPE_RESTRICT (decl_type) || add_restrict))
6406 : 850460 : vi->only_restrict_pointers = 1;
6407 : 75565054 : if (vi->only_restrict_pointers
6408 : 850460 : && !type_contains_placeholder_p (TREE_TYPE (decl_type))
6409 : 850460 : && handle_param
6410 : 76126367 : && !bitmap_bit_p (handled_struct_type,
6411 : 561313 : TYPE_UID (TREE_TYPE (decl_type))))
6412 : : {
6413 : 561313 : varinfo_t rvi;
6414 : 561313 : tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type));
6415 : 561313 : DECL_EXTERNAL (heapvar) = 1;
6416 : 561313 : if (var_can_have_subvars (heapvar))
6417 : 875628 : bitmap_set_bit (handled_struct_type,
6418 : 437814 : TYPE_UID (TREE_TYPE (decl_type)));
6419 : 561313 : rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
6420 : : true, handled_struct_type);
6421 : 561313 : if (var_can_have_subvars (heapvar))
6422 : 875628 : bitmap_clear_bit (handled_struct_type,
6423 : 437814 : TYPE_UID (TREE_TYPE (decl_type)));
6424 : 561313 : rvi->is_restrict_var = 1;
6425 : 561313 : insert_vi_for_tree (heapvar, rvi);
6426 : 561313 : make_constraint_from (vi, rvi->id);
6427 : 561313 : make_param_constraints (rvi);
6428 : : }
6429 : 75565054 : fieldstack.release ();
6430 : 75565054 : return vi;
6431 : : }
6432 : :
6433 : 7446690 : vi = new_var_info (decl, name, add_id);
6434 : 7446690 : vi->fullsize = tree_to_uhwi (declsize);
6435 : 7446690 : if (fieldstack.length () == 1)
6436 : 1664798 : vi->is_full_var = true;
6437 : : for (i = 0, newvi = vi;
6438 : 120661708 : fieldstack.iterate (i, &fo);
6439 : 21941680 : ++i, newvi = vi_next (newvi))
6440 : : {
6441 : 21941680 : const char *newname = NULL;
6442 : 21941680 : char *tempname;
6443 : :
6444 : 21941680 : if (dump_file)
6445 : : {
6446 : 331 : if (fieldstack.length () != 1)
6447 : : {
6448 : 301 : tempname
6449 : 301 : = xasprintf ("%s." HOST_WIDE_INT_PRINT_DEC
6450 : : "+" HOST_WIDE_INT_PRINT_DEC, name,
6451 : : fo->offset, fo->size);
6452 : 301 : newname = ggc_strdup (tempname);
6453 : 301 : free (tempname);
6454 : : }
6455 : : }
6456 : : else
6457 : : newname = "NULL";
6458 : :
6459 : 301 : if (newname)
6460 : 21941650 : newvi->name = newname;
6461 : 21941680 : newvi->offset = fo->offset;
6462 : 21941680 : newvi->size = fo->size;
6463 : 21941680 : newvi->fullsize = vi->fullsize;
6464 : 21941680 : newvi->may_have_pointers = fo->may_have_pointers;
6465 : 21941680 : newvi->only_restrict_pointers = fo->only_restrict_pointers;
6466 : 21941680 : if (handle_param
6467 : 1686422 : && newvi->only_restrict_pointers
6468 : 24612 : && !type_contains_placeholder_p (fo->restrict_pointed_type)
6469 : 21966292 : && !bitmap_bit_p (handled_struct_type,
6470 : 24612 : TYPE_UID (fo->restrict_pointed_type)))
6471 : : {
6472 : 24609 : varinfo_t rvi;
6473 : 24609 : tree heapvar = build_fake_var_decl (fo->restrict_pointed_type);
6474 : 24609 : DECL_EXTERNAL (heapvar) = 1;
6475 : 24609 : if (var_can_have_subvars (heapvar))
6476 : 80 : bitmap_set_bit (handled_struct_type,
6477 : 40 : TYPE_UID (fo->restrict_pointed_type));
6478 : 24609 : rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
6479 : : true, handled_struct_type);
6480 : 24609 : if (var_can_have_subvars (heapvar))
6481 : 80 : bitmap_clear_bit (handled_struct_type,
6482 : 40 : TYPE_UID (fo->restrict_pointed_type));
6483 : 24609 : rvi->is_restrict_var = 1;
6484 : 24609 : insert_vi_for_tree (heapvar, rvi);
6485 : 24609 : make_constraint_from (newvi, rvi->id);
6486 : 24609 : make_param_constraints (rvi);
6487 : : }
6488 : 36436670 : if (i + 1 < fieldstack.length ())
6489 : : {
6490 : 14494990 : varinfo_t tem = new_var_info (decl, name, false);
6491 : 14494990 : newvi->next = tem->id;
6492 : 14494990 : tem->head = vi->id;
6493 : : }
6494 : : }
6495 : :
6496 : : return vi;
6497 : 91273338 : }
6498 : :
6499 : : static unsigned int
6500 : 81367809 : create_variable_info_for (tree decl, const char *name, bool add_id)
6501 : : {
6502 : : /* First see if we are dealing with an ifunc resolver call and
6503 : : assiociate that with a call to the resolver function result. */
6504 : 81367809 : cgraph_node *node;
6505 : 81367809 : if (in_ipa_mode
6506 : 691419 : && TREE_CODE (decl) == FUNCTION_DECL
6507 : 17552 : && (node = cgraph_node::get (decl))
6508 : 81385359 : && node->ifunc_resolver)
6509 : : {
6510 : 1 : varinfo_t fi = get_vi_for_tree (node->get_alias_target ()->decl);
6511 : 1 : constraint_expr rhs
6512 : 1 : = get_function_part_constraint (fi, fi_result);
6513 : 1 : fi = new_var_info (NULL_TREE, "ifuncres", true);
6514 : 1 : fi->is_reg_var = true;
6515 : 1 : constraint_expr lhs;
6516 : 1 : lhs.type = SCALAR;
6517 : 1 : lhs.var = fi->id;
6518 : 1 : lhs.offset = 0;
6519 : 1 : process_constraint (new_constraint (lhs, rhs));
6520 : 1 : insert_vi_for_tree (decl, fi);
6521 : 1 : return fi->id;
6522 : : }
6523 : :
6524 : 81367808 : varinfo_t vi = create_variable_info_for_1 (decl, name, add_id, false, NULL);
6525 : 81367808 : unsigned int id = vi->id;
6526 : :
6527 : 81367808 : insert_vi_for_tree (decl, vi);
6528 : :
6529 : 81367808 : if (!VAR_P (decl))
6530 : : return id;
6531 : :
6532 : : /* Create initial constraints for globals. */
6533 : 33014276 : for (; vi; vi = vi_next (vi))
6534 : : {
6535 : 23182002 : if (!vi->may_have_pointers
6536 : 23182002 : || !vi->is_global_var)
6537 : 15269462 : continue;
6538 : :
6539 : : /* Mark global restrict qualified pointers. */
6540 : 15475214 : if ((POINTER_TYPE_P (TREE_TYPE (decl))
6541 : 350028 : && TYPE_RESTRICT (TREE_TYPE (decl)))
6542 : 15818560 : || vi->only_restrict_pointers)
6543 : : {
6544 : 11179 : varinfo_t rvi
6545 : 11179 : = make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT",
6546 : : true);
6547 : : /* ??? For now exclude reads from globals as restrict sources
6548 : : if those are not (indirectly) from incoming parameters. */
6549 : 11179 : rvi->is_restrict_var = false;
6550 : 11179 : continue;
6551 : 11179 : }
6552 : :
6553 : : /* In non-IPA mode the initializer from nonlocal is all we need. */
6554 : 7901361 : if (!in_ipa_mode
6555 : 7937891 : || DECL_HARD_REGISTER (decl))
6556 : 7864831 : make_copy_constraint (vi, nonlocal_id);
6557 : :
6558 : : /* In IPA mode parse the initializer and generate proper constraints
6559 : : for it. */
6560 : : else
6561 : : {
6562 : 36530 : varpool_node *vnode = varpool_node::get (decl);
6563 : :
6564 : : /* For escaped variables initialize them from nonlocal. */
6565 : 36530 : if (!vnode || !vnode->all_refs_explicit_p ())
6566 : 1466 : make_copy_constraint (vi, nonlocal_id);
6567 : :
6568 : : /* While we can in theory walk references for the varpool
6569 : : node that does not cover zero-initialization or references
6570 : : to the constant pool. */
6571 : 36530 : if (DECL_INITIAL (decl))
6572 : : {
6573 : 35426 : auto_vec<ce_s> rhsc;
6574 : 35426 : struct constraint_expr lhs, *rhsp;
6575 : 35426 : unsigned i;
6576 : 35426 : lhs.var = vi->id;
6577 : 35426 : lhs.offset = 0;
6578 : 35426 : lhs.type = SCALAR;
6579 : 35426 : get_constraint_for (DECL_INITIAL (decl), &rhsc);
6580 : 181851 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
6581 : 110999 : process_constraint (new_constraint (lhs, *rhsp));
6582 : : /* If this is a variable that escapes from the unit
6583 : : the initializer escapes as well. */
6584 : 35426 : if (!vnode || !vnode->all_refs_explicit_p ())
6585 : : {
6586 : 2199 : lhs.var = escaped_id;
6587 : 2199 : lhs.offset = 0;
6588 : 2199 : lhs.type = SCALAR;
6589 : 37625 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
6590 : 1584 : process_constraint (new_constraint (lhs, *rhsp));
6591 : : }
6592 : 35426 : }
6593 : : }
6594 : : }
6595 : :
6596 : : return id;
6597 : : }
6598 : :
6599 : : /* Print out the points-to solution for VAR to FILE. */
6600 : :
6601 : : static void
6602 : 5814 : dump_solution_for_var (FILE *file, unsigned int var)
6603 : : {
6604 : 5814 : varinfo_t vi = get_varinfo (var);
6605 : 5814 : unsigned int i;
6606 : 5814 : bitmap_iterator bi;
6607 : :
6608 : : /* Dump the solution for unified vars anyway, this avoids difficulties
6609 : : in scanning dumps in the testsuite. */
6610 : 5814 : fprintf (file, "%s = { ", vi->name);
6611 : 5814 : vi = get_varinfo (find (var));
6612 : 15338 : EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
6613 : 9524 : fprintf (file, "%s ", get_varinfo (i)->name);
6614 : 5814 : fprintf (file, "}");
6615 : :
6616 : : /* But note when the variable was unified. */
6617 : 5814 : if (vi->id != var)
6618 : 1224 : fprintf (file, " same as %s", vi->name);
6619 : :
6620 : 5814 : fprintf (file, "\n");
6621 : 5814 : }
6622 : :
6623 : : /* Print the points-to solution for VAR to stderr. */
6624 : :
6625 : : DEBUG_FUNCTION void
6626 : 0 : debug_solution_for_var (unsigned int var)
6627 : : {
6628 : 0 : dump_solution_for_var (stderr, var);
6629 : 0 : }
6630 : :
6631 : : /* Register the constraints for function parameter related VI. */
6632 : :
6633 : : static void
6634 : 9905530 : make_param_constraints (varinfo_t vi)
6635 : : {
6636 : 11284303 : for (; vi; vi = vi_next (vi))
6637 : : {
6638 : 10803665 : if (vi->only_restrict_pointers)
6639 : : ;
6640 : 10217740 : else if (vi->may_have_pointers)
6641 : 10217740 : make_constraint_from (vi, nonlocal_id);
6642 : :
6643 : 10803665 : if (vi->is_full_var)
6644 : : break;
6645 : : }
6646 : 9905530 : }
6647 : :
6648 : : /* Create varinfo structures for all of the variables in the
6649 : : function for intraprocedural mode. */
6650 : :
6651 : : static void
6652 : 4404575 : intra_create_variable_infos (struct function *fn)
6653 : : {
6654 : 4404575 : tree t;
6655 : 4404575 : bitmap handled_struct_type = NULL;
6656 : 4404575 : bool this_parm_in_ctor = DECL_CXX_CONSTRUCTOR_P (fn->decl);
6657 : :
6658 : : /* For each incoming pointer argument arg, create the constraint ARG
6659 : : = NONLOCAL or a dummy variable if it is a restrict qualified
6660 : : passed-by-reference argument. */
6661 : 13724183 : for (t = DECL_ARGUMENTS (fn->decl); t; t = DECL_CHAIN (t))
6662 : : {
6663 : 9319608 : if (handled_struct_type == NULL)
6664 : 3720692 : handled_struct_type = BITMAP_ALLOC (NULL);
6665 : :
6666 : 9319608 : varinfo_t p
6667 : 9319608 : = create_variable_info_for_1 (t, alias_get_name (t), false, true,
6668 : : handled_struct_type, this_parm_in_ctor);
6669 : 9319608 : insert_vi_for_tree (t, p);
6670 : :
6671 : 9319608 : make_param_constraints (p);
6672 : :
6673 : 9319608 : this_parm_in_ctor = false;
6674 : : }
6675 : :
6676 : 4404575 : if (handled_struct_type != NULL)
6677 : 3720692 : BITMAP_FREE (handled_struct_type);
6678 : :
6679 : : /* Add a constraint for a result decl that is passed by reference. */
6680 : 4404575 : if (DECL_RESULT (fn->decl)
6681 : 4404575 : && DECL_BY_REFERENCE (DECL_RESULT (fn->decl)))
6682 : : {
6683 : 57339 : varinfo_t p, result_vi = get_vi_for_tree (DECL_RESULT (fn->decl));
6684 : :
6685 : 172017 : for (p = result_vi; p; p = vi_next (p))
6686 : 57339 : make_constraint_from (p, nonlocal_id);
6687 : : }
6688 : :
6689 : : /* Add a constraint for the incoming static chain parameter. */
6690 : 4404575 : if (fn->static_chain_decl != NULL_TREE)
6691 : : {
6692 : 47246 : varinfo_t p, chain_vi = get_vi_for_tree (fn->static_chain_decl);
6693 : :
6694 : 141738 : for (p = chain_vi; p; p = vi_next (p))
6695 : 47246 : make_constraint_from (p, nonlocal_id);
6696 : : }
6697 : 4404575 : }
6698 : :
6699 : : /* Structure used to put solution bitmaps in a hashtable so they can
6700 : : be shared among variables with the same points-to set. */
6701 : :
6702 : : typedef struct shared_bitmap_info
6703 : : {
6704 : : bitmap pt_vars;
6705 : : hashval_t hashcode;
6706 : : } *shared_bitmap_info_t;
6707 : : typedef const struct shared_bitmap_info *const_shared_bitmap_info_t;
6708 : :
6709 : : /* Shared_bitmap hashtable helpers. */
6710 : :
6711 : : struct shared_bitmap_hasher : free_ptr_hash <shared_bitmap_info>
6712 : : {
6713 : : static inline hashval_t hash (const shared_bitmap_info *);
6714 : : static inline bool equal (const shared_bitmap_info *,
6715 : : const shared_bitmap_info *);
6716 : : };
6717 : :
6718 : : /* Hash function for a shared_bitmap_info_t */
6719 : :
6720 : : inline hashval_t
6721 : 4557084 : shared_bitmap_hasher::hash (const shared_bitmap_info *bi)
6722 : : {
6723 : 4557084 : return bi->hashcode;
6724 : : }
6725 : :
6726 : : /* Equality function for two shared_bitmap_info_t's. */
6727 : :
6728 : : inline bool
6729 : 41980449 : shared_bitmap_hasher::equal (const shared_bitmap_info *sbi1,
6730 : : const shared_bitmap_info *sbi2)
6731 : : {
6732 : 41980449 : return bitmap_equal_p (sbi1->pt_vars, sbi2->pt_vars);
6733 : : }
6734 : :
6735 : : /* Shared_bitmap hashtable. */
6736 : :
6737 : : static hash_table<shared_bitmap_hasher> *shared_bitmap_table;
6738 : :
6739 : : /* Lookup a bitmap in the shared bitmap hashtable, and return an already
6740 : : existing instance if there is one, NULL otherwise. */
6741 : :
6742 : : static bitmap
6743 : 45877267 : shared_bitmap_lookup (bitmap pt_vars)
6744 : : {
6745 : 45877267 : shared_bitmap_info **slot;
6746 : 45877267 : struct shared_bitmap_info sbi;
6747 : :
6748 : 45877267 : sbi.pt_vars = pt_vars;
6749 : 45877267 : sbi.hashcode = bitmap_hash (pt_vars);
6750 : :
6751 : 45877267 : slot = shared_bitmap_table->find_slot (&sbi, NO_INSERT);
6752 : 45877267 : if (!slot)
6753 : : return NULL;
6754 : : else
6755 : 37154054 : return (*slot)->pt_vars;
6756 : : }
6757 : :
6758 : :
6759 : : /* Add a bitmap to the shared bitmap hashtable. */
6760 : :
6761 : : static void
6762 : 8723213 : shared_bitmap_add (bitmap pt_vars)
6763 : : {
6764 : 8723213 : shared_bitmap_info **slot;
6765 : 8723213 : shared_bitmap_info_t sbi = XNEW (struct shared_bitmap_info);
6766 : :
6767 : 8723213 : sbi->pt_vars = pt_vars;
6768 : 8723213 : sbi->hashcode = bitmap_hash (pt_vars);
6769 : :
6770 : 8723213 : slot = shared_bitmap_table->find_slot (sbi, INSERT);
6771 : 8723213 : gcc_assert (!*slot);
6772 : 8723213 : *slot = sbi;
6773 : 8723213 : }
6774 : :
6775 : :
6776 : : /* Set bits in INTO corresponding to the variable uids in solution set FROM. */
6777 : :
6778 : : static void
6779 : 45877267 : set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt,
6780 : : tree fndecl)
6781 : : {
6782 : 45877267 : unsigned int i;
6783 : 45877267 : bitmap_iterator bi;
6784 : 45877267 : varinfo_t escaped_vi = get_varinfo (find (escaped_id));
6785 : 45877267 : varinfo_t escaped_return_vi = get_varinfo (find (escaped_return_id));
6786 : 45877267 : bool everything_escaped
6787 : 45877267 : = escaped_vi->solution && bitmap_bit_p (escaped_vi->solution, anything_id);
6788 : :
6789 : 267036362 : EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
6790 : : {
6791 : 221159095 : varinfo_t vi = get_varinfo (i);
6792 : :
6793 : 221159095 : if (vi->is_artificial_var)
6794 : 82224897 : continue;
6795 : :
6796 : 138934198 : if (everything_escaped
6797 : 138934198 : || (escaped_vi->solution
6798 : 138386105 : && bitmap_bit_p (escaped_vi->solution, i)))
6799 : : {
6800 : 120505441 : pt->vars_contains_escaped = true;
6801 : 120505441 : pt->vars_contains_escaped_heap |= vi->is_heap_var;
6802 : : }
6803 : 138934198 : if (escaped_return_vi->solution
6804 : 138934198 : && bitmap_bit_p (escaped_return_vi->solution, i))
6805 : 18685227 : pt->vars_contains_escaped_heap |= vi->is_heap_var;
6806 : :
6807 : 138934198 : if (vi->is_restrict_var)
6808 : 1746816 : pt->vars_contains_restrict = true;
6809 : :
6810 : 138934198 : if (VAR_P (vi->decl)
6811 : 2436868 : || TREE_CODE (vi->decl) == PARM_DECL
6812 : 1919632 : || TREE_CODE (vi->decl) == RESULT_DECL)
6813 : : {
6814 : : /* If we are in IPA mode we will not recompute points-to
6815 : : sets after inlining so make sure they stay valid. */
6816 : 137029012 : if (in_ipa_mode
6817 : 137029012 : && !DECL_PT_UID_SET_P (vi->decl))
6818 : 33186 : SET_DECL_PT_UID (vi->decl, DECL_UID (vi->decl));
6819 : :
6820 : : /* Add the decl to the points-to set. Note that the points-to
6821 : : set contains global variables. */
6822 : 137029012 : bitmap_set_bit (into, DECL_PT_UID (vi->decl));
6823 : 137029012 : if (vi->is_global_var
6824 : : /* In IPA mode the escaped_heap trick doesn't work as
6825 : : ESCAPED is escaped from the unit but
6826 : : pt_solution_includes_global needs to answer true for
6827 : : all variables not automatic within a function.
6828 : : For the same reason is_global_var is not the
6829 : : correct flag to track - local variables from other
6830 : : functions also need to be considered global.
6831 : : Conveniently all HEAP vars are not put in function
6832 : : scope. */
6833 : 137029012 : || (in_ipa_mode
6834 : 270007 : && fndecl
6835 : 245207 : && ! auto_var_in_fn_p (vi->decl, fndecl)))
6836 : 77200291 : pt->vars_contains_nonlocal = true;
6837 : :
6838 : : /* If we have a variable that is interposable record that fact
6839 : : for pointer comparison simplification. */
6840 : 137029012 : if (VAR_P (vi->decl)
6841 : 136497330 : && (TREE_STATIC (vi->decl) || DECL_EXTERNAL (vi->decl))
6842 : 214086006 : && ! decl_binds_to_current_def_p (vi->decl))
6843 : 54916509 : pt->vars_contains_interposable = true;
6844 : :
6845 : : /* If this is a local variable we can have overlapping lifetime
6846 : : of different function invocations through recursion duplicate
6847 : : it with its shadow variable. */
6848 : 137029012 : if (in_ipa_mode
6849 : 328288 : && vi->shadow_var_uid != 0)
6850 : : {
6851 : 201676 : bitmap_set_bit (into, vi->shadow_var_uid);
6852 : 201676 : pt->vars_contains_nonlocal = true;
6853 : : }
6854 : : }
6855 : :
6856 : 1905186 : else if (TREE_CODE (vi->decl) == FUNCTION_DECL
6857 : 1905186 : || TREE_CODE (vi->decl) == LABEL_DECL)
6858 : : {
6859 : : /* Nothing should read/write from/to code so we can
6860 : : save bits by not including them in the points-to bitmaps.
6861 : : Still mark the points-to set as containing global memory
6862 : : to make code-patching possible - see PR70128. */
6863 : 1751193 : pt->vars_contains_nonlocal = true;
6864 : : }
6865 : : }
6866 : 45877267 : }
6867 : :
6868 : :
6869 : : /* Compute the points-to solution *PT for the variable VI. */
6870 : :
6871 : : static struct pt_solution
6872 : 60528260 : find_what_var_points_to (tree fndecl, varinfo_t orig_vi)
6873 : : {
6874 : 60528260 : unsigned int i;
6875 : 60528260 : bitmap_iterator bi;
6876 : 60528260 : bitmap finished_solution;
6877 : 60528260 : bitmap result;
6878 : 60528260 : varinfo_t vi;
6879 : 60528260 : struct pt_solution *pt;
6880 : :
6881 : : /* This variable may have been collapsed, let's get the real
6882 : : variable. */
6883 : 60528260 : vi = get_varinfo (find (orig_vi->id));
6884 : :
6885 : : /* See if we have already computed the solution and return it. */
6886 : 60528260 : pt_solution **slot = &final_solutions->get_or_insert (vi);
6887 : 60528260 : if (*slot != NULL)
6888 : 14054610 : return **slot;
6889 : :
6890 : 46473650 : *slot = pt = XOBNEW (&final_solutions_obstack, struct pt_solution);
6891 : 46473650 : memset (pt, 0, sizeof (struct pt_solution));
6892 : :
6893 : : /* Translate artificial variables into SSA_NAME_PTR_INFO
6894 : : attributes. */
6895 : 272785431 : EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
6896 : : {
6897 : 226311781 : varinfo_t vi = get_varinfo (i);
6898 : :
6899 : 226311781 : if (vi->is_artificial_var)
6900 : : {
6901 : 84201900 : if (vi->id == nothing_id)
6902 : 9967242 : pt->null = 1;
6903 : : else if (vi->id == escaped_id)
6904 : : {
6905 : 32011273 : if (in_ipa_mode)
6906 : 133334 : pt->ipa_escaped = 1;
6907 : : else
6908 : 31877939 : pt->escaped = 1;
6909 : : /* Expand some special vars of ESCAPED in-place here. */
6910 : 32011273 : varinfo_t evi = get_varinfo (find (escaped_id));
6911 : 32011273 : if (bitmap_bit_p (evi->solution, nonlocal_id))
6912 : 29765288 : pt->nonlocal = 1;
6913 : : }
6914 : : else if (vi->id == nonlocal_id)
6915 : 35608947 : pt->nonlocal = 1;
6916 : : else if (vi->id == string_id)
6917 : 6017064 : pt->const_pool = 1;
6918 : : else if (vi->id == anything_id
6919 : : || vi->id == integer_id)
6920 : 596398 : pt->anything = 1;
6921 : : }
6922 : : }
6923 : :
6924 : : /* Instead of doing extra work, simply do not create
6925 : : elaborate points-to information for pt_anything pointers. */
6926 : 46473650 : if (pt->anything)
6927 : 596383 : return *pt;
6928 : :
6929 : : /* Share the final set of variables when possible. */
6930 : 45877267 : finished_solution = BITMAP_GGC_ALLOC ();
6931 : 45877267 : stats.points_to_sets_created++;
6932 : :
6933 : 45877267 : set_uids_in_ptset (finished_solution, vi->solution, pt, fndecl);
6934 : 45877267 : result = shared_bitmap_lookup (finished_solution);
6935 : 45877267 : if (!result)
6936 : : {
6937 : 8723213 : shared_bitmap_add (finished_solution);
6938 : 8723213 : pt->vars = finished_solution;
6939 : : }
6940 : : else
6941 : : {
6942 : 37154054 : pt->vars = result;
6943 : 37154054 : bitmap_clear (finished_solution);
6944 : : }
6945 : :
6946 : 45877267 : return *pt;
6947 : : }
6948 : :
6949 : : /* Given a pointer variable P, fill in its points-to set. */
6950 : :
6951 : : static void
6952 : 24163769 : find_what_p_points_to (tree fndecl, tree p)
6953 : : {
6954 : 24163769 : struct ptr_info_def *pi;
6955 : 24163769 : tree lookup_p = p;
6956 : 24163769 : varinfo_t vi;
6957 : 24163769 : prange vr;
6958 : 48327538 : get_range_query (DECL_STRUCT_FUNCTION (fndecl))->range_of_expr (vr, p);
6959 : 24163769 : bool nonnull = vr.nonzero_p ();
6960 : :
6961 : : /* For parameters, get at the points-to set for the actual parm
6962 : : decl. */
6963 : 24163769 : if (TREE_CODE (p) == SSA_NAME
6964 : 24163769 : && SSA_NAME_IS_DEFAULT_DEF (p)
6965 : 29283785 : && (TREE_CODE (SSA_NAME_VAR (p)) == PARM_DECL
6966 : 945493 : || TREE_CODE (SSA_NAME_VAR (p)) == RESULT_DECL))
6967 : 4231715 : lookup_p = SSA_NAME_VAR (p);
6968 : :
6969 : 24163769 : vi = lookup_vi_for_tree (lookup_p);
6970 : 24163769 : if (!vi)
6971 : 974215 : return;
6972 : :
6973 : 23189554 : pi = get_ptr_info (p);
6974 : 23189554 : pi->pt = find_what_var_points_to (fndecl, vi);
6975 : : /* Conservatively set to NULL from PTA (to true). */
6976 : 23189554 : pi->pt.null = 1;
6977 : : /* Preserve pointer nonnull globally computed. */
6978 : 23189554 : if (nonnull)
6979 : 3638149 : set_ptr_nonnull (p);
6980 : 24163769 : }
6981 : :
6982 : :
6983 : : /* Query statistics for points-to solutions. */
6984 : :
6985 : : static struct {
6986 : : unsigned HOST_WIDE_INT pt_solution_includes_may_alias;
6987 : : unsigned HOST_WIDE_INT pt_solution_includes_no_alias;
6988 : : unsigned HOST_WIDE_INT pt_solutions_intersect_may_alias;
6989 : : unsigned HOST_WIDE_INT pt_solutions_intersect_no_alias;
6990 : : } pta_stats;
6991 : :
6992 : : void
6993 : 0 : dump_pta_stats (FILE *s)
6994 : : {
6995 : 0 : fprintf (s, "\nPTA query stats:\n");
6996 : 0 : fprintf (s, " pt_solution_includes: "
6997 : : HOST_WIDE_INT_PRINT_DEC" disambiguations, "
6998 : : HOST_WIDE_INT_PRINT_DEC" queries\n",
6999 : : pta_stats.pt_solution_includes_no_alias,
7000 : 0 : pta_stats.pt_solution_includes_no_alias
7001 : 0 : + pta_stats.pt_solution_includes_may_alias);
7002 : 0 : fprintf (s, " pt_solutions_intersect: "
7003 : : HOST_WIDE_INT_PRINT_DEC" disambiguations, "
7004 : : HOST_WIDE_INT_PRINT_DEC" queries\n",
7005 : : pta_stats.pt_solutions_intersect_no_alias,
7006 : 0 : pta_stats.pt_solutions_intersect_no_alias
7007 : 0 : + pta_stats.pt_solutions_intersect_may_alias);
7008 : 0 : }
7009 : :
7010 : :
7011 : : /* Reset the points-to solution *PT to a conservative default
7012 : : (point to anything). */
7013 : :
7014 : : void
7015 : 66462471 : pt_solution_reset (struct pt_solution *pt)
7016 : : {
7017 : 66462471 : memset (pt, 0, sizeof (struct pt_solution));
7018 : 66462471 : pt->anything = true;
7019 : 66462471 : pt->null = true;
7020 : 66462471 : }
7021 : :
7022 : : /* Set the points-to solution *PT to point only to the variables
7023 : : in VARS. VARS_CONTAINS_GLOBAL specifies whether that contains
7024 : : global variables and VARS_CONTAINS_RESTRICT specifies whether
7025 : : it contains restrict tag variables. */
7026 : :
7027 : : void
7028 : 73064 : pt_solution_set (struct pt_solution *pt, bitmap vars,
7029 : : bool vars_contains_nonlocal)
7030 : : {
7031 : 73064 : memset (pt, 0, sizeof (struct pt_solution));
7032 : 73064 : pt->vars = vars;
7033 : 73064 : pt->vars_contains_nonlocal = vars_contains_nonlocal;
7034 : 73064 : pt->vars_contains_escaped
7035 : 146128 : = (cfun->gimple_df->escaped.anything
7036 : 73064 : || bitmap_intersect_p (cfun->gimple_df->escaped.vars, vars));
7037 : 73064 : }
7038 : :
7039 : : /* Set the points-to solution *PT to point only to the variable VAR. */
7040 : :
7041 : : void
7042 : 69895 : pt_solution_set_var (struct pt_solution *pt, tree var)
7043 : : {
7044 : 69895 : memset (pt, 0, sizeof (struct pt_solution));
7045 : 69895 : pt->vars = BITMAP_GGC_ALLOC ();
7046 : 69895 : bitmap_set_bit (pt->vars, DECL_PT_UID (var));
7047 : 69895 : pt->vars_contains_nonlocal = is_global_var (var);
7048 : 69895 : pt->vars_contains_escaped
7049 : 139790 : = (cfun->gimple_df->escaped.anything
7050 : 69895 : || bitmap_bit_p (cfun->gimple_df->escaped.vars, DECL_PT_UID (var)));
7051 : 69895 : }
7052 : :
7053 : : /* Computes the union of the points-to solutions *DEST and *SRC and
7054 : : stores the result in *DEST. This changes the points-to bitmap
7055 : : of *DEST and thus may not be used if that might be shared.
7056 : : The points-to bitmap of *SRC and *DEST will not be shared after
7057 : : this function if they were not before. */
7058 : :
7059 : : static void
7060 : 34 : pt_solution_ior_into (struct pt_solution *dest, struct pt_solution *src)
7061 : : {
7062 : 34 : dest->anything |= src->anything;
7063 : 34 : if (dest->anything)
7064 : : {
7065 : 0 : pt_solution_reset (dest);
7066 : 0 : return;
7067 : : }
7068 : :
7069 : 34 : dest->nonlocal |= src->nonlocal;
7070 : 34 : dest->escaped |= src->escaped;
7071 : 34 : dest->ipa_escaped |= src->ipa_escaped;
7072 : 34 : dest->null |= src->null;
7073 : 34 : dest->const_pool |= src->const_pool ;
7074 : 34 : dest->vars_contains_nonlocal |= src->vars_contains_nonlocal;
7075 : 34 : dest->vars_contains_escaped |= src->vars_contains_escaped;
7076 : 34 : dest->vars_contains_escaped_heap |= src->vars_contains_escaped_heap;
7077 : 34 : if (!src->vars)
7078 : : return;
7079 : :
7080 : 34 : if (!dest->vars)
7081 : 20 : dest->vars = BITMAP_GGC_ALLOC ();
7082 : 34 : bitmap_ior_into (dest->vars, src->vars);
7083 : : }
7084 : :
7085 : : /* Return true if the points-to solution *PT is empty. */
7086 : :
7087 : : bool
7088 : 11943 : pt_solution_empty_p (const pt_solution *pt)
7089 : : {
7090 : 11943 : if (pt->anything
7091 : 8514 : || pt->nonlocal)
7092 : : return false;
7093 : :
7094 : 247 : if (pt->vars
7095 : 247 : && !bitmap_empty_p (pt->vars))
7096 : : return false;
7097 : :
7098 : : /* If the solution includes ESCAPED, check if that is empty. */
7099 : 245 : if (pt->escaped
7100 : 245 : && !pt_solution_empty_p (&cfun->gimple_df->escaped))
7101 : : return false;
7102 : :
7103 : : /* If the solution includes ESCAPED, check if that is empty. */
7104 : 245 : if (pt->ipa_escaped
7105 : 245 : && !pt_solution_empty_p (&ipa_escaped_pt))
7106 : : return false;
7107 : :
7108 : : return true;
7109 : : }
7110 : :
7111 : : /* Return true if the points-to solution *PT only point to a single var, and
7112 : : return the var uid in *UID. */
7113 : :
7114 : : bool
7115 : 863414 : pt_solution_singleton_or_null_p (struct pt_solution *pt, unsigned *uid)
7116 : : {
7117 : 856682 : if (pt->anything || pt->nonlocal || pt->escaped || pt->ipa_escaped
7118 : 199830 : || pt->vars == NULL
7119 : 1063244 : || !bitmap_single_bit_set_p (pt->vars))
7120 : 669635 : return false;
7121 : :
7122 : 193779 : *uid = bitmap_first_set_bit (pt->vars);
7123 : 193779 : return true;
7124 : : }
7125 : :
7126 : : /* Return true if the points-to solution *PT includes global memory.
7127 : : If ESCAPED_LOCAL_P is true then escaped local variables are also
7128 : : considered global. */
7129 : :
7130 : : bool
7131 : 46487819 : pt_solution_includes_global (struct pt_solution *pt, bool escaped_local_p)
7132 : : {
7133 : 46487819 : if (pt->anything
7134 : 45667936 : || pt->nonlocal
7135 : 11516104 : || pt->vars_contains_nonlocal
7136 : : /* The following is a hack to make the malloc escape hack work.
7137 : : In reality we'd need different sets for escaped-through-return
7138 : : and escaped-to-callees and passes would need to be updated. */
7139 : 4021165 : || pt->vars_contains_escaped_heap)
7140 : : return true;
7141 : :
7142 : 2201323 : if (escaped_local_p && pt->vars_contains_escaped)
7143 : : return true;
7144 : :
7145 : : /* 'escaped' is also a placeholder so we have to look into it. */
7146 : 2200471 : if (pt->escaped)
7147 : 92 : return pt_solution_includes_global (&cfun->gimple_df->escaped,
7148 : 92 : escaped_local_p);
7149 : :
7150 : 2200379 : if (pt->ipa_escaped)
7151 : 27710 : return pt_solution_includes_global (&ipa_escaped_pt,
7152 : 27710 : escaped_local_p);
7153 : :
7154 : : return false;
7155 : : }
7156 : :
7157 : : /* Return true if the points-to solution *PT includes the variable
7158 : : declaration DECL. */
7159 : :
7160 : : static bool
7161 : 250470441 : pt_solution_includes_1 (struct pt_solution *pt, const_tree decl)
7162 : : {
7163 : 250470441 : if (pt->anything)
7164 : : return true;
7165 : :
7166 : 244916369 : if (pt->nonlocal
7167 : 244916369 : && is_global_var (decl))
7168 : : return true;
7169 : :
7170 : 226792723 : if (pt->vars
7171 : 226792723 : && bitmap_bit_p (pt->vars, DECL_PT_UID (decl)))
7172 : : return true;
7173 : :
7174 : : /* If the solution includes ESCAPED, check it. */
7175 : 178465927 : if (pt->escaped
7176 : 178465927 : && pt_solution_includes_1 (&cfun->gimple_df->escaped, decl))
7177 : : return true;
7178 : :
7179 : : /* If the solution includes ESCAPED, check it. */
7180 : 153645082 : if (pt->ipa_escaped
7181 : 153645082 : && pt_solution_includes_1 (&ipa_escaped_pt, decl))
7182 : : return true;
7183 : :
7184 : : return false;
7185 : : }
7186 : :
7187 : : bool
7188 : 167298010 : pt_solution_includes (struct pt_solution *pt, const_tree decl)
7189 : : {
7190 : 167298010 : bool res = pt_solution_includes_1 (pt, decl);
7191 : 167298010 : if (res)
7192 : 72004514 : ++pta_stats.pt_solution_includes_may_alias;
7193 : : else
7194 : 95293496 : ++pta_stats.pt_solution_includes_no_alias;
7195 : 167298010 : return res;
7196 : : }
7197 : :
7198 : : /* Return true if the points-to solution *PT contains a reference to a
7199 : : constant pool entry. */
7200 : :
7201 : : bool
7202 : 6765921 : pt_solution_includes_const_pool (struct pt_solution *pt)
7203 : : {
7204 : 6765921 : return (pt->const_pool
7205 : 6604734 : || pt->nonlocal
7206 : 421400 : || (pt->escaped && (!cfun || cfun->gimple_df->escaped.const_pool))
7207 : 7187321 : || (pt->ipa_escaped && ipa_escaped_pt.const_pool));
7208 : : }
7209 : :
7210 : : /* Return true if both points-to solutions PT1 and PT2 have a non-empty
7211 : : intersection. */
7212 : :
7213 : : static bool
7214 : 81895615 : pt_solutions_intersect_1 (struct pt_solution *pt1, struct pt_solution *pt2)
7215 : : {
7216 : 81895615 : if (pt1->anything || pt2->anything)
7217 : : return true;
7218 : :
7219 : : /* If either points to unknown global memory and the other points to
7220 : : any global memory they alias. */
7221 : 79451946 : if ((pt1->nonlocal
7222 : 55969201 : && (pt2->nonlocal
7223 : 13483274 : || pt2->vars_contains_nonlocal))
7224 : 35163498 : || (pt2->nonlocal
7225 : 8781506 : && pt1->vars_contains_nonlocal))
7226 : : return true;
7227 : :
7228 : : /* If either points to all escaped memory and the other points to
7229 : : any escaped memory they alias. */
7230 : 34831992 : if ((pt1->escaped
7231 : 8627459 : && (pt2->escaped
7232 : 8627459 : || pt2->vars_contains_escaped))
7233 : 31825995 : || (pt2->escaped
7234 : 6901047 : && pt1->vars_contains_escaped))
7235 : : return true;
7236 : :
7237 : : /* Check the escaped solution if required.
7238 : : ??? Do we need to check the local against the IPA escaped sets? */
7239 : 29904106 : if ((pt1->ipa_escaped || pt2->ipa_escaped)
7240 : 29915069 : && !pt_solution_empty_p (&ipa_escaped_pt))
7241 : : {
7242 : : /* If both point to escaped memory and that solution
7243 : : is not empty they alias. */
7244 : 10960 : if (pt1->ipa_escaped && pt2->ipa_escaped)
7245 : : return true;
7246 : :
7247 : : /* If either points to escaped memory see if the escaped solution
7248 : : intersects with the other. */
7249 : 10960 : if ((pt1->ipa_escaped
7250 : 1246 : && pt_solutions_intersect_1 (&ipa_escaped_pt, pt2))
7251 : 11156 : || (pt2->ipa_escaped
7252 : 9714 : && pt_solutions_intersect_1 (&ipa_escaped_pt, pt1)))
7253 : 10392 : return true;
7254 : : }
7255 : :
7256 : : /* Now both pointers alias if their points-to solution intersects. */
7257 : 29894963 : return (pt1->vars
7258 : 29894947 : && pt2->vars
7259 : 59789910 : && bitmap_intersect_p (pt1->vars, pt2->vars));
7260 : : }
7261 : :
7262 : : bool
7263 : 81884655 : pt_solutions_intersect (struct pt_solution *pt1, struct pt_solution *pt2)
7264 : : {
7265 : 81884655 : bool res = pt_solutions_intersect_1 (pt1, pt2);
7266 : 81884655 : if (res)
7267 : 55398828 : ++pta_stats.pt_solutions_intersect_may_alias;
7268 : : else
7269 : 26485827 : ++pta_stats.pt_solutions_intersect_no_alias;
7270 : 81884655 : return res;
7271 : : }
7272 : :
7273 : : /* Dump stats information to OUTFILE. */
7274 : :
7275 : : static void
7276 : 149 : dump_sa_stats (FILE *outfile)
7277 : : {
7278 : 149 : fprintf (outfile, "Points-to Stats:\n");
7279 : 149 : fprintf (outfile, "Total vars: %d\n", stats.total_vars);
7280 : 149 : fprintf (outfile, "Non-pointer vars: %d\n",
7281 : : stats.nonpointer_vars);
7282 : 149 : fprintf (outfile, "Statically unified vars: %d\n",
7283 : : stats.unified_vars_static);
7284 : 149 : fprintf (outfile, "Dynamically unified vars: %d\n",
7285 : : stats.unified_vars_dynamic);
7286 : 149 : fprintf (outfile, "Iterations: %d\n", stats.iterations);
7287 : 149 : fprintf (outfile, "Number of edges: %d\n", stats.num_edges);
7288 : 149 : fprintf (outfile, "Number of implicit edges: %d\n",
7289 : : stats.num_implicit_edges);
7290 : 149 : fprintf (outfile, "Number of avoided edges: %d\n",
7291 : : stats.num_avoided_edges);
7292 : 149 : }
7293 : :
7294 : : /* Dump points-to information to OUTFILE. */
7295 : :
7296 : : static void
7297 : 299 : dump_sa_points_to_info (FILE *outfile)
7298 : : {
7299 : 299 : fprintf (outfile, "\nPoints-to sets\n\n");
7300 : :
7301 : 6763 : for (unsigned i = 1; i < varmap.length (); i++)
7302 : : {
7303 : 6464 : varinfo_t vi = get_varinfo (i);
7304 : 6464 : if (!vi->may_have_pointers)
7305 : 650 : continue;
7306 : 5814 : dump_solution_for_var (outfile, i);
7307 : : }
7308 : 299 : }
7309 : :
7310 : :
7311 : : /* Debug points-to information to stderr. */
7312 : :
7313 : : DEBUG_FUNCTION void
7314 : 0 : debug_sa_points_to_info (void)
7315 : : {
7316 : 0 : dump_sa_points_to_info (stderr);
7317 : 0 : }
7318 : :
7319 : :
7320 : : /* Initialize the always-existing constraint variables for NULL
7321 : : ANYTHING, READONLY, and INTEGER */
7322 : :
7323 : : static void
7324 : 4408981 : init_base_vars (void)
7325 : : {
7326 : 4408981 : struct constraint_expr lhs, rhs;
7327 : 4408981 : varinfo_t var_anything;
7328 : 4408981 : varinfo_t var_nothing;
7329 : 4408981 : varinfo_t var_string;
7330 : 4408981 : varinfo_t var_escaped;
7331 : 4408981 : varinfo_t var_nonlocal;
7332 : 4408981 : varinfo_t var_escaped_return;
7333 : 4408981 : varinfo_t var_storedanything;
7334 : 4408981 : varinfo_t var_integer;
7335 : :
7336 : : /* Variable ID zero is reserved and should be NULL. */
7337 : 4408981 : varmap.safe_push (NULL);
7338 : :
7339 : : /* Create the NULL variable, used to represent that a variable points
7340 : : to NULL. */
7341 : 4408981 : var_nothing = new_var_info (NULL_TREE, "NULL", false);
7342 : 4408981 : gcc_assert (var_nothing->id == nothing_id);
7343 : 4408981 : var_nothing->is_artificial_var = 1;
7344 : 4408981 : var_nothing->offset = 0;
7345 : 4408981 : var_nothing->size = ~0;
7346 : 4408981 : var_nothing->fullsize = ~0;
7347 : 4408981 : var_nothing->is_special_var = 1;
7348 : 4408981 : var_nothing->may_have_pointers = 0;
7349 : 4408981 : var_nothing->is_global_var = 0;
7350 : :
7351 : : /* Create the ANYTHING variable, used to represent that a variable
7352 : : points to some unknown piece of memory. */
7353 : 4408981 : var_anything = new_var_info (NULL_TREE, "ANYTHING", false);
7354 : 4408981 : gcc_assert (var_anything->id == anything_id);
7355 : 4408981 : var_anything->is_artificial_var = 1;
7356 : 4408981 : var_anything->size = ~0;
7357 : 4408981 : var_anything->offset = 0;
7358 : 4408981 : var_anything->fullsize = ~0;
7359 : 4408981 : var_anything->is_special_var = 1;
7360 : :
7361 : : /* Anything points to anything. This makes deref constraints just
7362 : : work in the presence of linked list and other p = *p type loops,
7363 : : by saying that *ANYTHING = ANYTHING. */
7364 : 4408981 : lhs.type = SCALAR;
7365 : 4408981 : lhs.var = anything_id;
7366 : 4408981 : lhs.offset = 0;
7367 : 4408981 : rhs.type = ADDRESSOF;
7368 : 4408981 : rhs.var = anything_id;
7369 : 4408981 : rhs.offset = 0;
7370 : :
7371 : : /* This specifically does not use process_constraint because
7372 : : process_constraint ignores all anything = anything constraints, since all
7373 : : but this one are redundant. */
7374 : 4408981 : constraints.safe_push (new_constraint (lhs, rhs));
7375 : :
7376 : : /* Create the STRING variable, used to represent that a variable
7377 : : points to a string literal. String literals don't contain
7378 : : pointers so STRING doesn't point to anything. */
7379 : 4408981 : var_string = new_var_info (NULL_TREE, "STRING", false);
7380 : 4408981 : gcc_assert (var_string->id == string_id);
7381 : 4408981 : var_string->is_artificial_var = 1;
7382 : 4408981 : var_string->offset = 0;
7383 : 4408981 : var_string->size = ~0;
7384 : 4408981 : var_string->fullsize = ~0;
7385 : 4408981 : var_string->is_special_var = 1;
7386 : 4408981 : var_string->may_have_pointers = 0;
7387 : :
7388 : : /* Create the ESCAPED variable, used to represent the set of escaped
7389 : : memory. */
7390 : 4408981 : var_escaped = new_var_info (NULL_TREE, "ESCAPED", false);
7391 : 4408981 : gcc_assert (var_escaped->id == escaped_id);
7392 : 4408981 : var_escaped->is_artificial_var = 1;
7393 : 4408981 : var_escaped->offset = 0;
7394 : 4408981 : var_escaped->size = ~0;
7395 : 4408981 : var_escaped->fullsize = ~0;
7396 : 4408981 : var_escaped->is_special_var = 0;
7397 : :
7398 : : /* Create the NONLOCAL variable, used to represent the set of nonlocal
7399 : : memory. */
7400 : 4408981 : var_nonlocal = new_var_info (NULL_TREE, "NONLOCAL", false);
7401 : 4408981 : gcc_assert (var_nonlocal->id == nonlocal_id);
7402 : 4408981 : var_nonlocal->is_artificial_var = 1;
7403 : 4408981 : var_nonlocal->offset = 0;
7404 : 4408981 : var_nonlocal->size = ~0;
7405 : 4408981 : var_nonlocal->fullsize = ~0;
7406 : 4408981 : var_nonlocal->is_special_var = 1;
7407 : :
7408 : : /* Create the ESCAPED_RETURN variable, used to represent the set of escaped
7409 : : memory via a regular return stmt. */
7410 : 4408981 : var_escaped_return = new_var_info (NULL_TREE, "ESCAPED_RETURN", false);
7411 : 4408981 : gcc_assert (var_escaped_return->id == escaped_return_id);
7412 : 4408981 : var_escaped_return->is_artificial_var = 1;
7413 : 4408981 : var_escaped_return->offset = 0;
7414 : 4408981 : var_escaped_return->size = ~0;
7415 : 4408981 : var_escaped_return->fullsize = ~0;
7416 : 4408981 : var_escaped_return->is_special_var = 0;
7417 : :
7418 : : /* ESCAPED = *ESCAPED, because escaped is may-deref'd at calls, etc. */
7419 : 4408981 : lhs.type = SCALAR;
7420 : 4408981 : lhs.var = escaped_id;
7421 : 4408981 : lhs.offset = 0;
7422 : 4408981 : rhs.type = DEREF;
7423 : 4408981 : rhs.var = escaped_id;
7424 : 4408981 : rhs.offset = 0;
7425 : 4408981 : process_constraint (new_constraint (lhs, rhs));
7426 : :
7427 : : /* ESCAPED = ESCAPED + UNKNOWN_OFFSET, because if a sub-field escapes the
7428 : : whole variable escapes. */
7429 : 4408981 : lhs.type = SCALAR;
7430 : 4408981 : lhs.var = escaped_id;
7431 : 4408981 : lhs.offset = 0;
7432 : 4408981 : rhs.type = SCALAR;
7433 : 4408981 : rhs.var = escaped_id;
7434 : 4408981 : rhs.offset = UNKNOWN_OFFSET;
7435 : 4408981 : process_constraint (new_constraint (lhs, rhs));
7436 : :
7437 : : /* *ESCAPED = NONLOCAL. This is true because we have to assume
7438 : : everything pointed to by escaped points to what global memory can
7439 : : point to. */
7440 : 4408981 : lhs.type = DEREF;
7441 : 4408981 : lhs.var = escaped_id;
7442 : 4408981 : lhs.offset = 0;
7443 : 4408981 : rhs.type = SCALAR;
7444 : 4408981 : rhs.var = nonlocal_id;
7445 : 4408981 : rhs.offset = 0;
7446 : 4408981 : process_constraint (new_constraint (lhs, rhs));
7447 : :
7448 : : /* NONLOCAL = &NONLOCAL, NONLOCAL = &ESCAPED. This is true because
7449 : : global memory may point to global memory and escaped memory. */
7450 : 4408981 : lhs.type = SCALAR;
7451 : 4408981 : lhs.var = nonlocal_id;
7452 : 4408981 : lhs.offset = 0;
7453 : 4408981 : rhs.type = ADDRESSOF;
7454 : 4408981 : rhs.var = nonlocal_id;
7455 : 4408981 : rhs.offset = 0;
7456 : 4408981 : process_constraint (new_constraint (lhs, rhs));
7457 : 4408981 : rhs.type = ADDRESSOF;
7458 : 4408981 : rhs.var = escaped_id;
7459 : 4408981 : rhs.offset = 0;
7460 : 4408981 : process_constraint (new_constraint (lhs, rhs));
7461 : :
7462 : : /* Transitively close ESCAPED_RETURN.
7463 : : ESCAPED_RETURN = ESCAPED_RETURN + UNKNOWN_OFFSET
7464 : : ESCAPED_RETURN = *ESCAPED_RETURN. */
7465 : 4408981 : lhs.type = SCALAR;
7466 : 4408981 : lhs.var = escaped_return_id;
7467 : 4408981 : lhs.offset = 0;
7468 : 4408981 : rhs.type = SCALAR;
7469 : 4408981 : rhs.var = escaped_return_id;
7470 : 4408981 : rhs.offset = UNKNOWN_OFFSET;
7471 : 4408981 : process_constraint (new_constraint (lhs, rhs));
7472 : 4408981 : lhs.type = SCALAR;
7473 : 4408981 : lhs.var = escaped_return_id;
7474 : 4408981 : lhs.offset = 0;
7475 : 4408981 : rhs.type = DEREF;
7476 : 4408981 : rhs.var = escaped_return_id;
7477 : 4408981 : rhs.offset = 0;
7478 : 4408981 : process_constraint (new_constraint (lhs, rhs));
7479 : :
7480 : : /* Create the STOREDANYTHING variable, used to represent the set of
7481 : : variables stored to *ANYTHING. */
7482 : 4408981 : var_storedanything = new_var_info (NULL_TREE, "STOREDANYTHING", false);
7483 : 4408981 : gcc_assert (var_storedanything->id == storedanything_id);
7484 : 4408981 : var_storedanything->is_artificial_var = 1;
7485 : 4408981 : var_storedanything->offset = 0;
7486 : 4408981 : var_storedanything->size = ~0;
7487 : 4408981 : var_storedanything->fullsize = ~0;
7488 : 4408981 : var_storedanything->is_special_var = 0;
7489 : :
7490 : : /* Create the INTEGER variable, used to represent that a variable points
7491 : : to what an INTEGER "points to". */
7492 : 4408981 : var_integer = new_var_info (NULL_TREE, "INTEGER", false);
7493 : 4408981 : gcc_assert (var_integer->id == integer_id);
7494 : 4408981 : var_integer->is_artificial_var = 1;
7495 : 4408981 : var_integer->size = ~0;
7496 : 4408981 : var_integer->fullsize = ~0;
7497 : 4408981 : var_integer->offset = 0;
7498 : 4408981 : var_integer->is_special_var = 1;
7499 : :
7500 : : /* INTEGER = ANYTHING, because we don't know where a dereference of
7501 : : a random integer will point to. */
7502 : 4408981 : lhs.type = SCALAR;
7503 : 4408981 : lhs.var = integer_id;
7504 : 4408981 : lhs.offset = 0;
7505 : 4408981 : rhs.type = ADDRESSOF;
7506 : 4408981 : rhs.var = anything_id;
7507 : 4408981 : rhs.offset = 0;
7508 : 4408981 : process_constraint (new_constraint (lhs, rhs));
7509 : 4408981 : }
7510 : :
7511 : : /* Initialize things necessary to perform PTA */
7512 : :
7513 : : static void
7514 : 4408981 : init_alias_vars (void)
7515 : : {
7516 : 4408981 : use_field_sensitive = (param_max_fields_for_field_sensitive > 1);
7517 : :
7518 : 4408981 : bitmap_obstack_initialize (&pta_obstack);
7519 : 4408981 : bitmap_obstack_initialize (&oldpta_obstack);
7520 : 4408981 : bitmap_obstack_initialize (&predbitmap_obstack);
7521 : :
7522 : 4408981 : constraints.create (8);
7523 : 4408981 : varmap.create (8);
7524 : 4408981 : vi_for_tree = new hash_map<tree, varinfo_t>;
7525 : 4408981 : call_stmt_vars = new hash_map<gimple *, varinfo_t>;
7526 : :
7527 : 4408981 : memset (&stats, 0, sizeof (stats));
7528 : 4408981 : shared_bitmap_table = new hash_table<shared_bitmap_hasher> (511);
7529 : 4408981 : init_base_vars ();
7530 : :
7531 : 4408981 : gcc_obstack_init (&fake_var_decl_obstack);
7532 : :
7533 : 4408981 : final_solutions = new hash_map<varinfo_t, pt_solution *>;
7534 : 4408981 : gcc_obstack_init (&final_solutions_obstack);
7535 : 4408981 : }
7536 : :
7537 : : /* Remove the REF and ADDRESS edges from GRAPH, as well as all the
7538 : : predecessor edges. */
7539 : :
7540 : : static void
7541 : 4408981 : remove_preds_and_fake_succs (constraint_graph_t graph)
7542 : : {
7543 : 4408981 : unsigned int i;
7544 : :
7545 : : /* Clear the implicit ref and address nodes from the successor
7546 : : lists. */
7547 : 225962770 : for (i = 1; i < FIRST_REF_NODE; i++)
7548 : : {
7549 : 221553789 : if (graph->succs[i])
7550 : 64421857 : bitmap_clear_range (graph->succs[i], FIRST_REF_NODE,
7551 : 64421857 : FIRST_REF_NODE * 2);
7552 : : }
7553 : :
7554 : : /* Free the successor list for the non-ref nodes. */
7555 : 230371751 : for (i = FIRST_REF_NODE + 1; i < graph->size; i++)
7556 : : {
7557 : 221553789 : if (graph->succs[i])
7558 : 11740912 : BITMAP_FREE (graph->succs[i]);
7559 : : }
7560 : :
7561 : : /* Now reallocate the size of the successor list as, and blow away
7562 : : the predecessor bitmaps. */
7563 : 4408981 : graph->size = varmap.length ();
7564 : 4408981 : graph->succs = XRESIZEVEC (bitmap, graph->succs, graph->size);
7565 : :
7566 : 4408981 : free (graph->implicit_preds);
7567 : 4408981 : graph->implicit_preds = NULL;
7568 : 4408981 : free (graph->preds);
7569 : 4408981 : graph->preds = NULL;
7570 : 4408981 : bitmap_obstack_release (&predbitmap_obstack);
7571 : 4408981 : }
7572 : :
7573 : : /* Solve the constraint set. */
7574 : :
7575 : : static void
7576 : 4408981 : solve_constraints (void)
7577 : : {
7578 : 4408981 : class scc_info *si;
7579 : :
7580 : : /* Sort varinfos so that ones that cannot be pointed to are last.
7581 : : This makes bitmaps more efficient. */
7582 : 4408981 : unsigned int *map = XNEWVEC (unsigned int, varmap.length ());
7583 : 44089810 : for (unsigned i = 0; i < integer_id + 1; ++i)
7584 : 39680829 : map[i] = i;
7585 : : /* Start with address-taken vars, followed by not address-taken vars
7586 : : to move vars never appearing in the points-to solution bitmaps last. */
7587 : : unsigned j = integer_id + 1;
7588 : 381381844 : for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
7589 : 186281941 : if (varmap[varmap[i]->head]->address_taken)
7590 : 15162407 : map[i] = j++;
7591 : 190690922 : for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
7592 : 186281941 : if (! varmap[varmap[i]->head]->address_taken)
7593 : 171119534 : map[i] = j++;
7594 : : /* Shuffle varmap according to map. */
7595 : 190690922 : for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
7596 : : {
7597 : 276433889 : while (map[varmap[i]->id] != i)
7598 : 90151948 : std::swap (varmap[i], varmap[map[varmap[i]->id]]);
7599 : 186281941 : gcc_assert (bitmap_empty_p (varmap[i]->solution));
7600 : 186281941 : varmap[i]->id = i;
7601 : 186281941 : varmap[i]->next = map[varmap[i]->next];
7602 : 186281941 : varmap[i]->head = map[varmap[i]->head];
7603 : : }
7604 : : /* Finally rewrite constraints. */
7605 : 440477990 : for (unsigned i = 0; i < constraints.length (); ++i)
7606 : : {
7607 : 436069009 : constraints[i]->lhs.var = map[constraints[i]->lhs.var];
7608 : 436069009 : constraints[i]->rhs.var = map[constraints[i]->rhs.var];
7609 : : }
7610 : 4408981 : free (map);
7611 : :
7612 : 4408981 : if (dump_file)
7613 : 479 : fprintf (dump_file,
7614 : : "\nCollapsing static cycles and doing variable "
7615 : : "substitution\n");
7616 : :
7617 : 8817962 : init_graph (varmap.length () * 2);
7618 : :
7619 : 4408981 : if (dump_file)
7620 : 479 : fprintf (dump_file, "Building predecessor graph\n");
7621 : 4408981 : build_pred_graph ();
7622 : :
7623 : 4408981 : if (dump_file)
7624 : 479 : fprintf (dump_file, "Detecting pointer and location "
7625 : : "equivalences\n");
7626 : 4408981 : si = perform_var_substitution (graph);
7627 : :
7628 : 4408981 : if (dump_file)
7629 : 479 : fprintf (dump_file, "Rewriting constraints and unifying "
7630 : : "variables\n");
7631 : 4408981 : rewrite_constraints (graph, si);
7632 : :
7633 : 4408981 : build_succ_graph ();
7634 : :
7635 : 4408981 : free_var_substitution_info (si);
7636 : :
7637 : : /* Attach complex constraints to graph nodes. */
7638 : 4408981 : move_complex_constraints (graph);
7639 : :
7640 : 4408981 : if (dump_file)
7641 : 479 : fprintf (dump_file, "Uniting pointer but not location equivalent "
7642 : : "variables\n");
7643 : 4408981 : unite_pointer_equivalences (graph);
7644 : :
7645 : 4408981 : if (dump_file)
7646 : 479 : fprintf (dump_file, "Finding indirect cycles\n");
7647 : 4408981 : find_indirect_cycles (graph);
7648 : :
7649 : : /* Implicit nodes and predecessors are no longer necessary at this
7650 : : point. */
7651 : 4408981 : remove_preds_and_fake_succs (graph);
7652 : :
7653 : 4408981 : if (dump_file && (dump_flags & TDF_GRAPH))
7654 : : {
7655 : 3 : fprintf (dump_file, "\n\n// The constraint graph before solve-graph "
7656 : : "in dot format:\n");
7657 : 3 : dump_constraint_graph (dump_file);
7658 : 3 : fprintf (dump_file, "\n\n");
7659 : : }
7660 : :
7661 : 4408981 : if (dump_file)
7662 : 479 : fprintf (dump_file, "Solving graph\n");
7663 : :
7664 : 4408981 : solve_graph (graph);
7665 : :
7666 : 4408981 : if (dump_file && (dump_flags & TDF_GRAPH))
7667 : : {
7668 : 3 : fprintf (dump_file, "\n\n// The constraint graph after solve-graph "
7669 : : "in dot format:\n");
7670 : 3 : dump_constraint_graph (dump_file);
7671 : 3 : fprintf (dump_file, "\n\n");
7672 : : }
7673 : 4408981 : }
7674 : :
7675 : : /* Create points-to sets for the current function. See the comments
7676 : : at the start of the file for an algorithmic overview. */
7677 : :
7678 : : static void
7679 : 4404575 : compute_points_to_sets (void)
7680 : : {
7681 : 4404575 : basic_block bb;
7682 : 4404575 : varinfo_t vi;
7683 : :
7684 : 4404575 : timevar_push (TV_TREE_PTA);
7685 : :
7686 : 4404575 : init_alias_vars ();
7687 : :
7688 : 4404575 : intra_create_variable_infos (cfun);
7689 : :
7690 : : /* Now walk all statements and build the constraint set. */
7691 : 39457147 : FOR_EACH_BB_FN (bb, cfun)
7692 : : {
7693 : 47135842 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
7694 : 12083270 : gsi_next (&gsi))
7695 : : {
7696 : 12083270 : gphi *phi = gsi.phi ();
7697 : :
7698 : 24166540 : if (! virtual_operand_p (gimple_phi_result (phi)))
7699 : 6318091 : find_func_aliases (cfun, phi);
7700 : : }
7701 : :
7702 : 318953997 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
7703 : 248848853 : gsi_next (&gsi))
7704 : : {
7705 : 248848853 : gimple *stmt = gsi_stmt (gsi);
7706 : :
7707 : 248848853 : find_func_aliases (cfun, stmt);
7708 : : }
7709 : : }
7710 : :
7711 : 4404575 : if (dump_file && (dump_flags & TDF_DETAILS))
7712 : : {
7713 : 282 : fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n");
7714 : 282 : dump_constraints (dump_file, 0);
7715 : : }
7716 : :
7717 : : /* From the constraints compute the points-to sets. */
7718 : 4404575 : solve_constraints ();
7719 : :
7720 : 4404575 : if (dump_file && (dump_flags & TDF_STATS))
7721 : 149 : dump_sa_stats (dump_file);
7722 : :
7723 : 4404575 : if (dump_file && (dump_flags & TDF_DETAILS))
7724 : 282 : dump_sa_points_to_info (dump_file);
7725 : :
7726 : : /* Compute the points-to set for ESCAPED used for call-clobber analysis. */
7727 : 4404575 : cfun->gimple_df->escaped = find_what_var_points_to (cfun->decl,
7728 : : get_varinfo (escaped_id));
7729 : :
7730 : : /* Make sure the ESCAPED solution (which is used as placeholder in
7731 : : other solutions) does not reference itself. This simplifies
7732 : : points-to solution queries. */
7733 : 4404575 : cfun->gimple_df->escaped.escaped = 0;
7734 : :
7735 : : /* The ESCAPED_RETURN solution is what contains all memory that needs
7736 : : to be considered global. */
7737 : 4404575 : cfun->gimple_df->escaped_return
7738 : 4404575 : = find_what_var_points_to (cfun->decl, get_varinfo (escaped_return_id));
7739 : 4404575 : cfun->gimple_df->escaped_return.escaped = 1;
7740 : :
7741 : : /* Compute the points-to sets for pointer SSA_NAMEs. */
7742 : 4404575 : unsigned i;
7743 : 4404575 : tree ptr;
7744 : :
7745 : 163147486 : FOR_EACH_SSA_NAME (i, ptr, cfun)
7746 : : {
7747 : 125397248 : if (POINTER_TYPE_P (TREE_TYPE (ptr)))
7748 : 24056912 : find_what_p_points_to (cfun->decl, ptr);
7749 : : }
7750 : :
7751 : : /* Compute the call-used/clobbered sets. */
7752 : 39457147 : FOR_EACH_BB_FN (bb, cfun)
7753 : : {
7754 : 35052572 : gimple_stmt_iterator gsi;
7755 : :
7756 : 318953997 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
7757 : : {
7758 : 248848853 : gcall *stmt;
7759 : 248848853 : struct pt_solution *pt;
7760 : :
7761 : 248848853 : stmt = dyn_cast <gcall *> (gsi_stmt (gsi));
7762 : 248848853 : if (!stmt)
7763 : 231657304 : continue;
7764 : :
7765 : 17191549 : pt = gimple_call_use_set (stmt);
7766 : 17191549 : if (gimple_call_flags (stmt) & ECF_CONST)
7767 : 1519854 : memset (pt, 0, sizeof (struct pt_solution));
7768 : : else
7769 : : {
7770 : 15671695 : bool uses_global_memory = true;
7771 : 15671695 : bool reads_global_memory = true;
7772 : :
7773 : 15671695 : determine_global_memory_access (stmt, NULL,
7774 : : &reads_global_memory,
7775 : : &uses_global_memory);
7776 : 15671695 : if ((vi = lookup_call_use_vi (stmt)) != NULL)
7777 : : {
7778 : 14818869 : *pt = find_what_var_points_to (cfun->decl, vi);
7779 : : /* Escaped (and thus nonlocal) variables are always
7780 : : implicitly used by calls. */
7781 : : /* ??? ESCAPED can be empty even though NONLOCAL
7782 : : always escaped. */
7783 : 14818869 : if (uses_global_memory)
7784 : : {
7785 : 13346911 : pt->nonlocal = 1;
7786 : 13346911 : pt->escaped = 1;
7787 : : }
7788 : : }
7789 : 852826 : else if (uses_global_memory)
7790 : : {
7791 : : /* If there is nothing special about this call then
7792 : : we have made everything that is used also escape. */
7793 : 1807 : *pt = cfun->gimple_df->escaped;
7794 : 1807 : pt->nonlocal = 1;
7795 : : }
7796 : : else
7797 : 851019 : memset (pt, 0, sizeof (struct pt_solution));
7798 : : }
7799 : :
7800 : 17191549 : pt = gimple_call_clobber_set (stmt);
7801 : 17191549 : if (gimple_call_flags (stmt) & (ECF_CONST|ECF_PURE|ECF_NOVOPS))
7802 : 2793066 : memset (pt, 0, sizeof (struct pt_solution));
7803 : : else
7804 : : {
7805 : 14398483 : bool writes_global_memory = true;
7806 : :
7807 : 14398483 : determine_global_memory_access (stmt, &writes_global_memory,
7808 : : NULL, NULL);
7809 : :
7810 : 14398483 : if ((vi = lookup_call_clobber_vi (stmt)) != NULL)
7811 : : {
7812 : 13562272 : *pt = find_what_var_points_to (cfun->decl, vi);
7813 : : /* Escaped (and thus nonlocal) variables are always
7814 : : implicitly clobbered by calls. */
7815 : : /* ??? ESCAPED can be empty even though NONLOCAL
7816 : : always escaped. */
7817 : 13562272 : if (writes_global_memory)
7818 : : {
7819 : 12787758 : pt->nonlocal = 1;
7820 : 12787758 : pt->escaped = 1;
7821 : : }
7822 : : }
7823 : 836211 : else if (writes_global_memory)
7824 : : {
7825 : : /* If there is nothing special about this call then
7826 : : we have made everything that is used also escape. */
7827 : 482 : *pt = cfun->gimple_df->escaped;
7828 : 482 : pt->nonlocal = 1;
7829 : : }
7830 : : else
7831 : 835729 : memset (pt, 0, sizeof (struct pt_solution));
7832 : : }
7833 : : }
7834 : : }
7835 : :
7836 : 4404575 : timevar_pop (TV_TREE_PTA);
7837 : 4404575 : }
7838 : :
7839 : :
7840 : : /* Delete created points-to sets. */
7841 : :
7842 : : static void
7843 : 4408981 : delete_points_to_sets (void)
7844 : : {
7845 : 4408981 : unsigned int i;
7846 : :
7847 : 4408981 : delete shared_bitmap_table;
7848 : 4408981 : shared_bitmap_table = NULL;
7849 : 4408981 : if (dump_file && (dump_flags & TDF_STATS))
7850 : 149 : fprintf (dump_file, "Points to sets created:%d\n",
7851 : : stats.points_to_sets_created);
7852 : :
7853 : 8817962 : delete vi_for_tree;
7854 : 8817962 : delete call_stmt_vars;
7855 : 4408981 : bitmap_obstack_release (&pta_obstack);
7856 : 4408981 : constraints.release ();
7857 : :
7858 : 234780732 : for (i = 0; i < graph->size; i++)
7859 : 225962770 : graph->complex[i].release ();
7860 : 4408981 : free (graph->complex);
7861 : :
7862 : 4408981 : free (graph->rep);
7863 : 4408981 : free (graph->succs);
7864 : 4408981 : free (graph->pe);
7865 : 4408981 : free (graph->pe_rep);
7866 : 4408981 : free (graph->indirect_cycles);
7867 : 4408981 : free (graph);
7868 : :
7869 : 4408981 : varmap.release ();
7870 : 4408981 : variable_info_pool.release ();
7871 : 4408981 : constraint_pool.release ();
7872 : :
7873 : 4408981 : obstack_free (&fake_var_decl_obstack, NULL);
7874 : :
7875 : 8817962 : delete final_solutions;
7876 : 4408981 : obstack_free (&final_solutions_obstack, NULL);
7877 : 4408981 : }
7878 : :
7879 : : struct vls_data
7880 : : {
7881 : : unsigned short clique;
7882 : : bool escaped_p;
7883 : : bitmap rvars;
7884 : : };
7885 : :
7886 : : /* Mark "other" loads and stores as belonging to CLIQUE and with
7887 : : base zero. */
7888 : :
7889 : : static bool
7890 : 4447158 : visit_loadstore (gimple *, tree base, tree ref, void *data)
7891 : : {
7892 : 4447158 : unsigned short clique = ((vls_data *) data)->clique;
7893 : 4447158 : bitmap rvars = ((vls_data *) data)->rvars;
7894 : 4447158 : bool escaped_p = ((vls_data *) data)->escaped_p;
7895 : 4447158 : if (TREE_CODE (base) == MEM_REF
7896 : 4447158 : || TREE_CODE (base) == TARGET_MEM_REF)
7897 : : {
7898 : 3268235 : tree ptr = TREE_OPERAND (base, 0);
7899 : 3268235 : if (TREE_CODE (ptr) == SSA_NAME)
7900 : : {
7901 : : /* For parameters, get at the points-to set for the actual parm
7902 : : decl. */
7903 : 3095053 : if (SSA_NAME_IS_DEFAULT_DEF (ptr)
7904 : 3095053 : && (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL
7905 : 62 : || TREE_CODE (SSA_NAME_VAR (ptr)) == RESULT_DECL))
7906 : 2244142 : ptr = SSA_NAME_VAR (ptr);
7907 : :
7908 : : /* We need to make sure 'ptr' doesn't include any of
7909 : : the restrict tags we added bases for in its points-to set. */
7910 : 3095053 : varinfo_t vi = lookup_vi_for_tree (ptr);
7911 : 3095053 : if (! vi)
7912 : : return false;
7913 : :
7914 : 3094991 : vi = get_varinfo (find (vi->id));
7915 : 3094991 : if (bitmap_intersect_p (rvars, vi->solution)
7916 : 3094991 : || (escaped_p && bitmap_bit_p (vi->solution, escaped_id)))
7917 : 2232573 : return false;
7918 : : }
7919 : :
7920 : : /* Do not overwrite existing cliques (that includes clique, base
7921 : : pairs we just set). */
7922 : 1035600 : if (MR_DEPENDENCE_CLIQUE (base) == 0)
7923 : : {
7924 : 873057 : MR_DEPENDENCE_CLIQUE (base) = clique;
7925 : 873057 : MR_DEPENDENCE_BASE (base) = 0;
7926 : : }
7927 : : }
7928 : :
7929 : : /* For plain decl accesses see whether they are accesses to globals
7930 : : and rewrite them to MEM_REFs with { clique, 0 }. */
7931 : 2214523 : if (VAR_P (base)
7932 : 1146707 : && is_global_var (base)
7933 : : /* ??? We can't rewrite a plain decl with the walk_stmt_load_store
7934 : : ops callback. */
7935 : 2272844 : && base != ref)
7936 : : {
7937 : : tree *basep = &ref;
7938 : 88966 : while (handled_component_p (*basep))
7939 : 56403 : basep = &TREE_OPERAND (*basep, 0);
7940 : 32563 : gcc_assert (VAR_P (*basep));
7941 : 32563 : tree ptr = build_fold_addr_expr (*basep);
7942 : 32563 : tree zero = build_int_cst (TREE_TYPE (ptr), 0);
7943 : 32563 : *basep = build2 (MEM_REF, TREE_TYPE (*basep), ptr, zero);
7944 : 32563 : MR_DEPENDENCE_CLIQUE (*basep) = clique;
7945 : 32563 : MR_DEPENDENCE_BASE (*basep) = 0;
7946 : : }
7947 : :
7948 : : return false;
7949 : : }
7950 : :
7951 : : struct msdi_data {
7952 : : tree ptr;
7953 : : unsigned short *clique;
7954 : : unsigned short *last_ruid;
7955 : : varinfo_t restrict_var;
7956 : : };
7957 : :
7958 : : /* If BASE is a MEM_REF then assign a clique, base pair to it, updating
7959 : : CLIQUE, *RESTRICT_VAR and LAST_RUID as passed via DATA.
7960 : : Return whether dependence info was assigned to BASE. */
7961 : :
7962 : : static bool
7963 : 2277069 : maybe_set_dependence_info (gimple *, tree base, tree, void *data)
7964 : : {
7965 : 2277069 : tree ptr = ((msdi_data *)data)->ptr;
7966 : 2277069 : unsigned short &clique = *((msdi_data *)data)->clique;
7967 : 2277069 : unsigned short &last_ruid = *((msdi_data *)data)->last_ruid;
7968 : 2277069 : varinfo_t restrict_var = ((msdi_data *)data)->restrict_var;
7969 : 2277069 : if ((TREE_CODE (base) == MEM_REF
7970 : 2277069 : || TREE_CODE (base) == TARGET_MEM_REF)
7971 : 2277069 : && TREE_OPERAND (base, 0) == ptr)
7972 : : {
7973 : : /* Do not overwrite existing cliques. This avoids overwriting dependence
7974 : : info inlined from a function with restrict parameters inlined
7975 : : into a function with restrict parameters. This usually means we
7976 : : prefer to be precise in innermost loops. */
7977 : 2151059 : if (MR_DEPENDENCE_CLIQUE (base) == 0)
7978 : : {
7979 : 1641732 : if (clique == 0)
7980 : : {
7981 : 356522 : if (cfun->last_clique == 0)
7982 : 161492 : cfun->last_clique = 1;
7983 : 356522 : clique = 1;
7984 : : }
7985 : 1641732 : if (restrict_var->ruid == 0)
7986 : 443158 : restrict_var->ruid = ++last_ruid;
7987 : 1641732 : MR_DEPENDENCE_CLIQUE (base) = clique;
7988 : 1641732 : MR_DEPENDENCE_BASE (base) = restrict_var->ruid;
7989 : 1641732 : return true;
7990 : : }
7991 : : }
7992 : : return false;
7993 : : }
7994 : :
7995 : : /* Clear dependence info for the clique DATA. */
7996 : :
7997 : : static bool
7998 : 18565152 : clear_dependence_clique (gimple *, tree base, tree, void *data)
7999 : : {
8000 : 18565152 : unsigned short clique = (uintptr_t)data;
8001 : 18565152 : if ((TREE_CODE (base) == MEM_REF
8002 : 18565152 : || TREE_CODE (base) == TARGET_MEM_REF)
8003 : 18565152 : && MR_DEPENDENCE_CLIQUE (base) == clique)
8004 : : {
8005 : 1058336 : MR_DEPENDENCE_CLIQUE (base) = 0;
8006 : 1058336 : MR_DEPENDENCE_BASE (base) = 0;
8007 : : }
8008 : :
8009 : 18565152 : return false;
8010 : : }
8011 : :
8012 : : /* Compute the set of independend memory references based on restrict
8013 : : tags and their conservative propagation to the points-to sets. */
8014 : :
8015 : : static void
8016 : 4404575 : compute_dependence_clique (void)
8017 : : {
8018 : : /* First clear the special "local" clique. */
8019 : 4404575 : basic_block bb;
8020 : 4404575 : if (cfun->last_clique != 0)
8021 : 10691506 : FOR_EACH_BB_FN (bb, cfun)
8022 : 20304804 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
8023 : 138732522 : !gsi_end_p (gsi); gsi_next (&gsi))
8024 : : {
8025 : 128580120 : gimple *stmt = gsi_stmt (gsi);
8026 : 128580120 : walk_stmt_load_store_ops (stmt, (void *)(uintptr_t) 1,
8027 : : clear_dependence_clique,
8028 : : clear_dependence_clique);
8029 : : }
8030 : :
8031 : 4404575 : unsigned short clique = 0;
8032 : 4404575 : unsigned short last_ruid = 0;
8033 : 4404575 : bitmap rvars = BITMAP_ALLOC (NULL);
8034 : 4404575 : bool escaped_p = false;
8035 : 167552061 : for (unsigned i = 0; i < num_ssa_names; ++i)
8036 : : {
8037 : 163147486 : tree ptr = ssa_name (i);
8038 : 163147486 : if (!ptr || !POINTER_TYPE_P (TREE_TYPE (ptr)))
8039 : 140064680 : continue;
8040 : :
8041 : : /* Avoid all this when ptr is not dereferenced? */
8042 : 24056912 : tree p = ptr;
8043 : 24056912 : if (SSA_NAME_IS_DEFAULT_DEF (ptr)
8044 : 24056912 : && (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL
8045 : 945428 : || TREE_CODE (SSA_NAME_VAR (ptr)) == RESULT_DECL))
8046 : 4213862 : p = SSA_NAME_VAR (ptr);
8047 : 24056912 : varinfo_t vi = lookup_vi_for_tree (p);
8048 : 24056912 : if (!vi)
8049 : 974106 : continue;
8050 : 23082806 : vi = get_varinfo (find (vi->id));
8051 : 23082806 : bitmap_iterator bi;
8052 : 23082806 : unsigned j;
8053 : 23082806 : varinfo_t restrict_var = NULL;
8054 : 28897853 : EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi)
8055 : : {
8056 : 27624956 : varinfo_t oi = get_varinfo (j);
8057 : 27624956 : if (oi->head != j)
8058 : 966292 : oi = get_varinfo (oi->head);
8059 : 27624956 : if (oi->is_restrict_var)
8060 : : {
8061 : 1796799 : if (restrict_var
8062 : 1796799 : && restrict_var != oi)
8063 : : {
8064 : 40 : if (dump_file && (dump_flags & TDF_DETAILS))
8065 : : {
8066 : 0 : fprintf (dump_file, "found restrict pointed-to "
8067 : : "for ");
8068 : 0 : print_generic_expr (dump_file, ptr);
8069 : 0 : fprintf (dump_file, " but not exclusively\n");
8070 : : }
8071 : : restrict_var = NULL;
8072 : : break;
8073 : : }
8074 : : restrict_var = oi;
8075 : : }
8076 : : /* NULL is the only other valid points-to entry. */
8077 : 25828157 : else if (oi->id != nothing_id)
8078 : : {
8079 : : restrict_var = NULL;
8080 : : break;
8081 : : }
8082 : : }
8083 : : /* Ok, found that ptr must(!) point to a single(!) restrict
8084 : : variable. */
8085 : : /* ??? PTA isn't really a proper propagation engine to compute
8086 : : this property.
8087 : : ??? We could handle merging of two restricts by unifying them. */
8088 : 23082766 : if (restrict_var)
8089 : : {
8090 : : /* Now look at possible dereferences of ptr. */
8091 : 839936 : imm_use_iterator ui;
8092 : 839936 : gimple *use_stmt;
8093 : 839936 : bool used = false;
8094 : 839936 : msdi_data data = { ptr, &clique, &last_ruid, restrict_var };
8095 : 4089151 : FOR_EACH_IMM_USE_STMT (use_stmt, ui, ptr)
8096 : 3249215 : used |= walk_stmt_load_store_ops (use_stmt, &data,
8097 : : maybe_set_dependence_info,
8098 : 839936 : maybe_set_dependence_info);
8099 : 839936 : if (used)
8100 : : {
8101 : : /* Add all subvars to the set of restrict pointed-to set. */
8102 : 2588676 : for (unsigned sv = restrict_var->head; sv != 0;
8103 : 1053126 : sv = get_varinfo (sv)->next)
8104 : 1053126 : bitmap_set_bit (rvars, sv);
8105 : 482424 : varinfo_t escaped = get_varinfo (find (escaped_id));
8106 : 482424 : if (bitmap_bit_p (escaped->solution, restrict_var->id))
8107 : 839936 : escaped_p = true;
8108 : : }
8109 : : }
8110 : : }
8111 : :
8112 : 4404575 : if (clique != 0)
8113 : : {
8114 : : /* Assign the BASE id zero to all accesses not based on a restrict
8115 : : pointer. That way they get disambiguated against restrict
8116 : : accesses but not against each other. */
8117 : : /* ??? For restricts derived from globals (thus not incoming
8118 : : parameters) we can't restrict scoping properly thus the following
8119 : : is too aggressive there. For now we have excluded those globals from
8120 : : getting into the MR_DEPENDENCE machinery. */
8121 : 356522 : vls_data data = { clique, escaped_p, rvars };
8122 : 356522 : basic_block bb;
8123 : 2950400 : FOR_EACH_BB_FN (bb, cfun)
8124 : 5187756 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
8125 : 20930751 : !gsi_end_p (gsi); gsi_next (&gsi))
8126 : : {
8127 : 18336873 : gimple *stmt = gsi_stmt (gsi);
8128 : 18336873 : walk_stmt_load_store_ops (stmt, &data,
8129 : : visit_loadstore, visit_loadstore);
8130 : : }
8131 : : }
8132 : :
8133 : 4404575 : BITMAP_FREE (rvars);
8134 : 4404575 : }
8135 : :
8136 : : /* Compute points-to information for every SSA_NAME pointer in the
8137 : : current function and compute the transitive closure of escaped
8138 : : variables to re-initialize the call-clobber states of local variables. */
8139 : :
8140 : : unsigned int
8141 : 4431094 : compute_may_aliases (void)
8142 : : {
8143 : 4431094 : if (cfun->gimple_df->ipa_pta)
8144 : : {
8145 : 26519 : if (dump_file)
8146 : : {
8147 : 0 : fprintf (dump_file, "\nNot re-computing points-to information "
8148 : : "because IPA points-to information is available.\n\n");
8149 : :
8150 : : /* But still dump what we have remaining it. */
8151 : 0 : if (dump_flags & (TDF_DETAILS|TDF_ALIAS))
8152 : 0 : dump_alias_info (dump_file);
8153 : : }
8154 : :
8155 : 26519 : return 0;
8156 : : }
8157 : :
8158 : : /* For each pointer P_i, determine the sets of variables that P_i may
8159 : : point-to. Compute the reachability set of escaped and call-used
8160 : : variables. */
8161 : 4404575 : compute_points_to_sets ();
8162 : :
8163 : : /* Debugging dumps. */
8164 : 4404575 : if (dump_file && (dump_flags & (TDF_DETAILS|TDF_ALIAS)))
8165 : 282 : dump_alias_info (dump_file);
8166 : :
8167 : : /* Compute restrict-based memory disambiguations. */
8168 : 4404575 : compute_dependence_clique ();
8169 : :
8170 : : /* Deallocate memory used by aliasing data structures and the internal
8171 : : points-to solution. */
8172 : 4404575 : delete_points_to_sets ();
8173 : :
8174 : 4404575 : gcc_assert (!need_ssa_update_p (cfun));
8175 : :
8176 : : return 0;
8177 : : }
8178 : :
8179 : : /* A dummy pass to cause points-to information to be computed via
8180 : : TODO_rebuild_alias. */
8181 : :
8182 : : namespace {
8183 : :
8184 : : const pass_data pass_data_build_alias =
8185 : : {
8186 : : GIMPLE_PASS, /* type */
8187 : : "alias", /* name */
8188 : : OPTGROUP_NONE, /* optinfo_flags */
8189 : : TV_NONE, /* tv_id */
8190 : : ( PROP_cfg | PROP_ssa ), /* properties_required */
8191 : : 0, /* properties_provided */
8192 : : 0, /* properties_destroyed */
8193 : : 0, /* todo_flags_start */
8194 : : TODO_rebuild_alias, /* todo_flags_finish */
8195 : : };
8196 : :
8197 : : class pass_build_alias : public gimple_opt_pass
8198 : : {
8199 : : public:
8200 : 285081 : pass_build_alias (gcc::context *ctxt)
8201 : 570162 : : gimple_opt_pass (pass_data_build_alias, ctxt)
8202 : : {}
8203 : :
8204 : : /* opt_pass methods: */
8205 : 1021582 : bool gate (function *) final override { return flag_tree_pta; }
8206 : :
8207 : : }; // class pass_build_alias
8208 : :
8209 : : } // anon namespace
8210 : :
8211 : : gimple_opt_pass *
8212 : 285081 : make_pass_build_alias (gcc::context *ctxt)
8213 : : {
8214 : 285081 : return new pass_build_alias (ctxt);
8215 : : }
8216 : :
8217 : : /* A dummy pass to cause points-to information to be computed via
8218 : : TODO_rebuild_alias. */
8219 : :
8220 : : namespace {
8221 : :
8222 : : const pass_data pass_data_build_ealias =
8223 : : {
8224 : : GIMPLE_PASS, /* type */
8225 : : "ealias", /* name */
8226 : : OPTGROUP_NONE, /* optinfo_flags */
8227 : : TV_NONE, /* tv_id */
8228 : : ( PROP_cfg | PROP_ssa ), /* properties_required */
8229 : : 0, /* properties_provided */
8230 : : 0, /* properties_destroyed */
8231 : : 0, /* todo_flags_start */
8232 : : TODO_rebuild_alias, /* todo_flags_finish */
8233 : : };
8234 : :
8235 : : class pass_build_ealias : public gimple_opt_pass
8236 : : {
8237 : : public:
8238 : 285081 : pass_build_ealias (gcc::context *ctxt)
8239 : 570162 : : gimple_opt_pass (pass_data_build_ealias, ctxt)
8240 : : {}
8241 : :
8242 : : /* opt_pass methods: */
8243 : 2441318 : bool gate (function *) final override { return flag_tree_pta; }
8244 : :
8245 : : }; // class pass_build_ealias
8246 : :
8247 : : } // anon namespace
8248 : :
8249 : : gimple_opt_pass *
8250 : 285081 : make_pass_build_ealias (gcc::context *ctxt)
8251 : : {
8252 : 285081 : return new pass_build_ealias (ctxt);
8253 : : }
8254 : :
8255 : :
8256 : : /* IPA PTA solutions for ESCAPED. */
8257 : : struct pt_solution ipa_escaped_pt
8258 : : = { true, false, false, false, false, false,
8259 : : false, false, false, false, false, NULL };
8260 : :
8261 : : /* Associate node with varinfo DATA. Worker for
8262 : : cgraph_for_symbol_thunks_and_aliases. */
8263 : : static bool
8264 : 23427 : associate_varinfo_to_alias (struct cgraph_node *node, void *data)
8265 : : {
8266 : 23427 : if ((node->alias
8267 : 23374 : || (node->thunk
8268 : 3 : && ! node->inlined_to))
8269 : 53 : && node->analyzed
8270 : 53 : && !node->ifunc_resolver)
8271 : 52 : insert_vi_for_tree (node->decl, (varinfo_t)data);
8272 : 23427 : return false;
8273 : : }
8274 : :
8275 : : /* Dump varinfo VI to FILE. */
8276 : :
8277 : : static void
8278 : 0 : dump_varinfo (FILE *file, varinfo_t vi)
8279 : : {
8280 : 0 : if (vi == NULL)
8281 : : return;
8282 : :
8283 : 0 : fprintf (file, "%u: %s\n", vi->id, vi->name);
8284 : :
8285 : 0 : const char *sep = " ";
8286 : 0 : if (vi->is_artificial_var)
8287 : 0 : fprintf (file, "%sartificial", sep);
8288 : 0 : if (vi->is_special_var)
8289 : 0 : fprintf (file, "%sspecial", sep);
8290 : 0 : if (vi->is_unknown_size_var)
8291 : 0 : fprintf (file, "%sunknown-size", sep);
8292 : 0 : if (vi->is_full_var)
8293 : 0 : fprintf (file, "%sfull", sep);
8294 : 0 : if (vi->is_heap_var)
8295 : 0 : fprintf (file, "%sheap", sep);
8296 : 0 : if (vi->may_have_pointers)
8297 : 0 : fprintf (file, "%smay-have-pointers", sep);
8298 : 0 : if (vi->only_restrict_pointers)
8299 : 0 : fprintf (file, "%sonly-restrict-pointers", sep);
8300 : 0 : if (vi->is_restrict_var)
8301 : 0 : fprintf (file, "%sis-restrict-var", sep);
8302 : 0 : if (vi->is_global_var)
8303 : 0 : fprintf (file, "%sglobal", sep);
8304 : 0 : if (vi->is_ipa_escape_point)
8305 : 0 : fprintf (file, "%sipa-escape-point", sep);
8306 : 0 : if (vi->is_fn_info)
8307 : 0 : fprintf (file, "%sfn-info", sep);
8308 : 0 : if (vi->ruid)
8309 : 0 : fprintf (file, "%srestrict-uid:%u", sep, vi->ruid);
8310 : 0 : if (vi->next)
8311 : 0 : fprintf (file, "%snext:%u", sep, vi->next);
8312 : 0 : if (vi->head != vi->id)
8313 : 0 : fprintf (file, "%shead:%u", sep, vi->head);
8314 : 0 : if (vi->offset)
8315 : 0 : fprintf (file, "%soffset:" HOST_WIDE_INT_PRINT_DEC, sep, vi->offset);
8316 : 0 : if (vi->size != ~HOST_WIDE_INT_0U)
8317 : 0 : fprintf (file, "%ssize:" HOST_WIDE_INT_PRINT_DEC, sep, vi->size);
8318 : 0 : if (vi->fullsize != ~HOST_WIDE_INT_0U && vi->fullsize != vi->size)
8319 : 0 : fprintf (file, "%sfullsize:" HOST_WIDE_INT_PRINT_DEC, sep,
8320 : : vi->fullsize);
8321 : 0 : fprintf (file, "\n");
8322 : :
8323 : 0 : if (vi->solution && !bitmap_empty_p (vi->solution))
8324 : : {
8325 : 0 : bitmap_iterator bi;
8326 : 0 : unsigned i;
8327 : 0 : fprintf (file, " solution: {");
8328 : 0 : EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
8329 : 0 : fprintf (file, " %u", i);
8330 : 0 : fprintf (file, " }\n");
8331 : : }
8332 : :
8333 : 0 : if (vi->oldsolution && !bitmap_empty_p (vi->oldsolution)
8334 : 0 : && !bitmap_equal_p (vi->solution, vi->oldsolution))
8335 : : {
8336 : 0 : bitmap_iterator bi;
8337 : 0 : unsigned i;
8338 : 0 : fprintf (file, " oldsolution: {");
8339 : 0 : EXECUTE_IF_SET_IN_BITMAP (vi->oldsolution, 0, i, bi)
8340 : 0 : fprintf (file, " %u", i);
8341 : 0 : fprintf (file, " }\n");
8342 : : }
8343 : : }
8344 : :
8345 : : /* Dump varinfo VI to stderr. */
8346 : :
8347 : : DEBUG_FUNCTION void
8348 : 0 : debug_varinfo (varinfo_t vi)
8349 : : {
8350 : 0 : dump_varinfo (stderr, vi);
8351 : 0 : }
8352 : :
8353 : : /* Dump varmap to FILE. */
8354 : :
8355 : : static void
8356 : 0 : dump_varmap (FILE *file)
8357 : : {
8358 : 0 : if (varmap.length () == 0)
8359 : : return;
8360 : :
8361 : 0 : fprintf (file, "variables:\n");
8362 : :
8363 : 0 : for (unsigned int i = 0; i < varmap.length (); ++i)
8364 : : {
8365 : 0 : varinfo_t vi = get_varinfo (i);
8366 : 0 : dump_varinfo (file, vi);
8367 : : }
8368 : :
8369 : 0 : fprintf (file, "\n");
8370 : : }
8371 : :
8372 : : /* Dump varmap to stderr. */
8373 : :
8374 : : DEBUG_FUNCTION void
8375 : 0 : debug_varmap (void)
8376 : : {
8377 : 0 : dump_varmap (stderr);
8378 : 0 : }
8379 : :
8380 : : /* Compute whether node is refered to non-locally. Worker for
8381 : : cgraph_for_symbol_thunks_and_aliases. */
8382 : : static bool
8383 : 23427 : refered_from_nonlocal_fn (struct cgraph_node *node, void *data)
8384 : : {
8385 : 23427 : bool *nonlocal_p = (bool *)data;
8386 : 46854 : *nonlocal_p |= (node->used_from_other_partition
8387 : 23381 : || DECL_EXTERNAL (node->decl)
8388 : 23376 : || TREE_PUBLIC (node->decl)
8389 : 16425 : || node->force_output
8390 : 39842 : || lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)));
8391 : 23427 : return false;
8392 : : }
8393 : :
8394 : : /* Same for varpool nodes. */
8395 : : static bool
8396 : 36725 : refered_from_nonlocal_var (struct varpool_node *node, void *data)
8397 : : {
8398 : 36725 : bool *nonlocal_p = (bool *)data;
8399 : 73450 : *nonlocal_p |= (node->used_from_other_partition
8400 : 36624 : || DECL_EXTERNAL (node->decl)
8401 : 36138 : || TREE_PUBLIC (node->decl)
8402 : 71801 : || node->force_output);
8403 : 36725 : return false;
8404 : : }
8405 : :
8406 : : /* Execute the driver for IPA PTA. */
8407 : : static unsigned int
8408 : 4406 : ipa_pta_execute (void)
8409 : : {
8410 : 4406 : struct cgraph_node *node;
8411 : 4406 : varpool_node *var;
8412 : 4406 : unsigned int from = 0;
8413 : :
8414 : 4406 : in_ipa_mode = 1;
8415 : :
8416 : 4406 : init_alias_vars ();
8417 : :
8418 : 4406 : if (dump_file && (dump_flags & TDF_DETAILS))
8419 : : {
8420 : 17 : symtab->dump (dump_file);
8421 : 17 : fprintf (dump_file, "\n");
8422 : : }
8423 : :
8424 : 4406 : if (dump_file && (dump_flags & TDF_DETAILS))
8425 : : {
8426 : 17 : fprintf (dump_file, "Generating generic constraints\n\n");
8427 : 17 : dump_constraints (dump_file, from);
8428 : 17 : fprintf (dump_file, "\n");
8429 : 17 : from = constraints.length ();
8430 : : }
8431 : :
8432 : : /* Build the constraints. */
8433 : 29028 : FOR_EACH_DEFINED_FUNCTION (node)
8434 : : {
8435 : 24622 : varinfo_t vi;
8436 : : /* Nodes without a body in this partition are not interesting.
8437 : : Especially do not visit clones at this point for now - we
8438 : : get duplicate decls there for inline clones at least. */
8439 : 25873 : if (!node->has_gimple_body_p ()
8440 : 24521 : || node->in_other_partition
8441 : 49143 : || node->inlined_to)
8442 : 1251 : continue;
8443 : 23371 : node->get_body ();
8444 : :
8445 : 23371 : gcc_assert (!node->clone_of);
8446 : :
8447 : : /* For externally visible or attribute used annotated functions use
8448 : : local constraints for their arguments.
8449 : : For local functions we see all callers and thus do not need initial
8450 : : constraints for parameters. */
8451 : 23371 : bool nonlocal_p = (node->used_from_other_partition
8452 : 23325 : || DECL_EXTERNAL (node->decl)
8453 : 23321 : || TREE_PUBLIC (node->decl)
8454 : 16421 : || node->force_output
8455 : 39782 : || lookup_attribute ("noipa",
8456 : 16411 : DECL_ATTRIBUTES (node->decl)));
8457 : 23371 : node->call_for_symbol_thunks_and_aliases (refered_from_nonlocal_fn,
8458 : : &nonlocal_p, true);
8459 : :
8460 : 23371 : vi = create_function_info_for (node->decl,
8461 : : alias_get_name (node->decl), false,
8462 : : nonlocal_p);
8463 : 54 : if (dump_file && (dump_flags & TDF_DETAILS)
8464 : 23423 : && from != constraints.length ())
8465 : : {
8466 : 22 : fprintf (dump_file,
8467 : : "Generating initial constraints for %s",
8468 : : node->dump_name ());
8469 : 22 : if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
8470 : 44 : fprintf (dump_file, " (%s)",
8471 : 22 : IDENTIFIER_POINTER
8472 : : (DECL_ASSEMBLER_NAME (node->decl)));
8473 : 22 : fprintf (dump_file, "\n\n");
8474 : 22 : dump_constraints (dump_file, from);
8475 : 22 : fprintf (dump_file, "\n");
8476 : :
8477 : 22 : from = constraints.length ();
8478 : : }
8479 : :
8480 : 23371 : node->call_for_symbol_thunks_and_aliases
8481 : 23371 : (associate_varinfo_to_alias, vi, true);
8482 : : }
8483 : :
8484 : : /* Create constraints for global variables and their initializers. */
8485 : 82262 : FOR_EACH_VARIABLE (var)
8486 : : {
8487 : 36725 : if (var->alias && var->analyzed)
8488 : 9 : continue;
8489 : :
8490 : 36716 : varinfo_t vi = get_vi_for_tree (var->decl);
8491 : :
8492 : : /* For the purpose of IPA PTA unit-local globals are not
8493 : : escape points. */
8494 : 36716 : bool nonlocal_p = (DECL_EXTERNAL (var->decl)
8495 : 36230 : || TREE_PUBLIC (var->decl)
8496 : 35068 : || var->used_from_other_partition
8497 : 71784 : || var->force_output);
8498 : 36716 : var->call_for_symbol_and_aliases (refered_from_nonlocal_var,
8499 : : &nonlocal_p, true);
8500 : 36716 : if (nonlocal_p)
8501 : 1653 : vi->is_ipa_escape_point = true;
8502 : : }
8503 : :
8504 : 19 : if (dump_file && (dump_flags & TDF_DETAILS)
8505 : 4423 : && from != constraints.length ())
8506 : : {
8507 : 11 : fprintf (dump_file,
8508 : : "Generating constraints for global initializers\n\n");
8509 : 11 : dump_constraints (dump_file, from);
8510 : 11 : fprintf (dump_file, "\n");
8511 : 11 : from = constraints.length ();
8512 : : }
8513 : :
8514 : 27830 : FOR_EACH_DEFINED_FUNCTION (node)
8515 : : {
8516 : 23424 : struct function *func;
8517 : 23424 : basic_block bb;
8518 : :
8519 : : /* Nodes without a body in this partition are not interesting. */
8520 : 23477 : if (!node->has_gimple_body_p ()
8521 : 23371 : || node->in_other_partition
8522 : 46795 : || node->clone_of)
8523 : 53 : continue;
8524 : :
8525 : 23371 : if (dump_file && (dump_flags & TDF_DETAILS))
8526 : : {
8527 : 52 : fprintf (dump_file,
8528 : : "Generating constraints for %s", node->dump_name ());
8529 : 52 : if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
8530 : 104 : fprintf (dump_file, " (%s)",
8531 : 52 : IDENTIFIER_POINTER
8532 : : (DECL_ASSEMBLER_NAME (node->decl)));
8533 : 52 : fprintf (dump_file, "\n");
8534 : : }
8535 : :
8536 : 23371 : func = DECL_STRUCT_FUNCTION (node->decl);
8537 : 23371 : gcc_assert (cfun == NULL);
8538 : :
8539 : : /* Build constriants for the function body. */
8540 : 354524 : FOR_EACH_BB_FN (bb, func)
8541 : : {
8542 : 438344 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
8543 : 107191 : gsi_next (&gsi))
8544 : : {
8545 : 107191 : gphi *phi = gsi.phi ();
8546 : :
8547 : 214382 : if (! virtual_operand_p (gimple_phi_result (phi)))
8548 : 63772 : find_func_aliases (func, phi);
8549 : : }
8550 : :
8551 : 1616114 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
8552 : 953808 : gsi_next (&gsi))
8553 : : {
8554 : 953808 : gimple *stmt = gsi_stmt (gsi);
8555 : :
8556 : 953808 : find_func_aliases (func, stmt);
8557 : 953808 : find_func_clobbers (func, stmt);
8558 : : }
8559 : : }
8560 : :
8561 : 23371 : if (dump_file && (dump_flags & TDF_DETAILS))
8562 : : {
8563 : 52 : fprintf (dump_file, "\n");
8564 : 52 : dump_constraints (dump_file, from);
8565 : 52 : fprintf (dump_file, "\n");
8566 : 23476 : from = constraints.length ();
8567 : : }
8568 : : }
8569 : :
8570 : : /* From the constraints compute the points-to sets. */
8571 : 4406 : solve_constraints ();
8572 : :
8573 : 4406 : if (dump_file && (dump_flags & TDF_STATS))
8574 : 0 : dump_sa_stats (dump_file);
8575 : :
8576 : 4406 : if (dump_file && (dump_flags & TDF_DETAILS))
8577 : 17 : dump_sa_points_to_info (dump_file);
8578 : :
8579 : : /* Now post-process solutions to handle locals from different
8580 : : runtime instantiations coming in through recursive invocations. */
8581 : : unsigned shadow_var_cnt = 0;
8582 : 1192154 : for (unsigned i = 1; i < varmap.length (); ++i)
8583 : : {
8584 : 1187748 : varinfo_t fi = get_varinfo (i);
8585 : 1187748 : if (fi->is_fn_info
8586 : 23371 : && fi->decl)
8587 : : /* Automatic variables pointed to by their containing functions
8588 : : parameters need this treatment. */
8589 : 23371 : for (varinfo_t ai = first_vi_for_offset (fi, fi_parm_base);
8590 : 48472 : ai; ai = vi_next (ai))
8591 : : {
8592 : 25101 : varinfo_t vi = get_varinfo (find (ai->id));
8593 : 25101 : bitmap_iterator bi;
8594 : 25101 : unsigned j;
8595 : 67056 : EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi)
8596 : : {
8597 : 41955 : varinfo_t pt = get_varinfo (j);
8598 : 41955 : if (pt->shadow_var_uid == 0
8599 : 40655 : && pt->decl
8600 : 58207 : && auto_var_in_fn_p (pt->decl, fi->decl))
8601 : : {
8602 : 56 : pt->shadow_var_uid = allocate_decl_uid ();
8603 : 56 : shadow_var_cnt++;
8604 : : }
8605 : : }
8606 : : }
8607 : : /* As well as global variables which are another way of passing
8608 : : arguments to recursive invocations. */
8609 : 1164377 : else if (fi->is_global_var)
8610 : : {
8611 : 827829 : for (varinfo_t ai = fi; ai; ai = vi_next (ai))
8612 : : {
8613 : 440758 : varinfo_t vi = get_varinfo (find (ai->id));
8614 : 440758 : bitmap_iterator bi;
8615 : 440758 : unsigned j;
8616 : 1785623 : EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi)
8617 : : {
8618 : 1344865 : varinfo_t pt = get_varinfo (j);
8619 : 1344865 : if (pt->shadow_var_uid == 0
8620 : 1075361 : && pt->decl
8621 : 1497271 : && auto_var_p (pt->decl))
8622 : : {
8623 : 39363 : pt->shadow_var_uid = allocate_decl_uid ();
8624 : 39363 : shadow_var_cnt++;
8625 : : }
8626 : : }
8627 : : }
8628 : : }
8629 : : }
8630 : 4406 : if (shadow_var_cnt && dump_file && (dump_flags & TDF_DETAILS))
8631 : 10 : fprintf (dump_file, "Allocated %u shadow variables for locals "
8632 : : "maybe leaking into recursive invocations of their containing "
8633 : : "functions\n", shadow_var_cnt);
8634 : :
8635 : : /* Compute the global points-to sets for ESCAPED.
8636 : : ??? Note that the computed escape set is not correct
8637 : : for the whole unit as we fail to consider graph edges to
8638 : : externally visible functions. */
8639 : 4406 : ipa_escaped_pt = find_what_var_points_to (NULL, get_varinfo (escaped_id));
8640 : :
8641 : : /* Make sure the ESCAPED solution (which is used as placeholder in
8642 : : other solutions) does not reference itself. This simplifies
8643 : : points-to solution queries. */
8644 : 4406 : ipa_escaped_pt.ipa_escaped = 0;
8645 : :
8646 : : /* Assign the points-to sets to the SSA names in the unit. */
8647 : 27830 : FOR_EACH_DEFINED_FUNCTION (node)
8648 : : {
8649 : 23424 : tree ptr;
8650 : 23424 : struct function *fn;
8651 : 23424 : unsigned i;
8652 : 23424 : basic_block bb;
8653 : :
8654 : : /* Nodes without a body in this partition are not interesting. */
8655 : 23477 : if (!node->has_gimple_body_p ()
8656 : 23371 : || node->in_other_partition
8657 : 46795 : || node->clone_of)
8658 : 53 : continue;
8659 : :
8660 : 23371 : fn = DECL_STRUCT_FUNCTION (node->decl);
8661 : :
8662 : : /* Compute the points-to sets for pointer SSA_NAMEs. */
8663 : 1136970 : FOR_EACH_VEC_ELT (*fn->gimple_df->ssa_names, i, ptr)
8664 : : {
8665 : 1113599 : if (ptr
8666 : 1113599 : && POINTER_TYPE_P (TREE_TYPE (ptr)))
8667 : 106857 : find_what_p_points_to (node->decl, ptr);
8668 : : }
8669 : :
8670 : : /* Compute the call-use and call-clobber sets for indirect calls
8671 : : and calls to external functions. */
8672 : 354524 : FOR_EACH_BB_FN (bb, fn)
8673 : : {
8674 : 331153 : gimple_stmt_iterator gsi;
8675 : :
8676 : 1616114 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
8677 : : {
8678 : 953808 : gcall *stmt;
8679 : 953808 : struct pt_solution *pt;
8680 : 953808 : varinfo_t vi, fi;
8681 : 953808 : tree decl;
8682 : :
8683 : 953808 : stmt = dyn_cast <gcall *> (gsi_stmt (gsi));
8684 : 953808 : if (!stmt)
8685 : 700622 : continue;
8686 : :
8687 : : /* Handle direct calls to functions with body. */
8688 : 253186 : decl = gimple_call_fndecl (stmt);
8689 : :
8690 : 253186 : {
8691 : 253186 : tree called_decl = NULL_TREE;
8692 : 253186 : if (gimple_call_builtin_p (stmt, BUILT_IN_GOMP_PARALLEL))
8693 : 13 : called_decl = TREE_OPERAND (gimple_call_arg (stmt, 0), 0);
8694 : 253173 : else if (gimple_call_builtin_p (stmt, BUILT_IN_GOACC_PARALLEL))
8695 : 13749 : called_decl = TREE_OPERAND (gimple_call_arg (stmt, 1), 0);
8696 : :
8697 : 13762 : if (called_decl != NULL_TREE
8698 : 13762 : && !fndecl_maybe_in_other_partition (called_decl))
8699 : : decl = called_decl;
8700 : : }
8701 : :
8702 : 253186 : if (decl
8703 : 76937 : && (fi = lookup_vi_for_tree (decl))
8704 : 327078 : && fi->is_fn_info)
8705 : : {
8706 : 39572 : *gimple_call_clobber_set (stmt)
8707 : 19786 : = find_what_var_points_to
8708 : 19786 : (node->decl, first_vi_for_offset (fi, fi_clobbers));
8709 : 39572 : *gimple_call_use_set (stmt)
8710 : 19786 : = find_what_var_points_to
8711 : 19786 : (node->decl, first_vi_for_offset (fi, fi_uses));
8712 : : }
8713 : : /* Handle direct calls to external functions. */
8714 : 233400 : else if (decl && (!fi || fi->decl))
8715 : : {
8716 : 57150 : pt = gimple_call_use_set (stmt);
8717 : 57150 : if (gimple_call_flags (stmt) & ECF_CONST)
8718 : 1524 : memset (pt, 0, sizeof (struct pt_solution));
8719 : 55626 : else if ((vi = lookup_call_use_vi (stmt)) != NULL)
8720 : : {
8721 : 52319 : *pt = find_what_var_points_to (node->decl, vi);
8722 : : /* Escaped (and thus nonlocal) variables are always
8723 : : implicitly used by calls. */
8724 : : /* ??? ESCAPED can be empty even though NONLOCAL
8725 : : always escaped. */
8726 : 52319 : pt->nonlocal = 1;
8727 : 52319 : pt->ipa_escaped = 1;
8728 : : }
8729 : : else
8730 : : {
8731 : : /* If there is nothing special about this call then
8732 : : we have made everything that is used also escape. */
8733 : 3307 : *pt = ipa_escaped_pt;
8734 : 3307 : pt->nonlocal = 1;
8735 : : }
8736 : :
8737 : 57150 : pt = gimple_call_clobber_set (stmt);
8738 : 57150 : if (gimple_call_flags (stmt) & (ECF_CONST|ECF_PURE|ECF_NOVOPS))
8739 : 1775 : memset (pt, 0, sizeof (struct pt_solution));
8740 : 55375 : else if ((vi = lookup_call_clobber_vi (stmt)) != NULL)
8741 : : {
8742 : 52084 : *pt = find_what_var_points_to (node->decl, vi);
8743 : : /* Escaped (and thus nonlocal) variables are always
8744 : : implicitly clobbered by calls. */
8745 : : /* ??? ESCAPED can be empty even though NONLOCAL
8746 : : always escaped. */
8747 : 52084 : pt->nonlocal = 1;
8748 : 52084 : pt->ipa_escaped = 1;
8749 : : }
8750 : : else
8751 : : {
8752 : : /* If there is nothing special about this call then
8753 : : we have made everything that is used also escape. */
8754 : 3291 : *pt = ipa_escaped_pt;
8755 : 3291 : pt->nonlocal = 1;
8756 : : }
8757 : : }
8758 : : /* Handle indirect calls. */
8759 : 176250 : else if ((fi = get_fi_for_callee (stmt)))
8760 : : {
8761 : : /* We need to accumulate all clobbers/uses of all possible
8762 : : callees. */
8763 : 176250 : fi = get_varinfo (find (fi->id));
8764 : : /* If we cannot constrain the set of functions we'll end up
8765 : : calling we end up using/clobbering everything. */
8766 : 176250 : if (bitmap_bit_p (fi->solution, anything_id)
8767 : 677 : || bitmap_bit_p (fi->solution, nonlocal_id)
8768 : 176260 : || bitmap_bit_p (fi->solution, escaped_id))
8769 : : {
8770 : 176240 : pt_solution_reset (gimple_call_clobber_set (stmt));
8771 : 176240 : pt_solution_reset (gimple_call_use_set (stmt));
8772 : : }
8773 : : else
8774 : : {
8775 : 10 : bitmap_iterator bi;
8776 : 10 : unsigned i;
8777 : 10 : struct pt_solution *uses, *clobbers;
8778 : :
8779 : 10 : uses = gimple_call_use_set (stmt);
8780 : 10 : clobbers = gimple_call_clobber_set (stmt);
8781 : 10 : memset (uses, 0, sizeof (struct pt_solution));
8782 : 10 : memset (clobbers, 0, sizeof (struct pt_solution));
8783 : 27 : EXECUTE_IF_SET_IN_BITMAP (fi->solution, 0, i, bi)
8784 : : {
8785 : 17 : struct pt_solution sol;
8786 : :
8787 : 17 : vi = get_varinfo (i);
8788 : 17 : if (!vi->is_fn_info)
8789 : : {
8790 : : /* ??? We could be more precise here? */
8791 : 0 : uses->nonlocal = 1;
8792 : 0 : uses->ipa_escaped = 1;
8793 : 0 : clobbers->nonlocal = 1;
8794 : 0 : clobbers->ipa_escaped = 1;
8795 : 0 : continue;
8796 : : }
8797 : :
8798 : 17 : if (!uses->anything)
8799 : : {
8800 : 17 : sol = find_what_var_points_to
8801 : 17 : (node->decl,
8802 : : first_vi_for_offset (vi, fi_uses));
8803 : 17 : pt_solution_ior_into (uses, &sol);
8804 : : }
8805 : 17 : if (!clobbers->anything)
8806 : : {
8807 : 17 : sol = find_what_var_points_to
8808 : 17 : (node->decl,
8809 : : first_vi_for_offset (vi, fi_clobbers));
8810 : 17 : pt_solution_ior_into (clobbers, &sol);
8811 : : }
8812 : : }
8813 : : }
8814 : : }
8815 : : else
8816 : 0 : gcc_unreachable ();
8817 : : }
8818 : : }
8819 : :
8820 : 23371 : fn->gimple_df->ipa_pta = true;
8821 : :
8822 : : /* We have to re-set the final-solution cache after each function
8823 : : because what is a "global" is dependent on function context. */
8824 : 23371 : final_solutions->empty ();
8825 : 23371 : obstack_free (&final_solutions_obstack, NULL);
8826 : 23371 : gcc_obstack_init (&final_solutions_obstack);
8827 : : }
8828 : :
8829 : 4406 : delete_points_to_sets ();
8830 : :
8831 : 4406 : in_ipa_mode = 0;
8832 : :
8833 : 4406 : return 0;
8834 : : }
8835 : :
8836 : : namespace {
8837 : :
8838 : : const pass_data pass_data_ipa_pta =
8839 : : {
8840 : : SIMPLE_IPA_PASS, /* type */
8841 : : "pta", /* name */
8842 : : OPTGROUP_NONE, /* optinfo_flags */
8843 : : TV_IPA_PTA, /* tv_id */
8844 : : 0, /* properties_required */
8845 : : 0, /* properties_provided */
8846 : : 0, /* properties_destroyed */
8847 : : 0, /* todo_flags_start */
8848 : : 0, /* todo_flags_finish */
8849 : : };
8850 : :
8851 : : class pass_ipa_pta : public simple_ipa_opt_pass
8852 : : {
8853 : : public:
8854 : 570162 : pass_ipa_pta (gcc::context *ctxt)
8855 : 1140324 : : simple_ipa_opt_pass (pass_data_ipa_pta, ctxt)
8856 : : {}
8857 : :
8858 : : /* opt_pass methods: */
8859 : 230659 : bool gate (function *) final override
8860 : : {
8861 : 230659 : return (optimize
8862 : 148875 : && flag_ipa_pta
8863 : : /* Don't bother doing anything if the program has errors. */
8864 : 235065 : && !seen_error ());
8865 : : }
8866 : :
8867 : 285081 : opt_pass * clone () final override { return new pass_ipa_pta (m_ctxt); }
8868 : :
8869 : 4406 : unsigned int execute (function *) final override
8870 : : {
8871 : 4406 : return ipa_pta_execute ();
8872 : : }
8873 : :
8874 : : }; // class pass_ipa_pta
8875 : :
8876 : : } // anon namespace
8877 : :
8878 : : simple_ipa_opt_pass *
8879 : 285081 : make_pass_ipa_pta (gcc::context *ctxt)
8880 : : {
8881 : 285081 : return new pass_ipa_pta (ctxt);
8882 : : }
|