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 : : #include "tree-ssa-structalias.h"
52 : : #include "pta-andersen.h"
53 : :
54 : : /* The idea behind this analyzer is to generate set constraints from the
55 : : program, then solve the resulting constraints in order to generate the
56 : : points-to sets.
57 : :
58 : : Set constraints are a way of modeling program analysis problems that
59 : : involve sets. They consist of an inclusion constraint language,
60 : : describing the variables (each variable is a set) and operations that
61 : : are involved on the variables, and a set of rules that derive facts
62 : : from these operations. To solve a system of set constraints, you derive
63 : : all possible facts under the rules, which gives you the correct sets
64 : : as a consequence.
65 : :
66 : : See "Efficient Field-sensitive pointer analysis for C" by "David
67 : : J. Pearce and Paul H. J. Kelly and Chris Hankin", at
68 : : http://citeseer.ist.psu.edu/pearce04efficient.html
69 : :
70 : : Also see "Ultra-fast Aliasing Analysis using CLA: A Million Lines
71 : : of C Code in a Second" by "Nevin Heintze and Olivier Tardieu" at
72 : : http://citeseer.ist.psu.edu/heintze01ultrafast.html
73 : :
74 : : There are three types of real constraint expressions, DEREF,
75 : : ADDRESSOF, and SCALAR. Each constraint expression consists
76 : : of a constraint type, a variable, and an offset.
77 : :
78 : : SCALAR is a constraint expression type used to represent x, whether
79 : : it appears on the LHS or the RHS of a statement.
80 : : DEREF is a constraint expression type used to represent *x, whether
81 : : it appears on the LHS or the RHS of a statement.
82 : : ADDRESSOF is a constraint expression used to represent &x, whether
83 : : it appears on the LHS or the RHS of a statement.
84 : :
85 : : Each pointer variable in the program is assigned an integer id, and
86 : : each field of a structure variable is assigned an integer id as well.
87 : :
88 : : Structure variables are linked to their list of fields through a "next
89 : : field" in each variable that points to the next field in offset
90 : : order.
91 : : Each variable for a structure field has
92 : :
93 : : 1. "size", that tells the size in bits of that field.
94 : : 2. "fullsize", that tells the size in bits of the entire structure.
95 : : 3. "offset", that tells the offset in bits from the beginning of the
96 : : structure to this field.
97 : :
98 : : Thus,
99 : : struct f
100 : : {
101 : : int a;
102 : : int b;
103 : : } foo;
104 : : int *bar;
105 : :
106 : : looks like
107 : :
108 : : foo.a -> id 1, size 32, offset 0, fullsize 64, next foo.b
109 : : foo.b -> id 2, size 32, offset 32, fullsize 64, next NULL
110 : : bar -> id 3, size 32, offset 0, fullsize 32, next NULL
111 : :
112 : :
113 : : In order to solve the system of set constraints, the following is
114 : : done:
115 : :
116 : : 1. Each constraint variable x has a solution set associated with it,
117 : : Sol(x).
118 : :
119 : : 2. Constraints are separated into direct, copy, and complex.
120 : : Direct constraints are ADDRESSOF constraints that require no extra
121 : : processing, such as P = &Q
122 : : Copy constraints are those of the form P = Q.
123 : : Complex constraints are all the constraints involving dereferences
124 : : and offsets (including offsetted copies).
125 : :
126 : : 3. All direct constraints of the form P = &Q are processed, such
127 : : that Q is added to Sol(P)
128 : :
129 : : 4. All complex constraints for a given constraint variable are stored in a
130 : : linked list attached to that variable's node.
131 : :
132 : : 5. A directed graph is built out of the copy constraints. Each
133 : : constraint variable is a node in the graph, and an edge from
134 : : Q to P is added for each copy constraint of the form P = Q
135 : :
136 : : 6. The graph is then walked, and solution sets are
137 : : propagated along the copy edges, such that an edge from Q to P
138 : : causes Sol(P) <- Sol(P) union Sol(Q).
139 : :
140 : : 7. As we visit each node, all complex constraints associated with
141 : : that node are processed by adding appropriate copy edges to the graph, or the
142 : : appropriate variables to the solution set.
143 : :
144 : : 8. The process of walking the graph is iterated until no solution
145 : : sets change.
146 : :
147 : : Prior to walking the graph in steps 6 and 7, We perform static
148 : : cycle elimination on the constraint graph, as well
149 : : as off-line variable substitution.
150 : :
151 : : TODO: Adding offsets to pointer-to-structures can be handled (IE not punted
152 : : on and turned into anything), but isn't. You can just see what offset
153 : : inside the pointed-to struct it's going to access.
154 : :
155 : : TODO: Constant bounded arrays can be handled as if they were structs of the
156 : : same number of elements.
157 : :
158 : : TODO: Modeling heap and incoming pointers becomes much better if we
159 : : add fields to them as we discover them, which we could do.
160 : :
161 : : TODO: We could handle unions, but to be honest, it's probably not
162 : : worth the pain or slowdown. */
163 : :
164 : : /* IPA-PTA optimizations possible.
165 : :
166 : : When the indirect function called is ANYTHING we can add disambiguation
167 : : based on the function signatures (or simply the parameter count which
168 : : is the varinfo size). We also do not need to consider functions that
169 : : do not have their address taken.
170 : :
171 : : The is_global_var bit which marks escape points is overly conservative
172 : : in IPA mode. Split it to is_escape_point and is_global_var - only
173 : : externally visible globals are escape points in IPA mode.
174 : : There is now is_ipa_escape_point but this is only used in a few
175 : : selected places.
176 : :
177 : : The way we introduce DECL_PT_UID to avoid fixing up all points-to
178 : : sets in the translation unit when we copy a DECL during inlining
179 : : pessimizes precision. The advantage is that the DECL_PT_UID keeps
180 : : compile-time and memory usage overhead low - the points-to sets
181 : : do not grow or get unshared as they would during a fixup phase.
182 : : An alternative solution is to delay IPA PTA until after all
183 : : inlining transformations have been applied.
184 : :
185 : : The way we propagate clobber/use information isn't optimized.
186 : : It should use a new complex constraint that properly filters
187 : : out local variables of the callee (though that would make
188 : : the sets invalid after inlining). OTOH we might as well
189 : : admit defeat to WHOPR and simply do all the clobber/use analysis
190 : : and propagation after PTA finished but before we threw away
191 : : points-to information for memory variables. WHOPR and PTA
192 : : do not play along well anyway - the whole constraint solving
193 : : would need to be done in WPA phase and it will be very interesting
194 : : to apply the results to local SSA names during LTRANS phase.
195 : :
196 : : We probably should compute a per-function unit-ESCAPE solution
197 : : propagating it simply like the clobber / uses solutions. The
198 : : solution can go alongside the non-IPA escaped solution and be
199 : : used to query which vars escape the unit through a function.
200 : : This is also required to make the escaped-HEAP trick work in IPA mode.
201 : :
202 : : We never put function decls in points-to sets so we do not
203 : : keep the set of called functions for indirect calls.
204 : :
205 : : And probably more. */
206 : :
207 : : namespace pointer_analysis {
208 : :
209 : : /* Used for points-to sets. */
210 : : bitmap_obstack pta_obstack;
211 : :
212 : : /* Used for oldsolution members of variables. */
213 : : bitmap_obstack oldpta_obstack;
214 : :
215 : : /* Table of variable info structures for constraint variables.
216 : : Indexed directly by variable info id. */
217 : : vec<varinfo_t> varmap;
218 : :
219 : : /* List of constraints that we use to build the constraint graph from. */
220 : : vec<constraint_t> constraints;
221 : :
222 : : /* Map from trees to variable infos. */
223 : : static hash_map<tree, varinfo_t> *vi_for_tree;
224 : :
225 : : /* The representative variable for a variable. The points-to solution for a
226 : : var can be found in its rep. Trivially, a var can be its own rep.
227 : :
228 : : The solver provides this array once it is done solving. */
229 : : unsigned int *var_rep;
230 : :
231 : : struct constraint_stats stats;
232 : :
233 : : /* Find the first varinfo in the same variable as START that overlaps with
234 : : OFFSET. Return NULL if we can't find one. */
235 : :
236 : : varinfo_t
237 : 1063680 : first_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset)
238 : : {
239 : : /* If the offset is outside of the variable, bail out. */
240 : 1063680 : if (offset >= start->fullsize)
241 : : return NULL;
242 : :
243 : : /* If we cannot reach offset from start, lookup the first field
244 : : and start from there. */
245 : 1058921 : if (start->offset > offset)
246 : 0 : start = get_varinfo (start->head);
247 : :
248 : 2967539 : while (start)
249 : : {
250 : : /* We may not find a variable in the field list with the actual
251 : : offset when we have glommed a structure to a variable.
252 : : In that case, however, offset should still be within the size
253 : : of the variable. */
254 : 2967539 : if (offset >= start->offset
255 : 2967539 : && (offset - start->offset) < start->size)
256 : : return start;
257 : :
258 : 1908618 : start = vi_next (start);
259 : : }
260 : :
261 : : return NULL;
262 : : }
263 : :
264 : : /* Find the first varinfo in the same variable as START that overlaps with
265 : : OFFSET. If there is no such varinfo the varinfo directly preceding
266 : : OFFSET is returned. */
267 : :
268 : : varinfo_t
269 : 17745197 : first_or_preceding_vi_for_offset (varinfo_t start,
270 : : unsigned HOST_WIDE_INT offset)
271 : : {
272 : : /* If we cannot reach offset from start, lookup the first field
273 : : and start from there. */
274 : 17745197 : if (start->offset > offset)
275 : 455729 : start = get_varinfo (start->head);
276 : :
277 : : /* We may not find a variable in the field list with the actual
278 : : offset when we have glommed a structure to a variable.
279 : : In that case, however, offset should still be within the size
280 : : of the variable.
281 : : If we got beyond the offset we look for return the field
282 : : directly preceding offset which may be the last field. */
283 : 67512926 : while (start->next
284 : 57777750 : && offset >= start->offset
285 : 125284673 : && !((offset - start->offset) < start->size))
286 : 49767729 : start = vi_next (start);
287 : :
288 : 17745197 : return start;
289 : : }
290 : :
291 : : /* Print out constraint C to FILE. */
292 : :
293 : : void
294 : 9433 : dump_constraint (FILE *file, constraint_t c)
295 : : {
296 : 9433 : if (c->lhs.type == ADDRESSOF)
297 : 0 : fprintf (file, "&");
298 : 9433 : else if (c->lhs.type == DEREF)
299 : 864 : fprintf (file, "*");
300 : 9433 : if (dump_file)
301 : 9433 : fprintf (file, "%s", get_varinfo (c->lhs.var)->name);
302 : : else
303 : 0 : fprintf (file, "V%d", c->lhs.var);
304 : 9433 : if (c->lhs.offset == UNKNOWN_OFFSET)
305 : 6 : fprintf (file, " + UNKNOWN");
306 : 9427 : else if (c->lhs.offset != 0)
307 : 4 : fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->lhs.offset);
308 : 9433 : fprintf (file, " = ");
309 : 9433 : if (c->rhs.type == ADDRESSOF)
310 : 3385 : fprintf (file, "&");
311 : 6048 : else if (c->rhs.type == DEREF)
312 : 1206 : fprintf (file, "*");
313 : 9433 : if (dump_file)
314 : 9433 : fprintf (file, "%s", get_varinfo (c->rhs.var)->name);
315 : : else
316 : 0 : fprintf (file, "V%d", c->rhs.var);
317 : 9433 : if (c->rhs.offset == UNKNOWN_OFFSET)
318 : 1570 : fprintf (file, " + UNKNOWN");
319 : 7863 : else if (c->rhs.offset != 0)
320 : 103 : fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->rhs.offset);
321 : 9433 : }
322 : :
323 : : /* Print out constraint C to stderr. */
324 : :
325 : : DEBUG_FUNCTION void
326 : 0 : debug_constraint (constraint_t c)
327 : : {
328 : 0 : dump_constraint (stderr, c);
329 : 0 : fprintf (stderr, "\n");
330 : 0 : }
331 : :
332 : : /* Print out all constraints to FILE. */
333 : :
334 : : void
335 : 384 : dump_constraints (FILE *file, int from)
336 : : {
337 : 384 : int i;
338 : 384 : constraint_t c;
339 : 9721 : for (i = from; constraints.iterate (i, &c); i++)
340 : 9337 : if (c)
341 : : {
342 : 9337 : dump_constraint (file, c);
343 : 9337 : fprintf (file, "\n");
344 : : }
345 : 384 : }
346 : :
347 : : /* Print out all constraints to stderr. */
348 : :
349 : : DEBUG_FUNCTION void
350 : 0 : debug_constraints (void)
351 : : {
352 : 0 : dump_constraints (stderr, 0);
353 : 0 : }
354 : :
355 : : /* Print out the points-to solution for VAR to FILE. */
356 : :
357 : : void
358 : 5814 : dump_solution_for_var (FILE *file, unsigned int var)
359 : : {
360 : 5814 : varinfo_t vi = get_varinfo (var);
361 : 5814 : unsigned int i;
362 : 5814 : bitmap_iterator bi;
363 : :
364 : : /* Dump the solution for unified vars anyway, this avoids difficulties
365 : : in scanning dumps in the testsuite. */
366 : 5814 : fprintf (file, "%s = { ", vi->name);
367 : 5814 : vi = get_varinfo (var_rep[var]);
368 : 15338 : EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
369 : 9524 : fprintf (file, "%s ", get_varinfo (i)->name);
370 : 5814 : fprintf (file, "}");
371 : :
372 : : /* But note when the variable was unified. */
373 : 5814 : if (vi->id != var)
374 : 1224 : fprintf (file, " same as %s", vi->name);
375 : :
376 : 5814 : fprintf (file, "\n");
377 : 5814 : }
378 : :
379 : : /* Print the points-to solution for VAR to stderr. */
380 : :
381 : : DEBUG_FUNCTION void
382 : 0 : debug_solution_for_var (unsigned int var)
383 : : {
384 : 0 : dump_solution_for_var (stderr, var);
385 : 0 : }
386 : :
387 : : /* Dump stats information to OUTFILE. */
388 : :
389 : : void
390 : 149 : dump_sa_stats (FILE *outfile)
391 : : {
392 : 149 : fprintf (outfile, "Points-to Stats:\n");
393 : 149 : fprintf (outfile, "Total vars: %d\n", stats.total_vars);
394 : 149 : fprintf (outfile, "Non-pointer vars: %d\n",
395 : : stats.nonpointer_vars);
396 : 149 : fprintf (outfile, "Statically unified vars: %d\n",
397 : : stats.unified_vars_static);
398 : 149 : fprintf (outfile, "Dynamically unified vars: %d\n",
399 : : stats.unified_vars_dynamic);
400 : 149 : fprintf (outfile, "Iterations: %d\n", stats.iterations);
401 : 149 : fprintf (outfile, "Number of edges: %d\n", stats.num_edges);
402 : 149 : fprintf (outfile, "Number of implicit edges: %d\n",
403 : : stats.num_implicit_edges);
404 : 149 : fprintf (outfile, "Number of avoided edges: %d\n",
405 : : stats.num_avoided_edges);
406 : 149 : }
407 : :
408 : : /* Dump points-to information to OUTFILE. */
409 : :
410 : : void
411 : 299 : dump_sa_points_to_info (FILE *outfile)
412 : : {
413 : 299 : fprintf (outfile, "\nPoints-to sets\n\n");
414 : :
415 : 6763 : for (unsigned i = 1; i < varmap.length (); i++)
416 : : {
417 : 6464 : varinfo_t vi = get_varinfo (i);
418 : 6464 : if (!vi->may_have_pointers)
419 : 650 : continue;
420 : 5814 : dump_solution_for_var (outfile, i);
421 : : }
422 : 299 : }
423 : :
424 : :
425 : : /* Debug points-to information to stderr. */
426 : :
427 : : DEBUG_FUNCTION void
428 : 0 : debug_sa_points_to_info (void)
429 : : {
430 : 0 : dump_sa_points_to_info (stderr);
431 : 0 : }
432 : :
433 : : /* Dump varinfo VI to FILE. */
434 : :
435 : : void
436 : 0 : dump_varinfo (FILE *file, varinfo_t vi)
437 : : {
438 : 0 : if (vi == NULL)
439 : : return;
440 : :
441 : 0 : fprintf (file, "%u: %s\n", vi->id, vi->name);
442 : :
443 : 0 : const char *sep = " ";
444 : 0 : if (vi->is_artificial_var)
445 : 0 : fprintf (file, "%sartificial", sep);
446 : 0 : if (vi->is_special_var)
447 : 0 : fprintf (file, "%sspecial", sep);
448 : 0 : if (vi->is_unknown_size_var)
449 : 0 : fprintf (file, "%sunknown-size", sep);
450 : 0 : if (vi->is_full_var)
451 : 0 : fprintf (file, "%sfull", sep);
452 : 0 : if (vi->is_heap_var)
453 : 0 : fprintf (file, "%sheap", sep);
454 : 0 : if (vi->may_have_pointers)
455 : 0 : fprintf (file, "%smay-have-pointers", sep);
456 : 0 : if (vi->only_restrict_pointers)
457 : 0 : fprintf (file, "%sonly-restrict-pointers", sep);
458 : 0 : if (vi->is_restrict_var)
459 : 0 : fprintf (file, "%sis-restrict-var", sep);
460 : 0 : if (vi->is_global_var)
461 : 0 : fprintf (file, "%sglobal", sep);
462 : 0 : if (vi->is_ipa_escape_point)
463 : 0 : fprintf (file, "%sipa-escape-point", sep);
464 : 0 : if (vi->is_fn_info)
465 : 0 : fprintf (file, "%sfn-info", sep);
466 : 0 : if (vi->ruid)
467 : 0 : fprintf (file, "%srestrict-uid:%u", sep, vi->ruid);
468 : 0 : if (vi->next)
469 : 0 : fprintf (file, "%snext:%u", sep, vi->next);
470 : 0 : if (vi->head != vi->id)
471 : 0 : fprintf (file, "%shead:%u", sep, vi->head);
472 : 0 : if (vi->offset)
473 : 0 : fprintf (file, "%soffset:" HOST_WIDE_INT_PRINT_DEC, sep, vi->offset);
474 : 0 : if (vi->size != ~HOST_WIDE_INT_0U)
475 : 0 : fprintf (file, "%ssize:" HOST_WIDE_INT_PRINT_DEC, sep, vi->size);
476 : 0 : if (vi->fullsize != ~HOST_WIDE_INT_0U && vi->fullsize != vi->size)
477 : 0 : fprintf (file, "%sfullsize:" HOST_WIDE_INT_PRINT_DEC, sep,
478 : : vi->fullsize);
479 : 0 : fprintf (file, "\n");
480 : :
481 : 0 : if (vi->solution && !bitmap_empty_p (vi->solution))
482 : : {
483 : 0 : bitmap_iterator bi;
484 : 0 : unsigned i;
485 : 0 : fprintf (file, " solution: {");
486 : 0 : EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
487 : 0 : fprintf (file, " %u", i);
488 : 0 : fprintf (file, " }\n");
489 : : }
490 : :
491 : 0 : if (vi->oldsolution && !bitmap_empty_p (vi->oldsolution)
492 : 0 : && !bitmap_equal_p (vi->solution, vi->oldsolution))
493 : : {
494 : 0 : bitmap_iterator bi;
495 : 0 : unsigned i;
496 : 0 : fprintf (file, " oldsolution: {");
497 : 0 : EXECUTE_IF_SET_IN_BITMAP (vi->oldsolution, 0, i, bi)
498 : 0 : fprintf (file, " %u", i);
499 : 0 : fprintf (file, " }\n");
500 : : }
501 : : }
502 : :
503 : : /* Dump varinfo VI to stderr. */
504 : :
505 : : DEBUG_FUNCTION void
506 : 0 : debug_varinfo (varinfo_t vi)
507 : : {
508 : 0 : dump_varinfo (stderr, vi);
509 : 0 : }
510 : :
511 : : /* Dump varmap to FILE. */
512 : :
513 : : void
514 : 0 : dump_varmap (FILE *file)
515 : : {
516 : 0 : if (varmap.length () == 0)
517 : : return;
518 : :
519 : 0 : fprintf (file, "variables:\n");
520 : :
521 : 0 : for (unsigned int i = 0; i < varmap.length (); ++i)
522 : : {
523 : 0 : varinfo_t vi = get_varinfo (i);
524 : 0 : dump_varinfo (file, vi);
525 : : }
526 : :
527 : 0 : fprintf (file, "\n");
528 : : }
529 : :
530 : : /* Dump varmap to stderr. */
531 : :
532 : : DEBUG_FUNCTION void
533 : 0 : debug_varmap (void)
534 : : {
535 : 0 : dump_varmap (stderr);
536 : 0 : }
537 : :
538 : : } // namespace pointer_analysis
539 : :
540 : :
541 : : using namespace pointer_analysis;
542 : :
543 : : static bool use_field_sensitive = true;
544 : : static int in_ipa_mode = 0;
545 : :
546 : : static unsigned int create_variable_info_for (tree, const char *, bool);
547 : : static varinfo_t lookup_vi_for_tree (tree);
548 : : static inline bool type_can_have_subvars (const_tree);
549 : : static void make_param_constraints (varinfo_t);
550 : :
551 : : /* Pool of variable info structures. */
552 : : static object_allocator<variable_info> variable_info_pool
553 : : ("Variable info pool");
554 : :
555 : : /* Map varinfo to final pt_solution. */
556 : : static hash_map<varinfo_t, pt_solution *> *final_solutions;
557 : : static struct obstack final_solutions_obstack;
558 : :
559 : : /* Return a new variable info structure consisting for a variable
560 : : named NAME, and using constraint graph node NODE. Append it
561 : : to the vector of variable info structures. */
562 : :
563 : : static varinfo_t
564 : 223014338 : new_var_info (tree t, const char *name, bool add_id)
565 : : {
566 : 223014338 : unsigned index = varmap.length ();
567 : 223014338 : varinfo_t ret = variable_info_pool.allocate ();
568 : :
569 : 223014338 : if (dump_file && add_id)
570 : : {
571 : 2326 : char *tempname = xasprintf ("%s(%d)", name, index);
572 : 2326 : name = ggc_strdup (tempname);
573 : 2326 : free (tempname);
574 : : }
575 : :
576 : 223014338 : ret->id = index;
577 : 223014338 : ret->name = name;
578 : 223014338 : ret->decl = t;
579 : : /* Vars without decl are artificial and do not have sub-variables. */
580 : 223014338 : ret->is_artificial_var = (t == NULL_TREE);
581 : 223014338 : ret->is_special_var = false;
582 : 223014338 : ret->is_unknown_size_var = false;
583 : 223014338 : ret->is_full_var = (t == NULL_TREE);
584 : 223014338 : ret->is_heap_var = false;
585 : 223014338 : ret->may_have_pointers = true;
586 : 223014338 : ret->only_restrict_pointers = false;
587 : 223014338 : ret->is_restrict_var = false;
588 : 223014338 : ret->ruid = 0;
589 : 223014338 : ret->is_global_var = (t == NULL_TREE);
590 : 223014338 : ret->is_ipa_escape_point = false;
591 : 223014338 : ret->is_fn_info = false;
592 : 223014338 : ret->address_taken = false;
593 : 223014338 : if (t && DECL_P (t))
594 : 43251700 : ret->is_global_var = (is_global_var (t)
595 : : /* We have to treat even local register variables
596 : : as escape points. */
597 : 43251700 : || (VAR_P (t) && DECL_HARD_REGISTER (t)));
598 : 106408524 : ret->is_reg_var = (t && TREE_CODE (t) == SSA_NAME);
599 : 223014338 : ret->solution = BITMAP_ALLOC (&pta_obstack);
600 : 223014338 : ret->oldsolution = NULL;
601 : 223014338 : ret->next = 0;
602 : 223014338 : ret->shadow_var_uid = 0;
603 : 223014338 : ret->head = ret->id;
604 : :
605 : 223014338 : stats.total_vars++;
606 : :
607 : 223014338 : varmap.safe_push (ret);
608 : :
609 : 223014338 : return ret;
610 : : }
611 : :
612 : : /* A map mapping call statements to per-stmt variables for uses
613 : : and clobbers specific to the call. */
614 : : static hash_map<gimple *, varinfo_t> *call_stmt_vars;
615 : :
616 : : /* Lookup or create the variable for the call statement CALL. */
617 : :
618 : : static varinfo_t
619 : 68117067 : get_call_vi (gcall *call)
620 : : {
621 : 68117067 : varinfo_t vi, vi2;
622 : :
623 : 68117067 : bool existed;
624 : 68117067 : varinfo_t *slot_p = &call_stmt_vars->get_or_insert (call, &existed);
625 : 68117067 : if (existed)
626 : 52239330 : return *slot_p;
627 : :
628 : 15877737 : vi = new_var_info (NULL_TREE, "CALLUSED", true);
629 : 15877737 : vi->offset = 0;
630 : 15877737 : vi->size = 1;
631 : 15877737 : vi->fullsize = 2;
632 : 15877737 : vi->is_full_var = true;
633 : 15877737 : vi->is_reg_var = true;
634 : :
635 : 15877737 : vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED", true);
636 : 15877737 : vi2->offset = 1;
637 : 15877737 : vi2->size = 1;
638 : 15877737 : vi2->fullsize = 2;
639 : 15877737 : vi2->is_full_var = true;
640 : 15877737 : vi2->is_reg_var = true;
641 : :
642 : 15877737 : vi->next = vi2->id;
643 : :
644 : 15877737 : *slot_p = vi;
645 : 15877737 : return vi;
646 : : }
647 : :
648 : : /* Lookup the variable for the call statement CALL representing
649 : : the uses. Returns NULL if there is nothing special about this call. */
650 : :
651 : : static varinfo_t
652 : 30550395 : lookup_call_use_vi (gcall *call)
653 : : {
654 : 30550395 : varinfo_t *slot_p = call_stmt_vars->get (call);
655 : 30550395 : if (slot_p)
656 : 28774676 : return *slot_p;
657 : :
658 : : return NULL;
659 : : }
660 : :
661 : : /* Lookup the variable for the call statement CALL representing
662 : : the clobbers. Returns NULL if there is nothing special about this call. */
663 : :
664 : : static varinfo_t
665 : 14632623 : lookup_call_clobber_vi (gcall *call)
666 : : {
667 : 14632623 : varinfo_t uses = lookup_call_use_vi (call);
668 : 14632623 : if (!uses)
669 : : return NULL;
670 : :
671 : 13753070 : return vi_next (uses);
672 : : }
673 : :
674 : : /* Lookup or create the variable for the call statement CALL representing
675 : : the uses. */
676 : :
677 : : static varinfo_t
678 : 42673848 : get_call_use_vi (gcall *call)
679 : : {
680 : 0 : return get_call_vi (call);
681 : : }
682 : :
683 : : /* Lookup or create the variable for the call statement CALL representing
684 : : the clobbers. */
685 : :
686 : : static varinfo_t ATTRIBUTE_UNUSED
687 : 25443219 : get_call_clobber_vi (gcall *call)
688 : : {
689 : 25443219 : return vi_next (get_call_vi (call));
690 : : }
691 : :
692 : :
693 : : static void get_constraint_for_1 (tree, vec<ce_s> *, bool, bool);
694 : : static void get_constraint_for (tree, vec<ce_s> *);
695 : : static void get_constraint_for_rhs (tree, vec<ce_s> *);
696 : : static void do_deref (vec<ce_s> *);
697 : :
698 : : /* Allocator for 'constraints' vector. */
699 : :
700 : : static object_allocator<constraint> constraint_pool ("Constraint pool");
701 : :
702 : : /* Create a new constraint consisting of LHS and RHS expressions. */
703 : :
704 : : static constraint_t
705 : 443931010 : new_constraint (const struct constraint_expr lhs,
706 : : const struct constraint_expr rhs)
707 : : {
708 : 0 : constraint_t ret = constraint_pool.allocate ();
709 : 443931010 : ret->lhs = lhs;
710 : 443931010 : ret->rhs = rhs;
711 : 443931010 : return ret;
712 : : }
713 : :
714 : : /* Insert ID as the variable id for tree T in the vi_for_tree map. */
715 : :
716 : : static void
717 : 91879332 : insert_vi_for_tree (tree t, varinfo_t vi)
718 : : {
719 : 91879332 : gcc_assert (vi);
720 : 91879332 : bool existed = vi_for_tree->put (t, vi);
721 : 91879332 : gcc_assert (!existed);
722 : 91879332 : }
723 : :
724 : : /* Find the variable info for tree T in VI_FOR_TREE. If T does not
725 : : exist in the map, return NULL, otherwise, return the varinfo we found. */
726 : :
727 : : static varinfo_t
728 : 52677957 : lookup_vi_for_tree (tree t)
729 : : {
730 : 52677957 : varinfo_t *slot = vi_for_tree->get (t);
731 : 52677957 : if (slot == NULL)
732 : : return NULL;
733 : :
734 : 50736593 : return *slot;
735 : : }
736 : :
737 : : /* Return a printable name for DECL. */
738 : :
739 : : static const char *
740 : 90889902 : alias_get_name (tree decl)
741 : : {
742 : 90889902 : const char *res = "NULL";
743 : 90889902 : if (dump_file)
744 : : {
745 : 3960 : char *temp = NULL;
746 : 3960 : if (TREE_CODE (decl) == SSA_NAME)
747 : : {
748 : 2238 : res = get_name (decl);
749 : 3669 : temp = xasprintf ("%s_%u", res ? res : "", SSA_NAME_VERSION (decl));
750 : : }
751 : 1722 : else if (HAS_DECL_ASSEMBLER_NAME_P (decl)
752 : 1722 : && DECL_ASSEMBLER_NAME_SET_P (decl))
753 : 756 : res = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME_RAW (decl));
754 : 966 : else if (DECL_P (decl))
755 : : {
756 : 966 : res = get_name (decl);
757 : 966 : if (!res)
758 : 4 : temp = xasprintf ("D.%u", DECL_UID (decl));
759 : : }
760 : :
761 : 2998 : if (temp)
762 : : {
763 : 2242 : res = ggc_strdup (temp);
764 : 2242 : free (temp);
765 : : }
766 : : }
767 : :
768 : 90889902 : return res;
769 : : }
770 : :
771 : : /* Find the variable id for tree T in the map.
772 : : If T doesn't exist in the map, create an entry for it and return it. */
773 : :
774 : : static varinfo_t
775 : 242544904 : get_vi_for_tree (tree t)
776 : : {
777 : 242544904 : varinfo_t *slot = vi_for_tree->get (t);
778 : 242544904 : if (slot == NULL)
779 : : {
780 : 81448899 : unsigned int id = create_variable_info_for (t, alias_get_name (t), false);
781 : 81448899 : return get_varinfo (id);
782 : : }
783 : :
784 : 161096005 : return *slot;
785 : : }
786 : :
787 : : /* Get a scalar constraint expression for a new temporary variable. */
788 : :
789 : : static struct constraint_expr
790 : 3125874 : new_scalar_tmp_constraint_exp (const char *name, bool add_id)
791 : : {
792 : 3125874 : struct constraint_expr tmp;
793 : 3125874 : varinfo_t vi;
794 : :
795 : 3125874 : vi = new_var_info (NULL_TREE, name, add_id);
796 : 3125874 : vi->offset = 0;
797 : 3125874 : vi->size = -1;
798 : 3125874 : vi->fullsize = -1;
799 : 3125874 : vi->is_full_var = 1;
800 : 3125874 : vi->is_reg_var = 1;
801 : :
802 : 3125874 : tmp.var = vi->id;
803 : 3125874 : tmp.type = SCALAR;
804 : 3125874 : tmp.offset = 0;
805 : :
806 : 3125874 : return tmp;
807 : : }
808 : :
809 : : /* Get a constraint expression vector from an SSA_VAR_P node.
810 : : If address_p is true, the result will be taken its address of. */
811 : :
812 : : static void
813 : 221875127 : get_constraint_for_ssa_var (tree t, vec<ce_s> *results, bool address_p)
814 : : {
815 : 221875127 : struct constraint_expr cexpr;
816 : 221875127 : varinfo_t vi;
817 : :
818 : : /* We allow FUNCTION_DECLs here even though it doesn't make much sense. */
819 : 221875127 : gcc_assert (TREE_CODE (t) == SSA_NAME || DECL_P (t));
820 : :
821 : 221875127 : if (TREE_CODE (t) == SSA_NAME
822 : 221875127 : && SSA_NAME_IS_DEFAULT_DEF (t))
823 : : {
824 : : /* For parameters, get at the points-to set for the actual parm
825 : : decl. */
826 : 18309148 : if (TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL
827 : 18309148 : || TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL)
828 : : {
829 : 18050640 : get_constraint_for_ssa_var (SSA_NAME_VAR (t), results, address_p);
830 : 42598513 : return;
831 : : }
832 : : /* For undefined SSA names return nothing. */
833 : 258508 : else if (!ssa_defined_default_def_p (t))
834 : : {
835 : 258508 : cexpr.var = nothing_id;
836 : 258508 : cexpr.type = SCALAR;
837 : 258508 : cexpr.offset = 0;
838 : 258508 : results->safe_push (cexpr);
839 : 258508 : return;
840 : : }
841 : : }
842 : :
843 : : /* For global variables resort to the alias target. */
844 : 203565979 : if (VAR_P (t) && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
845 : : {
846 : 11179593 : varpool_node *node = varpool_node::get (t);
847 : 11179593 : if (node && node->alias && node->analyzed)
848 : : {
849 : 17144 : node = node->ultimate_alias_target ();
850 : : /* Canonicalize the PT uid of all aliases to the ultimate target.
851 : : ??? Hopefully the set of aliases can't change in a way that
852 : : changes the ultimate alias target. */
853 : 17144 : gcc_assert ((! DECL_PT_UID_SET_P (node->decl)
854 : : || DECL_PT_UID (node->decl) == DECL_UID (node->decl))
855 : : && (! DECL_PT_UID_SET_P (t)
856 : : || DECL_PT_UID (t) == DECL_UID (node->decl)));
857 : 17144 : DECL_PT_UID (t) = DECL_UID (node->decl);
858 : 17144 : t = node->decl;
859 : : }
860 : :
861 : : /* If this is decl may bind to NULL note that. */
862 : 11179593 : if (address_p
863 : 11179593 : && (! node || ! node->nonzero_address ()))
864 : : {
865 : 8698 : cexpr.var = nothing_id;
866 : 8698 : cexpr.type = SCALAR;
867 : 8698 : cexpr.offset = 0;
868 : 8698 : results->safe_push (cexpr);
869 : : }
870 : : }
871 : :
872 : 203565979 : vi = get_vi_for_tree (t);
873 : 203565979 : cexpr.var = vi->id;
874 : 203565979 : cexpr.type = SCALAR;
875 : 203565979 : cexpr.offset = 0;
876 : :
877 : : /* If we are not taking the address of the constraint expr, add all
878 : : sub-fiels of the variable as well. */
879 : 203565979 : if (!address_p
880 : 166320577 : && !vi->is_full_var)
881 : : {
882 : 21009322 : for (; vi; vi = vi_next (vi))
883 : : {
884 : 14770597 : cexpr.var = vi->id;
885 : 14770597 : results->safe_push (cexpr);
886 : : }
887 : : return;
888 : : }
889 : :
890 : 197327254 : results->safe_push (cexpr);
891 : : }
892 : :
893 : : /* Process constraint T, performing various simplifications and then
894 : : adding it to our list of overall constraints. */
895 : :
896 : : static void
897 : 439441394 : process_constraint (constraint_t t)
898 : : {
899 : 439441394 : struct constraint_expr rhs = t->rhs;
900 : 439441394 : struct constraint_expr lhs = t->lhs;
901 : :
902 : 439441394 : gcc_assert (rhs.var < varmap.length ());
903 : 439441394 : gcc_assert (lhs.var < varmap.length ());
904 : :
905 : : /* If we didn't get any useful constraint from the lhs we get
906 : : &ANYTHING as fallback from get_constraint_for. Deal with
907 : : it here by turning it into *ANYTHING. */
908 : 439441394 : if (lhs.type == ADDRESSOF
909 : 0 : && lhs.var == anything_id)
910 : 0 : t->lhs.type = lhs.type = DEREF;
911 : :
912 : : /* ADDRESSOF on the lhs is invalid. */
913 : 439441394 : gcc_assert (lhs.type != ADDRESSOF);
914 : :
915 : : /* We shouldn't add constraints from things that cannot have pointers.
916 : : It's not completely trivial to avoid in the callers, so do it here. */
917 : 439441394 : if (rhs.type != ADDRESSOF
918 : 439441394 : && !get_varinfo (rhs.var)->may_have_pointers)
919 : 439441394 : return;
920 : :
921 : : /* Likewise adding to the solution of a non-pointer var isn't useful. */
922 : 439048504 : if (!get_varinfo (lhs.var)->may_have_pointers)
923 : : return;
924 : :
925 : : /* This can happen in our IR with things like n->a = *p. */
926 : 439046743 : if (rhs.type == DEREF && lhs.type == DEREF && rhs.var != anything_id)
927 : : {
928 : : /* Split into tmp = *rhs, *lhs = tmp. */
929 : 285774 : struct constraint_expr tmplhs;
930 : 285774 : tmplhs = new_scalar_tmp_constraint_exp ("doubledereftmp", true);
931 : 285774 : process_constraint (new_constraint (tmplhs, rhs));
932 : 285774 : process_constraint (new_constraint (lhs, tmplhs));
933 : 285774 : }
934 : 438760969 : else if ((rhs.type != SCALAR || rhs.offset != 0) && lhs.type == DEREF)
935 : : {
936 : : /* Split into tmp = &rhs, *lhs = tmp. */
937 : 2019363 : struct constraint_expr tmplhs;
938 : 2019363 : tmplhs = new_scalar_tmp_constraint_exp ("derefaddrtmp", true);
939 : 2019363 : process_constraint (new_constraint (tmplhs, rhs));
940 : 2019363 : process_constraint (new_constraint (lhs, tmplhs));
941 : 2019363 : }
942 : : else
943 : : {
944 : 436741606 : gcc_assert (rhs.type != ADDRESSOF || rhs.offset == 0);
945 : 436741606 : if (rhs.type == ADDRESSOF)
946 : 85653248 : get_varinfo (get_varinfo (rhs.var)->head)->address_taken = true;
947 : 436741606 : constraints.safe_push (t);
948 : : }
949 : : }
950 : :
951 : :
952 : : /* Return the position, in bits, of FIELD_DECL from the beginning of its
953 : : structure. */
954 : :
955 : : static unsigned HOST_WIDE_INT
956 : 40469316 : bitpos_of_field (const tree fdecl)
957 : : {
958 : 40469316 : if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fdecl))
959 : 40469316 : || !tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (fdecl)))
960 : : return -1;
961 : :
962 : 40469316 : return (tree_to_uhwi (DECL_FIELD_OFFSET (fdecl)) * BITS_PER_UNIT
963 : 40469316 : + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fdecl)));
964 : : }
965 : :
966 : :
967 : : /* Get constraint expressions for offsetting PTR by OFFSET. Stores the
968 : : resulting constraint expressions in *RESULTS. */
969 : :
970 : : static void
971 : 40221433 : get_constraint_for_ptr_offset (tree ptr, tree offset,
972 : : vec<ce_s> *results)
973 : : {
974 : 40221433 : struct constraint_expr c;
975 : 40221433 : unsigned int j, n;
976 : 40221433 : HOST_WIDE_INT rhsoffset;
977 : :
978 : : /* If we do not do field-sensitive PTA adding offsets to pointers
979 : : does not change the points-to solution. */
980 : 40221433 : if (!use_field_sensitive)
981 : : {
982 : 1915248 : get_constraint_for_rhs (ptr, results);
983 : 1915248 : return;
984 : : }
985 : :
986 : : /* If the offset is not a non-negative integer constant that fits
987 : : in a HOST_WIDE_INT, we have to fall back to a conservative
988 : : solution which includes all sub-fields of all pointed-to
989 : : variables of ptr. */
990 : 38306185 : if (offset == NULL_TREE
991 : 13702892 : || TREE_CODE (offset) != INTEGER_CST)
992 : : rhsoffset = UNKNOWN_OFFSET;
993 : : else
994 : : {
995 : : /* Sign-extend the offset. */
996 : 11770889 : offset_int soffset = offset_int::from (wi::to_wide (offset), SIGNED);
997 : 11770889 : if (!wi::fits_shwi_p (soffset))
998 : : rhsoffset = UNKNOWN_OFFSET;
999 : : else
1000 : : {
1001 : : /* Make sure the bit-offset also fits. */
1002 : 11770889 : HOST_WIDE_INT rhsunitoffset = soffset.to_shwi ();
1003 : 11770889 : rhsoffset = rhsunitoffset * (unsigned HOST_WIDE_INT) BITS_PER_UNIT;
1004 : 11770889 : if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
1005 : 358 : rhsoffset = UNKNOWN_OFFSET;
1006 : : }
1007 : : }
1008 : :
1009 : 38306185 : get_constraint_for_rhs (ptr, results);
1010 : 38306185 : if (rhsoffset == 0)
1011 : : return;
1012 : :
1013 : : /* As we are eventually appending to the solution do not use
1014 : : vec::iterate here. */
1015 : 32117980 : n = results->length ();
1016 : 64236146 : for (j = 0; j < n; j++)
1017 : : {
1018 : 32118166 : varinfo_t curr;
1019 : 32118166 : c = (*results)[j];
1020 : 32118166 : curr = get_varinfo (c.var);
1021 : :
1022 : 32118166 : if (c.type == ADDRESSOF
1023 : : /* If this varinfo represents a full variable just use it. */
1024 : 10546988 : && curr->is_full_var)
1025 : : ;
1026 : 23966039 : else if (c.type == ADDRESSOF
1027 : : /* If we do not know the offset add all subfields. */
1028 : 2394861 : && rhsoffset == UNKNOWN_OFFSET)
1029 : : {
1030 : 33236 : varinfo_t temp = get_varinfo (curr->head);
1031 : 193304 : do
1032 : : {
1033 : 193304 : struct constraint_expr c2;
1034 : 193304 : c2.var = temp->id;
1035 : 193304 : c2.type = ADDRESSOF;
1036 : 193304 : c2.offset = 0;
1037 : 193304 : if (c2.var != c.var)
1038 : 160068 : results->safe_push (c2);
1039 : 193304 : temp = vi_next (temp);
1040 : : }
1041 : 193304 : while (temp);
1042 : : }
1043 : 23932803 : else if (c.type == ADDRESSOF)
1044 : : {
1045 : 2361625 : varinfo_t temp;
1046 : 2361625 : unsigned HOST_WIDE_INT offset = curr->offset + rhsoffset;
1047 : :
1048 : : /* If curr->offset + rhsoffset is less than zero adjust it. */
1049 : 2361625 : if (rhsoffset < 0
1050 : 0 : && curr->offset < offset)
1051 : 2361625 : offset = 0;
1052 : :
1053 : : /* We have to include all fields that overlap the current
1054 : : field shifted by rhsoffset. And we include at least
1055 : : the last or the first field of the variable to represent
1056 : : reachability of off-bound addresses, in particular &object + 1,
1057 : : conservatively correct. */
1058 : 2361625 : temp = first_or_preceding_vi_for_offset (curr, offset);
1059 : 2361625 : c.var = temp->id;
1060 : 2361625 : c.offset = 0;
1061 : 2361625 : temp = vi_next (temp);
1062 : 2361625 : while (temp
1063 : 2481228 : && temp->offset < offset + curr->size)
1064 : : {
1065 : 119603 : struct constraint_expr c2;
1066 : 119603 : c2.var = temp->id;
1067 : 119603 : c2.type = ADDRESSOF;
1068 : 119603 : c2.offset = 0;
1069 : 119603 : results->safe_push (c2);
1070 : 119603 : temp = vi_next (temp);
1071 : : }
1072 : : }
1073 : 21571178 : else if (c.type == SCALAR)
1074 : : {
1075 : 21571178 : gcc_assert (c.offset == 0);
1076 : : c.offset = rhsoffset;
1077 : : }
1078 : : else
1079 : : /* We shouldn't get any DEREFs here. */
1080 : 0 : gcc_unreachable ();
1081 : :
1082 : 32118166 : (*results)[j] = c;
1083 : : }
1084 : : }
1085 : :
1086 : :
1087 : : /* Given a COMPONENT_REF T, return the constraint_expr vector for it.
1088 : : If address_p is true the result will be taken its address of.
1089 : : If lhs_p is true then the constraint expression is assumed to be used
1090 : : as the lhs. */
1091 : :
1092 : : static void
1093 : 32330208 : get_constraint_for_component_ref (tree t, vec<ce_s> *results,
1094 : : bool address_p, bool lhs_p)
1095 : : {
1096 : 32330208 : tree orig_t = t;
1097 : 32330208 : poly_int64 bitsize = -1;
1098 : 32330208 : poly_int64 bitmaxsize = -1;
1099 : 32330208 : poly_int64 bitpos;
1100 : 32330208 : bool reverse;
1101 : 32330208 : tree forzero;
1102 : :
1103 : : /* Some people like to do cute things like take the address of
1104 : : &0->a.b. */
1105 : 32330208 : forzero = t;
1106 : 32330208 : while (handled_component_p (forzero)
1107 : 47842447 : || INDIRECT_REF_P (forzero)
1108 : 142465438 : || TREE_CODE (forzero) == MEM_REF)
1109 : 62292783 : forzero = TREE_OPERAND (forzero, 0);
1110 : :
1111 : 32330208 : if (CONSTANT_CLASS_P (forzero) && integer_zerop (forzero))
1112 : : {
1113 : 1707 : struct constraint_expr temp;
1114 : :
1115 : 1707 : temp.offset = 0;
1116 : 1707 : temp.var = integer_id;
1117 : 1707 : temp.type = SCALAR;
1118 : 1707 : results->safe_push (temp);
1119 : 1707 : return;
1120 : : }
1121 : :
1122 : 32328501 : t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize, &reverse);
1123 : :
1124 : : /* We can end up here for component references on a
1125 : : VIEW_CONVERT_EXPR <>(&foobar) or things like a
1126 : : BIT_FIELD_REF <&MEM[(void *)&b + 4B], ...>. So for
1127 : : symbolic constants simply give up. */
1128 : 32328501 : if (TREE_CODE (t) == ADDR_EXPR)
1129 : : {
1130 : 42 : constraint_expr result;
1131 : 42 : result.type = SCALAR;
1132 : 42 : result.var = anything_id;
1133 : 42 : result.offset = 0;
1134 : 42 : results->safe_push (result);
1135 : 42 : return;
1136 : : }
1137 : :
1138 : : /* Avoid creating pointer-offset constraints, so handle MEM_REF
1139 : : offsets directly. Pretend to take the address of the base,
1140 : : we'll take care of adding the required subset of sub-fields below. */
1141 : 32328459 : if (TREE_CODE (t) == MEM_REF
1142 : 32328459 : && !integer_zerop (TREE_OPERAND (t, 0)))
1143 : : {
1144 : 12191831 : poly_offset_int off = mem_ref_offset (t);
1145 : 12191831 : off <<= LOG2_BITS_PER_UNIT;
1146 : 12191831 : off += bitpos;
1147 : 12191831 : poly_int64 off_hwi;
1148 : 12191831 : if (off.to_shwi (&off_hwi))
1149 : 12191829 : bitpos = off_hwi;
1150 : : else
1151 : : {
1152 : 2 : bitpos = 0;
1153 : 2 : bitmaxsize = -1;
1154 : : }
1155 : 12191831 : get_constraint_for_1 (TREE_OPERAND (t, 0), results, false, lhs_p);
1156 : 12191831 : do_deref (results);
1157 : : }
1158 : : else
1159 : 20136628 : get_constraint_for_1 (t, results, true, lhs_p);
1160 : :
1161 : : /* Strip off nothing_id. */
1162 : 32328459 : if (results->length () == 2)
1163 : : {
1164 : 7748 : gcc_assert ((*results)[0].var == nothing_id);
1165 : 7748 : results->unordered_remove (0);
1166 : : }
1167 : 32328459 : gcc_assert (results->length () == 1);
1168 : 32328459 : struct constraint_expr &result = results->last ();
1169 : :
1170 : 32328459 : if (result.type == SCALAR
1171 : 32328459 : && get_varinfo (result.var)->is_full_var)
1172 : : /* For single-field vars do not bother about the offset. */
1173 : 8251992 : result.offset = 0;
1174 : 24076467 : else if (result.type == SCALAR)
1175 : : {
1176 : : /* In languages like C, you can access one past the end of an
1177 : : array. You aren't allowed to dereference it, so we can
1178 : : ignore this constraint. When we handle pointer subtraction,
1179 : : we may have to do something cute here. */
1180 : :
1181 : 11884725 : if (maybe_lt (poly_uint64 (bitpos), get_varinfo (result.var)->fullsize)
1182 : 11884725 : && maybe_ne (bitmaxsize, 0))
1183 : : {
1184 : : /* It's also not true that the constraint will actually start at the
1185 : : right offset, it may start in some padding. We only care about
1186 : : setting the constraint to the first actual field it touches, so
1187 : : walk to find it. */
1188 : 11875332 : struct constraint_expr cexpr = result;
1189 : 11875332 : varinfo_t curr;
1190 : 11875332 : results->pop ();
1191 : 11875332 : cexpr.offset = 0;
1192 : 62637739 : for (curr = get_varinfo (cexpr.var); curr; curr = vi_next (curr))
1193 : : {
1194 : 51657535 : if (ranges_maybe_overlap_p (poly_int64 (curr->offset),
1195 : 51657535 : curr->size, bitpos, bitmaxsize))
1196 : : {
1197 : 12057903 : cexpr.var = curr->id;
1198 : 12057903 : results->safe_push (cexpr);
1199 : 12057903 : if (address_p)
1200 : : break;
1201 : : }
1202 : : }
1203 : : /* If we are going to take the address of this field then
1204 : : to be able to compute reachability correctly add at least
1205 : : the last field of the variable. */
1206 : 12770484 : if (address_p && results->length () == 0)
1207 : : {
1208 : 24 : curr = get_varinfo (cexpr.var);
1209 : 64 : while (curr->next != 0)
1210 : 40 : curr = vi_next (curr);
1211 : 24 : cexpr.var = curr->id;
1212 : 24 : results->safe_push (cexpr);
1213 : : }
1214 : 11875308 : else if (results->length () == 0)
1215 : : /* Assert that we found *some* field there. The user couldn't be
1216 : : accessing *only* padding. */
1217 : : /* Still the user could access one past the end of an array
1218 : : embedded in a struct resulting in accessing *only* padding. */
1219 : : /* Or accessing only padding via type-punning to a type
1220 : : that has a filed just in padding space. */
1221 : : {
1222 : 18 : cexpr.type = SCALAR;
1223 : 18 : cexpr.var = anything_id;
1224 : 18 : cexpr.offset = 0;
1225 : 18 : results->safe_push (cexpr);
1226 : : }
1227 : : }
1228 : 9393 : else if (known_eq (bitmaxsize, 0))
1229 : : {
1230 : 9174 : if (dump_file && (dump_flags & TDF_DETAILS))
1231 : 0 : fprintf (dump_file, "Access to zero-sized part of variable, "
1232 : : "ignoring\n");
1233 : : }
1234 : : else
1235 : 219 : if (dump_file && (dump_flags & TDF_DETAILS))
1236 : 0 : fprintf (dump_file, "Access to past the end of variable, ignoring\n");
1237 : : }
1238 : 12191742 : else if (result.type == DEREF)
1239 : : {
1240 : : /* If we do not know exactly where the access goes say so. Note
1241 : : that only for non-structure accesses we know that we access
1242 : : at most one subfiled of any variable. */
1243 : 12191691 : HOST_WIDE_INT const_bitpos;
1244 : 12191691 : if (!bitpos.is_constant (&const_bitpos)
1245 : 12191691 : || const_bitpos == -1
1246 : 12191691 : || maybe_ne (bitsize, bitmaxsize)
1247 : 11500977 : || AGGREGATE_TYPE_P (TREE_TYPE (orig_t))
1248 : 9710702 : || result.offset == UNKNOWN_OFFSET)
1249 : 2480989 : result.offset = UNKNOWN_OFFSET;
1250 : : else
1251 : 9710702 : result.offset += const_bitpos;
1252 : : }
1253 : 51 : else if (result.type == ADDRESSOF)
1254 : : {
1255 : : /* We can end up here for component references on constants like
1256 : : VIEW_CONVERT_EXPR <>({ 0, 1, 2, 3 })[i]. */
1257 : 51 : result.type = SCALAR;
1258 : 51 : result.var = anything_id;
1259 : 51 : result.offset = 0;
1260 : : }
1261 : : else
1262 : 0 : gcc_unreachable ();
1263 : : }
1264 : :
1265 : :
1266 : : /* Dereference the constraint expression CONS, and return the result.
1267 : : DEREF (ADDRESSOF) = SCALAR
1268 : : DEREF (SCALAR) = DEREF
1269 : : DEREF (DEREF) = (temp = DEREF1; result = DEREF (temp))
1270 : : This is needed so that we can handle dereferencing DEREF constraints. */
1271 : :
1272 : : static void
1273 : 24184668 : do_deref (vec<ce_s> *constraints)
1274 : : {
1275 : 24184668 : struct constraint_expr *c;
1276 : 24184668 : unsigned int i = 0;
1277 : :
1278 : 48527761 : FOR_EACH_VEC_ELT (*constraints, i, c)
1279 : : {
1280 : 24343093 : if (c->type == SCALAR)
1281 : 18526127 : c->type = DEREF;
1282 : 5816966 : else if (c->type == ADDRESSOF)
1283 : 5816960 : c->type = SCALAR;
1284 : 6 : else if (c->type == DEREF)
1285 : : {
1286 : 6 : struct constraint_expr tmplhs;
1287 : 6 : tmplhs = new_scalar_tmp_constraint_exp ("dereftmp", true);
1288 : 6 : process_constraint (new_constraint (tmplhs, *c));
1289 : 6 : c->var = tmplhs.var;
1290 : : }
1291 : : else
1292 : 0 : gcc_unreachable ();
1293 : : }
1294 : 24184668 : }
1295 : :
1296 : : /* Given a tree T, return the constraint expression for taking the
1297 : : address of it. */
1298 : :
1299 : : static void
1300 : 28089871 : get_constraint_for_address_of (tree t, vec<ce_s> *results)
1301 : : {
1302 : 28089871 : struct constraint_expr *c;
1303 : 28089871 : unsigned int i;
1304 : :
1305 : 28089871 : get_constraint_for_1 (t, results, true, true);
1306 : :
1307 : 84272833 : FOR_EACH_VEC_ELT (*results, i, c)
1308 : : {
1309 : 28093091 : if (c->type == DEREF)
1310 : 1690365 : c->type = SCALAR;
1311 : : else
1312 : 26402726 : c->type = ADDRESSOF;
1313 : : }
1314 : 28089871 : }
1315 : :
1316 : : /* Given a tree T, return the constraint expression for it. */
1317 : :
1318 : : static void
1319 : 317908908 : get_constraint_for_1 (tree t, vec<ce_s> *results, bool address_p,
1320 : : bool lhs_p)
1321 : : {
1322 : 317908908 : struct constraint_expr temp;
1323 : :
1324 : : /* x = integer is all glommed to a single variable, which doesn't
1325 : : point to anything by itself. That is, of course, unless it is an
1326 : : integer constant being treated as a pointer, in which case, we
1327 : : will return that this is really the addressof anything. This
1328 : : happens below, since it will fall into the default case. The only
1329 : : case we know something about an integer treated like a pointer is
1330 : : when it is the NULL pointer, and then we just say it points to
1331 : : NULL.
1332 : :
1333 : : Do not do that if -fno-delete-null-pointer-checks though, because
1334 : : in that case *NULL does not fail, so it _should_ alias *anything.
1335 : : It is not worth adding a new option or renaming the existing one,
1336 : : since this case is relatively obscure. */
1337 : 317908908 : if ((TREE_CODE (t) == INTEGER_CST
1338 : 32233307 : && integer_zerop (t))
1339 : : /* The only valid CONSTRUCTORs in gimple with pointer typed
1340 : : elements are zero-initializer. But in IPA mode we also
1341 : : process global initializers, so verify at least. */
1342 : 339524539 : || (TREE_CODE (t) == CONSTRUCTOR
1343 : 578001 : && CONSTRUCTOR_NELTS (t) == 0))
1344 : : {
1345 : 11148368 : if (flag_delete_null_pointer_checks)
1346 : 11128563 : temp.var = nothing_id;
1347 : : else
1348 : 19805 : temp.var = nonlocal_id;
1349 : 11148368 : temp.type = ADDRESSOF;
1350 : 11148368 : temp.offset = 0;
1351 : 11148368 : results->safe_push (temp);
1352 : 328234707 : return;
1353 : : }
1354 : :
1355 : : /* String constants are read-only, ideally we'd have a CONST_DECL
1356 : : for those. */
1357 : 306760540 : if (TREE_CODE (t) == STRING_CST)
1358 : : {
1359 : 6388279 : temp.var = string_id;
1360 : 6388279 : temp.type = SCALAR;
1361 : 6388279 : temp.offset = 0;
1362 : 6388279 : results->safe_push (temp);
1363 : 6388279 : return;
1364 : : }
1365 : :
1366 : 300372261 : switch (TREE_CODE_CLASS (TREE_CODE (t)))
1367 : : {
1368 : 27882845 : case tcc_expression:
1369 : 27882845 : {
1370 : 27882845 : switch (TREE_CODE (t))
1371 : : {
1372 : 27852785 : case ADDR_EXPR:
1373 : 27852785 : get_constraint_for_address_of (TREE_OPERAND (t, 0), results);
1374 : 27852785 : return;
1375 : : default:;
1376 : : }
1377 : : break;
1378 : : }
1379 : 44559022 : case tcc_reference:
1380 : 44559022 : {
1381 : 44559022 : if (!lhs_p && TREE_THIS_VOLATILE (t))
1382 : : /* Fall back to anything. */
1383 : : break;
1384 : :
1385 : 44453687 : switch (TREE_CODE (t))
1386 : : {
1387 : 11321620 : case MEM_REF:
1388 : 11321620 : {
1389 : 11321620 : struct constraint_expr cs;
1390 : 11321620 : varinfo_t vi, curr;
1391 : 11321620 : get_constraint_for_ptr_offset (TREE_OPERAND (t, 0),
1392 : 11321620 : TREE_OPERAND (t, 1), results);
1393 : 11321620 : do_deref (results);
1394 : :
1395 : : /* If we are not taking the address then make sure to process
1396 : : all subvariables we might access. */
1397 : 11321620 : if (address_p)
1398 : : return;
1399 : :
1400 : 10630780 : cs = results->last ();
1401 : 10630780 : if (cs.type == DEREF
1402 : 10630780 : && type_can_have_subvars (TREE_TYPE (t)))
1403 : : {
1404 : : /* For dereferences this means we have to defer it
1405 : : to solving time. */
1406 : 652154 : results->last ().offset = UNKNOWN_OFFSET;
1407 : 652154 : return;
1408 : : }
1409 : 9978626 : if (cs.type != SCALAR)
1410 : : return;
1411 : :
1412 : 4803634 : vi = get_varinfo (cs.var);
1413 : 4803634 : curr = vi_next (vi);
1414 : 4803634 : if (!vi->is_full_var
1415 : 3811134 : && curr)
1416 : : {
1417 : 2487401 : unsigned HOST_WIDE_INT size;
1418 : 2487401 : if (tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (t))))
1419 : 2487401 : size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (t)));
1420 : : else
1421 : 2487401 : size = -1;
1422 : 5003694 : for (; curr; curr = vi_next (curr))
1423 : : {
1424 : : /* The start of the access might happen anywhere
1425 : : within vi, so conservatively assume it was
1426 : : at its end. */
1427 : 3380569 : if (curr->offset - (vi->offset + vi->size - 1) < size)
1428 : : {
1429 : 2516293 : cs.var = curr->id;
1430 : 2516293 : results->safe_push (cs);
1431 : : }
1432 : : else
1433 : : break;
1434 : : }
1435 : : }
1436 : : return;
1437 : : }
1438 : 32330208 : case ARRAY_REF:
1439 : 32330208 : case ARRAY_RANGE_REF:
1440 : 32330208 : case COMPONENT_REF:
1441 : 32330208 : case IMAGPART_EXPR:
1442 : 32330208 : case REALPART_EXPR:
1443 : 32330208 : case BIT_FIELD_REF:
1444 : 32330208 : get_constraint_for_component_ref (t, results, address_p, lhs_p);
1445 : 32330208 : return;
1446 : 801859 : case VIEW_CONVERT_EXPR:
1447 : 801859 : get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p,
1448 : : lhs_p);
1449 : 801859 : return;
1450 : : /* We are missing handling for TARGET_MEM_REF here. */
1451 : : default:;
1452 : : }
1453 : : break;
1454 : : }
1455 : 155444843 : case tcc_exceptional:
1456 : 155444843 : {
1457 : 155444843 : switch (TREE_CODE (t))
1458 : : {
1459 : 155397334 : case SSA_NAME:
1460 : 155397334 : {
1461 : 155397334 : get_constraint_for_ssa_var (t, results, address_p);
1462 : 155397334 : return;
1463 : : }
1464 : 47309 : case CONSTRUCTOR:
1465 : 47309 : {
1466 : 47309 : unsigned int i;
1467 : 47309 : tree val;
1468 : 47309 : auto_vec<ce_s> tmp;
1469 : 272068 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, val)
1470 : : {
1471 : 224759 : struct constraint_expr *rhsp;
1472 : 224759 : unsigned j;
1473 : 224759 : get_constraint_for_1 (val, &tmp, address_p, lhs_p);
1474 : 449735 : FOR_EACH_VEC_ELT (tmp, j, rhsp)
1475 : 224976 : results->safe_push (*rhsp);
1476 : 224759 : tmp.truncate (0);
1477 : : }
1478 : : /* We do not know whether the constructor was complete,
1479 : : so technically we have to add &NOTHING or &ANYTHING
1480 : : like we do for an empty constructor as well. */
1481 : 47309 : return;
1482 : 47309 : }
1483 : : default:;
1484 : : }
1485 : : break;
1486 : : }
1487 : 49114090 : case tcc_declaration:
1488 : 49114090 : {
1489 : 49114090 : if (!lhs_p && VAR_P (t) && TREE_THIS_VOLATILE (t))
1490 : : /* Fall back to anything. */
1491 : : break;
1492 : 48427153 : get_constraint_for_ssa_var (t, results, address_p);
1493 : 48427153 : return;
1494 : : }
1495 : 23371424 : case tcc_constant:
1496 : 23371424 : {
1497 : : /* We cannot refer to automatic variables through constants. */
1498 : 23371424 : temp.type = ADDRESSOF;
1499 : 23371424 : temp.var = nonlocal_id;
1500 : 23371424 : temp.offset = 0;
1501 : 23371424 : results->safe_push (temp);
1502 : 23371424 : return;
1503 : : }
1504 : 792272 : default:;
1505 : : }
1506 : :
1507 : : /* The default fallback is a constraint from anything. */
1508 : 822569 : temp.type = ADDRESSOF;
1509 : 822569 : temp.var = anything_id;
1510 : 822569 : temp.offset = 0;
1511 : 822569 : results->safe_push (temp);
1512 : : }
1513 : :
1514 : : /* Given a gimple tree T, return the constraint expression vector for it. */
1515 : :
1516 : : static void
1517 : 87486145 : get_constraint_for (tree t, vec<ce_s> *results)
1518 : : {
1519 : 87486145 : gcc_assert (results->length () == 0);
1520 : :
1521 : 87486145 : get_constraint_for_1 (t, results, false, true);
1522 : 87486145 : }
1523 : :
1524 : : /* Given a gimple tree T, return the constraint expression vector for it
1525 : : to be used as the rhs of a constraint. */
1526 : :
1527 : : static void
1528 : 168977815 : get_constraint_for_rhs (tree t, vec<ce_s> *results)
1529 : : {
1530 : 168977815 : gcc_assert (results->length () == 0);
1531 : :
1532 : 168977815 : get_constraint_for_1 (t, results, false, false);
1533 : 168977815 : }
1534 : :
1535 : :
1536 : : /* Efficiently generates constraints from all entries in *RHSC to all
1537 : : entries in *LHSC. */
1538 : :
1539 : : static void
1540 : 94132430 : process_all_all_constraints (const vec<ce_s> &lhsc,
1541 : : const vec<ce_s> &rhsc)
1542 : : {
1543 : 94132430 : struct constraint_expr *lhsp, *rhsp;
1544 : 94132430 : unsigned i, j;
1545 : :
1546 : 96439784 : if (lhsc.length () <= 1 || rhsc.length () <= 1)
1547 : : {
1548 : 283523463 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
1549 : 306470368 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
1550 : 116258604 : process_constraint (new_constraint (*lhsp, *rhsp));
1551 : : }
1552 : : else
1553 : : {
1554 : 820731 : struct constraint_expr tmp;
1555 : 820731 : tmp = new_scalar_tmp_constraint_exp ("allalltmp", true);
1556 : 4321474 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
1557 : 2680012 : process_constraint (new_constraint (tmp, *rhsp));
1558 : 3631138 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
1559 : 1989676 : process_constraint (new_constraint (*lhsp, tmp));
1560 : : }
1561 : 94132430 : }
1562 : :
1563 : : /* Handle aggregate copies by expanding into copies of the respective
1564 : : fields of the structures. */
1565 : :
1566 : : static void
1567 : 2753118 : do_structure_copy (tree lhsop, tree rhsop)
1568 : : {
1569 : 2753118 : struct constraint_expr *lhsp, *rhsp;
1570 : 2753118 : auto_vec<ce_s> lhsc;
1571 : 2753118 : auto_vec<ce_s> rhsc;
1572 : 2753118 : unsigned j;
1573 : :
1574 : 2753118 : get_constraint_for (lhsop, &lhsc);
1575 : 2753118 : get_constraint_for_rhs (rhsop, &rhsc);
1576 : 2753118 : lhsp = &lhsc[0];
1577 : 2753118 : rhsp = &rhsc[0];
1578 : 2753118 : if (lhsp->type == DEREF
1579 : 2189821 : || (lhsp->type == ADDRESSOF && lhsp->var == anything_id)
1580 : 2189821 : || rhsp->type == DEREF)
1581 : : {
1582 : 1071450 : if (lhsp->type == DEREF)
1583 : : {
1584 : 563297 : gcc_assert (lhsc.length () == 1);
1585 : 563297 : lhsp->offset = UNKNOWN_OFFSET;
1586 : : }
1587 : 1071450 : if (rhsp->type == DEREF)
1588 : : {
1589 : 617573 : gcc_assert (rhsc.length () == 1);
1590 : 617573 : rhsp->offset = UNKNOWN_OFFSET;
1591 : : }
1592 : 1071450 : process_all_all_constraints (lhsc, rhsc);
1593 : : }
1594 : 1681668 : else if (lhsp->type == SCALAR
1595 : 1681668 : && (rhsp->type == SCALAR
1596 : 440929 : || rhsp->type == ADDRESSOF))
1597 : : {
1598 : 1681668 : HOST_WIDE_INT lhssize, lhsoffset;
1599 : 1681668 : HOST_WIDE_INT rhssize, rhsoffset;
1600 : 1681668 : bool reverse;
1601 : 1681668 : unsigned k = 0;
1602 : 1681668 : if (!get_ref_base_and_extent_hwi (lhsop, &lhsoffset, &lhssize, &reverse)
1603 : 1681668 : || !get_ref_base_and_extent_hwi (rhsop, &rhsoffset, &rhssize,
1604 : : &reverse))
1605 : : {
1606 : 5707 : process_all_all_constraints (lhsc, rhsc);
1607 : 5707 : return;
1608 : : }
1609 : 6267649 : for (j = 0; lhsc.iterate (j, &lhsp);)
1610 : : {
1611 : 4668171 : varinfo_t lhsv, rhsv;
1612 : 4668171 : rhsp = &rhsc[k];
1613 : 4668171 : lhsv = get_varinfo (lhsp->var);
1614 : 4668171 : rhsv = get_varinfo (rhsp->var);
1615 : 4668171 : if (lhsv->may_have_pointers
1616 : 4668171 : && (lhsv->is_full_var
1617 : 4093057 : || rhsv->is_full_var
1618 : 3186884 : || ranges_overlap_p (lhsv->offset + rhsoffset, lhsv->size,
1619 : 3186884 : rhsv->offset + lhsoffset, rhsv->size)))
1620 : 3490112 : process_constraint (new_constraint (*lhsp, *rhsp));
1621 : 4668171 : if (!rhsv->is_full_var
1622 : 3327624 : && (lhsv->is_full_var
1623 : 3186884 : || (lhsv->offset + rhsoffset + lhsv->size
1624 : 3186884 : > rhsv->offset + lhsoffset + rhsv->size)))
1625 : : {
1626 : 1326908 : ++k;
1627 : 1326908 : if (k >= rhsc.length ())
1628 : : break;
1629 : : }
1630 : : else
1631 : 3341263 : ++j;
1632 : : }
1633 : 1675961 : }
1634 : : else
1635 : 0 : gcc_unreachable ();
1636 : 2753118 : }
1637 : :
1638 : : /* Create constraints ID = { rhsc }. */
1639 : :
1640 : : static void
1641 : 56551278 : make_constraints_to (unsigned id, const vec<ce_s> &rhsc)
1642 : : {
1643 : 56551278 : struct constraint_expr *c;
1644 : 56551278 : struct constraint_expr includes;
1645 : 56551278 : unsigned int j;
1646 : :
1647 : 56551278 : includes.var = id;
1648 : 56551278 : includes.offset = 0;
1649 : 56551278 : includes.type = SCALAR;
1650 : :
1651 : 116440157 : FOR_EACH_VEC_ELT (rhsc, j, c)
1652 : 59888879 : process_constraint (new_constraint (includes, *c));
1653 : 56551278 : }
1654 : :
1655 : : /* Create a constraint ID = OP. */
1656 : :
1657 : : static void
1658 : 56387989 : make_constraint_to (unsigned id, tree op)
1659 : : {
1660 : 56387989 : auto_vec<ce_s> rhsc;
1661 : 56387989 : get_constraint_for_rhs (op, &rhsc);
1662 : 56387989 : make_constraints_to (id, rhsc);
1663 : 56387989 : }
1664 : :
1665 : : /* Create a constraint ID = &FROM. */
1666 : :
1667 : : static void
1668 : 11513412 : make_constraint_from (varinfo_t vi, int from)
1669 : : {
1670 : 11513412 : struct constraint_expr lhs, rhs;
1671 : :
1672 : 11513412 : lhs.var = vi->id;
1673 : 11513412 : lhs.offset = 0;
1674 : 11513412 : lhs.type = SCALAR;
1675 : :
1676 : 11513412 : rhs.var = from;
1677 : 11513412 : rhs.offset = 0;
1678 : 11513412 : rhs.type = ADDRESSOF;
1679 : 11513412 : process_constraint (new_constraint (lhs, rhs));
1680 : 11513412 : }
1681 : :
1682 : : /* Create a constraint ID = FROM. */
1683 : :
1684 : : static void
1685 : 77041502 : make_copy_constraint (varinfo_t vi, int from)
1686 : : {
1687 : 77041502 : struct constraint_expr lhs, rhs;
1688 : :
1689 : 77041502 : lhs.var = vi->id;
1690 : 77041502 : lhs.offset = 0;
1691 : 77041502 : lhs.type = SCALAR;
1692 : :
1693 : 77041502 : rhs.var = from;
1694 : 77041502 : rhs.offset = 0;
1695 : 77041502 : rhs.type = SCALAR;
1696 : 77041502 : process_constraint (new_constraint (lhs, rhs));
1697 : 77041502 : }
1698 : :
1699 : : /* Make constraints necessary to make OP escape. */
1700 : :
1701 : : static void
1702 : 23554157 : make_escape_constraint (tree op)
1703 : : {
1704 : 0 : make_constraint_to (escaped_id, op);
1705 : 23554157 : }
1706 : :
1707 : : /* Make constraint necessary to make all indirect references
1708 : : from VI escape. */
1709 : :
1710 : : static void
1711 : 1181708 : make_indirect_escape_constraint (varinfo_t vi)
1712 : : {
1713 : 1181708 : struct constraint_expr lhs, rhs;
1714 : : /* escaped = *(VAR + UNKNOWN); */
1715 : 1181708 : lhs.type = SCALAR;
1716 : 1181708 : lhs.var = escaped_id;
1717 : 1181708 : lhs.offset = 0;
1718 : 1181708 : rhs.type = DEREF;
1719 : 1181708 : rhs.var = vi->id;
1720 : 1181708 : rhs.offset = UNKNOWN_OFFSET;
1721 : 1181708 : process_constraint (new_constraint (lhs, rhs));
1722 : 1181708 : }
1723 : :
1724 : : /* Add constraints to that the solution of VI is transitively closed. */
1725 : :
1726 : : static void
1727 : 25823524 : make_transitive_closure_constraints (varinfo_t vi)
1728 : : {
1729 : 25823524 : struct constraint_expr lhs, rhs;
1730 : :
1731 : : /* VAR = *(VAR + UNKNOWN); */
1732 : 25823524 : lhs.type = SCALAR;
1733 : 25823524 : lhs.var = vi->id;
1734 : 25823524 : lhs.offset = 0;
1735 : 25823524 : rhs.type = DEREF;
1736 : 25823524 : rhs.var = vi->id;
1737 : 25823524 : rhs.offset = UNKNOWN_OFFSET;
1738 : 25823524 : process_constraint (new_constraint (lhs, rhs));
1739 : 25823524 : }
1740 : :
1741 : : /* Add constraints to that the solution of VI has all subvariables added. */
1742 : :
1743 : : static void
1744 : 31331721 : make_any_offset_constraints (varinfo_t vi)
1745 : : {
1746 : 31331721 : struct constraint_expr lhs, rhs;
1747 : :
1748 : : /* VAR = VAR + UNKNOWN; */
1749 : 31331721 : lhs.type = SCALAR;
1750 : 31331721 : lhs.var = vi->id;
1751 : 31331721 : lhs.offset = 0;
1752 : 31331721 : rhs.type = SCALAR;
1753 : 31331721 : rhs.var = vi->id;
1754 : 31331721 : rhs.offset = UNKNOWN_OFFSET;
1755 : 31331721 : process_constraint (new_constraint (lhs, rhs));
1756 : 31331721 : }
1757 : :
1758 : : /* Temporary storage for fake var decls. */
1759 : : struct obstack fake_var_decl_obstack;
1760 : :
1761 : : /* Build a fake VAR_DECL acting as referrer to a DECL_UID. */
1762 : :
1763 : : static tree
1764 : 940621 : build_fake_var_decl (tree type)
1765 : : {
1766 : 940621 : tree decl = (tree) XOBNEW (&fake_var_decl_obstack, struct tree_var_decl);
1767 : 940621 : memset (decl, 0, sizeof (struct tree_var_decl));
1768 : 940621 : TREE_SET_CODE (decl, VAR_DECL);
1769 : 940621 : TREE_TYPE (decl) = type;
1770 : 940621 : DECL_UID (decl) = allocate_decl_uid ();
1771 : 940621 : SET_DECL_PT_UID (decl, -1);
1772 : 940621 : layout_decl (decl, 0);
1773 : 940621 : return decl;
1774 : : }
1775 : :
1776 : : /* Create a new artificial heap variable with NAME.
1777 : : Return the created variable. */
1778 : :
1779 : : static varinfo_t
1780 : 340297 : make_heapvar (const char *name, bool add_id)
1781 : : {
1782 : 340297 : varinfo_t vi;
1783 : 340297 : tree heapvar;
1784 : :
1785 : 340297 : heapvar = build_fake_var_decl (ptr_type_node);
1786 : 340297 : DECL_EXTERNAL (heapvar) = 1;
1787 : :
1788 : 340297 : vi = new_var_info (heapvar, name, add_id);
1789 : 340297 : vi->is_heap_var = true;
1790 : 340297 : vi->is_unknown_size_var = true;
1791 : 340297 : vi->offset = 0;
1792 : 340297 : vi->fullsize = ~0;
1793 : 340297 : vi->size = ~0;
1794 : 340297 : vi->is_full_var = true;
1795 : 340297 : insert_vi_for_tree (heapvar, vi);
1796 : :
1797 : 340297 : return vi;
1798 : : }
1799 : :
1800 : : /* Create a new artificial heap variable with NAME and make a
1801 : : constraint from it to LHS. Set flags according to a tag used
1802 : : for tracking restrict pointers. */
1803 : :
1804 : : static varinfo_t
1805 : 11220 : make_constraint_from_restrict (varinfo_t lhs, const char *name, bool add_id)
1806 : : {
1807 : 11220 : varinfo_t vi = make_heapvar (name, add_id);
1808 : 11220 : vi->is_restrict_var = 1;
1809 : 11220 : vi->is_global_var = 1;
1810 : 11220 : vi->may_have_pointers = 1;
1811 : 11220 : make_constraint_from (lhs, vi->id);
1812 : 11220 : return vi;
1813 : : }
1814 : :
1815 : : /* Create a new artificial heap variable with NAME and make a
1816 : : constraint from it to LHS. Set flags according to a tag used
1817 : : for tracking restrict pointers and make the artificial heap
1818 : : point to global memory. */
1819 : :
1820 : : static varinfo_t
1821 : 11220 : make_constraint_from_global_restrict (varinfo_t lhs, const char *name,
1822 : : bool add_id)
1823 : : {
1824 : 11220 : varinfo_t vi = make_constraint_from_restrict (lhs, name, add_id);
1825 : 11220 : make_copy_constraint (vi, nonlocal_id);
1826 : 11220 : return vi;
1827 : : }
1828 : :
1829 : : /* In IPA mode there are varinfos for different aspects of reach
1830 : : function designator. One for the points-to set of the return
1831 : : value, one for the variables that are clobbered by the function,
1832 : : one for its uses and one for each parameter (including a single
1833 : : glob for remaining variadic arguments). */
1834 : :
1835 : : enum { fi_clobbers = 1, fi_uses = 2,
1836 : : fi_static_chain = 3, fi_result = 4, fi_parm_base = 5 };
1837 : :
1838 : : /* Get a constraint for the requested part of a function designator FI
1839 : : when operating in IPA mode. */
1840 : :
1841 : : static struct constraint_expr
1842 : 1437493 : get_function_part_constraint (varinfo_t fi, unsigned part)
1843 : : {
1844 : 1437493 : struct constraint_expr c;
1845 : :
1846 : 1437493 : gcc_assert (in_ipa_mode);
1847 : :
1848 : 1437493 : if (fi->id == anything_id)
1849 : : {
1850 : : /* ??? We probably should have a ANYFN special variable. */
1851 : : c.var = anything_id;
1852 : : c.offset = 0;
1853 : : c.type = SCALAR;
1854 : : }
1855 : 494469 : else if (fi->decl && TREE_CODE (fi->decl) == FUNCTION_DECL)
1856 : : {
1857 : 491086 : varinfo_t ai = first_vi_for_offset (fi, part);
1858 : 491086 : if (ai)
1859 : 491086 : c.var = ai->id;
1860 : : else
1861 : : c.var = anything_id;
1862 : : c.offset = 0;
1863 : : c.type = SCALAR;
1864 : : }
1865 : : else
1866 : : {
1867 : 3383 : c.var = fi->id;
1868 : 3383 : c.offset = part;
1869 : 3383 : c.type = DEREF;
1870 : : }
1871 : :
1872 : 1437493 : return c;
1873 : : }
1874 : :
1875 : : /* Produce constraints for argument ARG of call STMT with eaf flags
1876 : : FLAGS. RESULTS is array holding constraints for return value.
1877 : : CALLESCAPE_ID is variable where call loocal escapes are added.
1878 : : WRITES_GLOVEL_MEMORY is true if callee may write global memory. */
1879 : :
1880 : : static void
1881 : 30203616 : handle_call_arg (gcall *stmt, tree arg, vec<ce_s> *results, int flags,
1882 : : int callescape_id, bool writes_global_memory)
1883 : : {
1884 : 30203616 : int relevant_indirect_flags = EAF_NO_INDIRECT_CLOBBER | EAF_NO_INDIRECT_READ
1885 : : | EAF_NO_INDIRECT_ESCAPE;
1886 : 30203616 : int relevant_flags = relevant_indirect_flags
1887 : : | EAF_NO_DIRECT_CLOBBER
1888 : : | EAF_NO_DIRECT_READ
1889 : : | EAF_NO_DIRECT_ESCAPE;
1890 : 30203616 : if (gimple_call_lhs (stmt))
1891 : : {
1892 : 11426774 : relevant_flags |= EAF_NOT_RETURNED_DIRECTLY | EAF_NOT_RETURNED_INDIRECTLY;
1893 : 11426774 : relevant_indirect_flags |= EAF_NOT_RETURNED_INDIRECTLY;
1894 : :
1895 : : /* If value is never read from it can not be returned indirectly
1896 : : (except through the escape solution).
1897 : : For all flags we get these implications right except for
1898 : : not_returned because we miss return functions in ipa-prop. */
1899 : :
1900 : 11426774 : if (flags & EAF_NO_DIRECT_READ)
1901 : 1975872 : flags |= EAF_NOT_RETURNED_INDIRECTLY;
1902 : : }
1903 : :
1904 : : /* If the argument is not used we can ignore it.
1905 : : Similarly argument is invisile for us if it not clobbered, does not
1906 : : escape, is not read and can not be returned. */
1907 : 30203616 : if ((flags & EAF_UNUSED) || ((flags & relevant_flags) == relevant_flags))
1908 : : return;
1909 : :
1910 : : /* Produce varinfo for direct accesses to ARG. */
1911 : 28956443 : varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
1912 : 28956443 : tem->is_reg_var = true;
1913 : 28956443 : make_constraint_to (tem->id, arg);
1914 : 28956443 : make_any_offset_constraints (tem);
1915 : :
1916 : 28956443 : bool callarg_transitive = false;
1917 : :
1918 : : /* As an compile time optimization if we make no difference between
1919 : : direct and indirect accesses make arg transitively closed.
1920 : : This avoids the need to build indir arg and do everything twice. */
1921 : 28956443 : if (((flags & EAF_NO_INDIRECT_CLOBBER) != 0)
1922 : 28956443 : == ((flags & EAF_NO_DIRECT_CLOBBER) != 0)
1923 : 27602009 : && (((flags & EAF_NO_INDIRECT_READ) != 0)
1924 : 27602009 : == ((flags & EAF_NO_DIRECT_READ) != 0))
1925 : 26658811 : && (((flags & EAF_NO_INDIRECT_ESCAPE) != 0)
1926 : 26658811 : == ((flags & EAF_NO_DIRECT_ESCAPE) != 0))
1927 : 26121462 : && (((flags & EAF_NOT_RETURNED_INDIRECTLY) != 0)
1928 : 26121462 : == ((flags & EAF_NOT_RETURNED_DIRECTLY) != 0)))
1929 : : {
1930 : 24278841 : make_transitive_closure_constraints (tem);
1931 : 24278841 : callarg_transitive = true;
1932 : : }
1933 : :
1934 : : /* If necessary, produce varinfo for indirect accesses to ARG. */
1935 : 28956443 : varinfo_t indir_tem = NULL;
1936 : 24278841 : if (!callarg_transitive
1937 : 4677602 : && (flags & relevant_indirect_flags) != relevant_indirect_flags)
1938 : : {
1939 : 1660771 : struct constraint_expr lhs, rhs;
1940 : 1660771 : indir_tem = new_var_info (NULL_TREE, "indircallarg", true);
1941 : 1660771 : indir_tem->is_reg_var = true;
1942 : :
1943 : : /* indir_term = *tem. */
1944 : 1660771 : lhs.type = SCALAR;
1945 : 1660771 : lhs.var = indir_tem->id;
1946 : 1660771 : lhs.offset = 0;
1947 : :
1948 : 1660771 : rhs.type = DEREF;
1949 : 1660771 : rhs.var = tem->id;
1950 : 1660771 : rhs.offset = UNKNOWN_OFFSET;
1951 : 1660771 : process_constraint (new_constraint (lhs, rhs));
1952 : :
1953 : 1660771 : make_any_offset_constraints (indir_tem);
1954 : :
1955 : : /* If we do not read indirectly there is no need for transitive closure.
1956 : : We know there is only one level of indirection. */
1957 : 1660771 : if (!(flags & EAF_NO_INDIRECT_READ))
1958 : 1544683 : make_transitive_closure_constraints (indir_tem);
1959 : 1660771 : gcc_checking_assert (!(flags & EAF_NO_DIRECT_READ));
1960 : : }
1961 : :
1962 : 28956443 : if (gimple_call_lhs (stmt))
1963 : : {
1964 : 11194890 : if (!(flags & EAF_NOT_RETURNED_DIRECTLY))
1965 : : {
1966 : 10225289 : struct constraint_expr cexpr;
1967 : 10225289 : cexpr.var = tem->id;
1968 : 10225289 : cexpr.type = SCALAR;
1969 : 10225289 : cexpr.offset = 0;
1970 : 10225289 : results->safe_push (cexpr);
1971 : : }
1972 : 11194890 : if (!callarg_transitive & !(flags & EAF_NOT_RETURNED_INDIRECTLY))
1973 : : {
1974 : 631436 : struct constraint_expr cexpr;
1975 : 631436 : cexpr.var = indir_tem->id;
1976 : 631436 : cexpr.type = SCALAR;
1977 : 631436 : cexpr.offset = 0;
1978 : 631436 : results->safe_push (cexpr);
1979 : : }
1980 : : }
1981 : :
1982 : 28956443 : if (!(flags & EAF_NO_DIRECT_READ))
1983 : : {
1984 : 26815916 : varinfo_t uses = get_call_use_vi (stmt);
1985 : 26815916 : make_copy_constraint (uses, tem->id);
1986 : 26815916 : if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_READ))
1987 : 1544683 : make_copy_constraint (uses, indir_tem->id);
1988 : : }
1989 : : else
1990 : : /* To read indirectly we need to read directly. */
1991 : 2140527 : gcc_checking_assert (flags & EAF_NO_INDIRECT_READ);
1992 : :
1993 : 28956443 : if (!(flags & EAF_NO_DIRECT_CLOBBER))
1994 : : {
1995 : 24064407 : struct constraint_expr lhs, rhs;
1996 : :
1997 : : /* *arg = callescape. */
1998 : 24064407 : lhs.type = DEREF;
1999 : 24064407 : lhs.var = tem->id;
2000 : 24064407 : lhs.offset = 0;
2001 : :
2002 : 24064407 : rhs.type = SCALAR;
2003 : 24064407 : rhs.var = callescape_id;
2004 : 24064407 : rhs.offset = 0;
2005 : 24064407 : process_constraint (new_constraint (lhs, rhs));
2006 : :
2007 : : /* callclobbered = arg. */
2008 : 24064407 : make_copy_constraint (get_call_clobber_vi (stmt), tem->id);
2009 : : }
2010 : 28956443 : if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_CLOBBER))
2011 : : {
2012 : 1359007 : struct constraint_expr lhs, rhs;
2013 : :
2014 : : /* *indir_arg = callescape. */
2015 : 1359007 : lhs.type = DEREF;
2016 : 1359007 : lhs.var = indir_tem->id;
2017 : 1359007 : lhs.offset = 0;
2018 : :
2019 : 1359007 : rhs.type = SCALAR;
2020 : 1359007 : rhs.var = callescape_id;
2021 : 1359007 : rhs.offset = 0;
2022 : 1359007 : process_constraint (new_constraint (lhs, rhs));
2023 : :
2024 : : /* callclobbered = indir_arg. */
2025 : 1359007 : make_copy_constraint (get_call_clobber_vi (stmt), indir_tem->id);
2026 : : }
2027 : :
2028 : 28956443 : if (!(flags & (EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE)))
2029 : : {
2030 : 22553344 : struct constraint_expr lhs, rhs;
2031 : :
2032 : : /* callescape = arg; */
2033 : 22553344 : lhs.var = callescape_id;
2034 : 22553344 : lhs.offset = 0;
2035 : 22553344 : lhs.type = SCALAR;
2036 : :
2037 : 22553344 : rhs.var = tem->id;
2038 : 22553344 : rhs.offset = 0;
2039 : 22553344 : rhs.type = SCALAR;
2040 : 22553344 : process_constraint (new_constraint (lhs, rhs));
2041 : :
2042 : 22553344 : if (writes_global_memory)
2043 : 21824844 : make_escape_constraint (arg);
2044 : : }
2045 : 6403099 : else if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_ESCAPE))
2046 : : {
2047 : 1298432 : struct constraint_expr lhs, rhs;
2048 : :
2049 : : /* callescape = *(indir_arg + UNKNOWN); */
2050 : 1298432 : lhs.var = callescape_id;
2051 : 1298432 : lhs.offset = 0;
2052 : 1298432 : lhs.type = SCALAR;
2053 : :
2054 : 1298432 : rhs.var = indir_tem->id;
2055 : 1298432 : rhs.offset = 0;
2056 : 1298432 : rhs.type = SCALAR;
2057 : 1298432 : process_constraint (new_constraint (lhs, rhs));
2058 : :
2059 : 1298432 : if (writes_global_memory)
2060 : 1181708 : make_indirect_escape_constraint (tem);
2061 : : }
2062 : : }
2063 : :
2064 : : /* Determine global memory access of call STMT and update
2065 : : WRITES_GLOBAL_MEMORY, READS_GLOBAL_MEMORY and USES_GLOBAL_MEMORY. */
2066 : :
2067 : : static void
2068 : 45476515 : determine_global_memory_access (gcall *stmt,
2069 : : bool *writes_global_memory,
2070 : : bool *reads_global_memory,
2071 : : bool *uses_global_memory)
2072 : : {
2073 : 45476515 : tree callee;
2074 : 45476515 : cgraph_node *node;
2075 : 45476515 : modref_summary *summary;
2076 : :
2077 : : /* We need to detrmine reads to set uses. */
2078 : 45476515 : gcc_assert (!uses_global_memory || reads_global_memory);
2079 : :
2080 : 45476515 : if ((callee = gimple_call_fndecl (stmt)) != NULL_TREE
2081 : 43306648 : && (node = cgraph_node::get (callee)) != NULL
2082 : 88752089 : && (summary = get_modref_function_summary (node)))
2083 : : {
2084 : 8491709 : if (writes_global_memory && *writes_global_memory)
2085 : 5258568 : *writes_global_memory = summary->global_memory_written;
2086 : 8491709 : if (reads_global_memory && *reads_global_memory)
2087 : 5830989 : *reads_global_memory = summary->global_memory_read;
2088 : 8491709 : if (reads_global_memory && uses_global_memory
2089 : 2920510 : && !summary->calls_interposable
2090 : 10763562 : && !*reads_global_memory && node->binds_to_current_def_p ())
2091 : 441682 : *uses_global_memory = false;
2092 : : }
2093 : 45476515 : if ((writes_global_memory && *writes_global_memory)
2094 : 18284407 : || (uses_global_memory && *uses_global_memory)
2095 : 2917095 : || (reads_global_memory && *reads_global_memory))
2096 : : {
2097 : 43085756 : attr_fnspec fnspec = gimple_call_fnspec (stmt);
2098 : 43085756 : if (fnspec.known_p ())
2099 : : {
2100 : 5795989 : if (writes_global_memory
2101 : 5795989 : && !fnspec.global_memory_written_p ())
2102 : 1481441 : *writes_global_memory = false;
2103 : 5795989 : if (reads_global_memory && !fnspec.global_memory_read_p ())
2104 : : {
2105 : 2259422 : *reads_global_memory = false;
2106 : 2259422 : if (uses_global_memory)
2107 : 1930844 : *uses_global_memory = false;
2108 : : }
2109 : : }
2110 : : }
2111 : 45476515 : }
2112 : :
2113 : : /* For non-IPA mode, generate constraints necessary for a call on the
2114 : : RHS and collect return value constraint to RESULTS to be used later in
2115 : : handle_lhs_call.
2116 : :
2117 : : IMPLICIT_EAF_FLAGS are added to each function argument. If
2118 : : WRITES_GLOBAL_MEMORY is true function is assumed to possibly write to global
2119 : : memory. Similar for READS_GLOBAL_MEMORY. */
2120 : :
2121 : : static void
2122 : 15143425 : handle_rhs_call (gcall *stmt, vec<ce_s> *results,
2123 : : int implicit_eaf_flags,
2124 : : bool writes_global_memory,
2125 : : bool reads_global_memory)
2126 : : {
2127 : 15143425 : determine_global_memory_access (stmt, &writes_global_memory,
2128 : : &reads_global_memory,
2129 : : NULL);
2130 : :
2131 : 15143425 : varinfo_t callescape = new_var_info (NULL_TREE, "callescape", true);
2132 : :
2133 : : /* If function can use global memory, add it to callescape
2134 : : and to possible return values. If not we can still use/return addresses
2135 : : of global symbols. */
2136 : 15143425 : struct constraint_expr lhs, rhs;
2137 : :
2138 : 15143425 : lhs.type = SCALAR;
2139 : 15143425 : lhs.var = callescape->id;
2140 : 15143425 : lhs.offset = 0;
2141 : :
2142 : 15143425 : rhs.type = reads_global_memory ? SCALAR : ADDRESSOF;
2143 : 15143425 : rhs.var = nonlocal_id;
2144 : 15143425 : rhs.offset = 0;
2145 : :
2146 : 15143425 : process_constraint (new_constraint (lhs, rhs));
2147 : 15143425 : results->safe_push (rhs);
2148 : :
2149 : 15143425 : varinfo_t uses = get_call_use_vi (stmt);
2150 : 15143425 : make_copy_constraint (uses, callescape->id);
2151 : :
2152 : 45263300 : for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
2153 : : {
2154 : 30119875 : tree arg = gimple_call_arg (stmt, i);
2155 : 30119875 : int flags = gimple_call_arg_flags (stmt, i);
2156 : 30119875 : handle_call_arg (stmt, arg, results,
2157 : : flags | implicit_eaf_flags,
2158 : 30119875 : callescape->id, writes_global_memory);
2159 : : }
2160 : :
2161 : : /* The static chain escapes as well. */
2162 : 15143425 : if (gimple_call_chain (stmt))
2163 : 83741 : handle_call_arg (stmt, gimple_call_chain (stmt), results,
2164 : : implicit_eaf_flags
2165 : 83741 : | gimple_call_static_chain_flags (stmt),
2166 : 83741 : callescape->id, writes_global_memory);
2167 : :
2168 : : /* And if we applied NRV the address of the return slot escapes as well. */
2169 : 15143425 : if (gimple_call_return_slot_opt_p (stmt)
2170 : 640001 : && gimple_call_lhs (stmt) != NULL_TREE
2171 : 15755191 : && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
2172 : : {
2173 : 87803 : int flags = gimple_call_retslot_flags (stmt);
2174 : 87803 : const int relevant_flags = EAF_NO_DIRECT_ESCAPE
2175 : : | EAF_NOT_RETURNED_DIRECTLY;
2176 : :
2177 : 87803 : if (!(flags & EAF_UNUSED) && (flags & relevant_flags) != relevant_flags)
2178 : : {
2179 : 70838 : auto_vec<ce_s> tmpc;
2180 : :
2181 : 70838 : get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
2182 : :
2183 : 70838 : if (!(flags & EAF_NO_DIRECT_ESCAPE))
2184 : : {
2185 : 70834 : make_constraints_to (callescape->id, tmpc);
2186 : 70834 : if (writes_global_memory)
2187 : 69459 : make_constraints_to (escaped_id, tmpc);
2188 : : }
2189 : 70838 : if (!(flags & EAF_NOT_RETURNED_DIRECTLY))
2190 : : {
2191 : : struct constraint_expr *c;
2192 : : unsigned i;
2193 : 210364 : FOR_EACH_VEC_ELT (tmpc, i, c)
2194 : 69763 : results->safe_push (*c);
2195 : : }
2196 : 70838 : }
2197 : : }
2198 : 15143425 : }
2199 : :
2200 : : /* For non-IPA mode, generate constraints necessary for a call
2201 : : that returns a pointer and assigns it to LHS. This simply makes
2202 : : the LHS point to global and escaped variables. */
2203 : :
2204 : : static void
2205 : 5809805 : handle_lhs_call (gcall *stmt, tree lhs, int flags, vec<ce_s> &rhsc,
2206 : : tree fndecl)
2207 : : {
2208 : 5809805 : auto_vec<ce_s> lhsc;
2209 : :
2210 : 5809805 : get_constraint_for (lhs, &lhsc);
2211 : : /* If the store is to a global decl make sure to
2212 : : add proper escape constraints. */
2213 : 5809805 : lhs = get_base_address (lhs);
2214 : 5809805 : if (lhs
2215 : 5809805 : && DECL_P (lhs)
2216 : 6877715 : && is_global_var (lhs))
2217 : : {
2218 : 3277 : struct constraint_expr tmpc;
2219 : 3277 : tmpc.var = escaped_id;
2220 : 3277 : tmpc.offset = 0;
2221 : 3277 : tmpc.type = SCALAR;
2222 : 3277 : lhsc.safe_push (tmpc);
2223 : : }
2224 : :
2225 : : /* If the call returns an argument unmodified override the rhs
2226 : : constraints. */
2227 : 5809805 : if (flags & ERF_RETURNS_ARG
2228 : 5809805 : && (flags & ERF_RETURN_ARG_MASK) < gimple_call_num_args (stmt))
2229 : : {
2230 : 78206 : tree arg;
2231 : 78206 : rhsc.truncate (0);
2232 : 78206 : arg = gimple_call_arg (stmt, flags & ERF_RETURN_ARG_MASK);
2233 : 78206 : get_constraint_for (arg, &rhsc);
2234 : 78206 : process_all_all_constraints (lhsc, rhsc);
2235 : 78206 : rhsc.truncate (0);
2236 : : }
2237 : 5731599 : else if (flags & ERF_NOALIAS)
2238 : : {
2239 : 295998 : varinfo_t vi;
2240 : 295998 : struct constraint_expr tmpc;
2241 : 295998 : rhsc.truncate (0);
2242 : 295998 : vi = make_heapvar ("HEAP", true);
2243 : : /* We are marking allocated storage local, we deal with it becoming
2244 : : global by escaping and setting of vars_contains_escaped_heap. */
2245 : 295998 : DECL_EXTERNAL (vi->decl) = 0;
2246 : 295998 : vi->is_global_var = 0;
2247 : : /* If this is not a real malloc call assume the memory was
2248 : : initialized and thus may point to global memory. All
2249 : : builtin functions with the malloc attribute behave in a sane way. */
2250 : 295998 : if (!fndecl
2251 : 295998 : || !fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
2252 : 155623 : make_constraint_from (vi, nonlocal_id);
2253 : 295998 : tmpc.var = vi->id;
2254 : 295998 : tmpc.offset = 0;
2255 : 295998 : tmpc.type = ADDRESSOF;
2256 : 295998 : rhsc.safe_push (tmpc);
2257 : 295998 : process_all_all_constraints (lhsc, rhsc);
2258 : 295998 : rhsc.truncate (0);
2259 : : }
2260 : : else
2261 : 5435601 : process_all_all_constraints (lhsc, rhsc);
2262 : 5809805 : }
2263 : :
2264 : :
2265 : : /* Return the varinfo for the callee of CALL. */
2266 : :
2267 : : static varinfo_t
2268 : 16730996 : get_fi_for_callee (gcall *call)
2269 : : {
2270 : 16730996 : tree decl, fn = gimple_call_fn (call);
2271 : :
2272 : 16730996 : if (fn && TREE_CODE (fn) == OBJ_TYPE_REF)
2273 : 151937 : fn = OBJ_TYPE_REF_EXPR (fn);
2274 : :
2275 : : /* If we can directly resolve the function being called, do so.
2276 : : Otherwise, it must be some sort of indirect expression that
2277 : : we should still be able to handle. */
2278 : 16730996 : decl = gimple_call_addr_fndecl (fn);
2279 : 16730996 : if (decl)
2280 : 15317552 : return get_vi_for_tree (decl);
2281 : :
2282 : : /* If the function is anything other than a SSA name pointer we have no
2283 : : clue and should be getting ANYFN (well, ANYTHING for now). */
2284 : 1413444 : if (!fn || TREE_CODE (fn) != SSA_NAME)
2285 : 926076 : return get_varinfo (anything_id);
2286 : :
2287 : 487368 : if (SSA_NAME_IS_DEFAULT_DEF (fn)
2288 : 487368 : && (TREE_CODE (SSA_NAME_VAR (fn)) == PARM_DECL
2289 : 15 : || TREE_CODE (SSA_NAME_VAR (fn)) == RESULT_DECL))
2290 : 12355 : fn = SSA_NAME_VAR (fn);
2291 : :
2292 : 487368 : return get_vi_for_tree (fn);
2293 : : }
2294 : :
2295 : : /* Create constraints for assigning call argument ARG to the incoming parameter
2296 : : INDEX of function FI. */
2297 : :
2298 : : static void
2299 : 805446 : find_func_aliases_for_call_arg (varinfo_t fi, unsigned index, tree arg)
2300 : : {
2301 : 805446 : struct constraint_expr lhs;
2302 : 805446 : lhs = get_function_part_constraint (fi, fi_parm_base + index);
2303 : :
2304 : 805446 : auto_vec<ce_s, 2> rhsc;
2305 : 805446 : get_constraint_for_rhs (arg, &rhsc);
2306 : :
2307 : 805446 : unsigned j;
2308 : 805446 : struct constraint_expr *rhsp;
2309 : 3221785 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2310 : 805447 : process_constraint (new_constraint (lhs, *rhsp));
2311 : 805446 : }
2312 : :
2313 : : /* Return true if FNDECL may be part of another lto partition. */
2314 : :
2315 : : static bool
2316 : 41394 : fndecl_maybe_in_other_partition (tree fndecl)
2317 : : {
2318 : 41394 : cgraph_node *fn_node = cgraph_node::get (fndecl);
2319 : 41394 : if (fn_node == NULL)
2320 : : return true;
2321 : :
2322 : 41394 : return fn_node->in_other_partition;
2323 : : }
2324 : :
2325 : : /* Create constraints for the builtin call T. Return true if the call
2326 : : was handled, otherwise false. */
2327 : :
2328 : : static bool
2329 : 5065345 : find_func_aliases_for_builtin_call (struct function *fn, gcall *t)
2330 : : {
2331 : 5065345 : tree fndecl = gimple_call_fndecl (t);
2332 : 5065345 : auto_vec<ce_s, 2> lhsc;
2333 : 5065345 : auto_vec<ce_s, 4> rhsc;
2334 : 5065345 : varinfo_t fi;
2335 : :
2336 : 5065345 : if (gimple_call_builtin_p (t, BUILT_IN_NORMAL))
2337 : : /* ??? All builtins that are handled here need to be handled
2338 : : in the alias-oracle query functions explicitly! */
2339 : 4619657 : switch (DECL_FUNCTION_CODE (fndecl))
2340 : : {
2341 : : /* All the following functions return a pointer to the same object
2342 : : as their first argument points to. The functions do not add
2343 : : to the ESCAPED solution. The functions make the first argument
2344 : : pointed to memory point to what the second argument pointed to
2345 : : memory points to. */
2346 : 273221 : case BUILT_IN_STRCPY:
2347 : 273221 : case BUILT_IN_STRNCPY:
2348 : 273221 : case BUILT_IN_BCOPY:
2349 : 273221 : case BUILT_IN_MEMCPY:
2350 : 273221 : case BUILT_IN_MEMMOVE:
2351 : 273221 : case BUILT_IN_MEMPCPY:
2352 : 273221 : case BUILT_IN_STPCPY:
2353 : 273221 : case BUILT_IN_STPNCPY:
2354 : 273221 : case BUILT_IN_STRCAT:
2355 : 273221 : case BUILT_IN_STRNCAT:
2356 : 273221 : case BUILT_IN_STRCPY_CHK:
2357 : 273221 : case BUILT_IN_STRNCPY_CHK:
2358 : 273221 : case BUILT_IN_MEMCPY_CHK:
2359 : 273221 : case BUILT_IN_MEMMOVE_CHK:
2360 : 273221 : case BUILT_IN_MEMPCPY_CHK:
2361 : 273221 : case BUILT_IN_STPCPY_CHK:
2362 : 273221 : case BUILT_IN_STPNCPY_CHK:
2363 : 273221 : case BUILT_IN_STRCAT_CHK:
2364 : 273221 : case BUILT_IN_STRNCAT_CHK:
2365 : 273221 : case BUILT_IN_TM_MEMCPY:
2366 : 273221 : case BUILT_IN_TM_MEMMOVE:
2367 : 273221 : {
2368 : 273221 : tree res = gimple_call_lhs (t);
2369 : 546442 : tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
2370 : : == BUILT_IN_BCOPY ? 1 : 0));
2371 : 546442 : tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
2372 : 273221 : == BUILT_IN_BCOPY ? 0 : 1));
2373 : 273221 : if (res != NULL_TREE)
2374 : : {
2375 : 26056 : get_constraint_for (res, &lhsc);
2376 : 26056 : if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY
2377 : 22919 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY
2378 : 21744 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY
2379 : 19988 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY_CHK
2380 : 19651 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY_CHK
2381 : 45426 : || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY_CHK)
2382 : 6961 : get_constraint_for_ptr_offset (dest, NULL_TREE, &rhsc);
2383 : : else
2384 : 19095 : get_constraint_for (dest, &rhsc);
2385 : 26056 : process_all_all_constraints (lhsc, rhsc);
2386 : 26056 : lhsc.truncate (0);
2387 : 26056 : rhsc.truncate (0);
2388 : : }
2389 : 273221 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
2390 : 273221 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2391 : 273221 : do_deref (&lhsc);
2392 : 273221 : do_deref (&rhsc);
2393 : 273221 : process_all_all_constraints (lhsc, rhsc);
2394 : 273221 : return true;
2395 : : }
2396 : 73682 : case BUILT_IN_MEMSET:
2397 : 73682 : case BUILT_IN_MEMSET_CHK:
2398 : 73682 : case BUILT_IN_TM_MEMSET:
2399 : 73682 : {
2400 : 73682 : tree res = gimple_call_lhs (t);
2401 : 73682 : tree dest = gimple_call_arg (t, 0);
2402 : 73682 : unsigned i;
2403 : 73682 : ce_s *lhsp;
2404 : 73682 : struct constraint_expr ac;
2405 : 73682 : if (res != NULL_TREE)
2406 : : {
2407 : 5553 : get_constraint_for (res, &lhsc);
2408 : 5553 : get_constraint_for (dest, &rhsc);
2409 : 5553 : process_all_all_constraints (lhsc, rhsc);
2410 : 5553 : lhsc.truncate (0);
2411 : : }
2412 : 73682 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
2413 : 73682 : do_deref (&lhsc);
2414 : 73682 : if (flag_delete_null_pointer_checks
2415 : 147223 : && integer_zerop (gimple_call_arg (t, 1)))
2416 : : {
2417 : : ac.type = ADDRESSOF;
2418 : : ac.var = nothing_id;
2419 : : }
2420 : : else
2421 : : {
2422 : : ac.type = SCALAR;
2423 : : ac.var = integer_id;
2424 : : }
2425 : 73682 : ac.offset = 0;
2426 : 1471639 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
2427 : 79767 : process_constraint (new_constraint (*lhsp, ac));
2428 : : return true;
2429 : : }
2430 : : case BUILT_IN_STACK_SAVE:
2431 : : case BUILT_IN_STACK_RESTORE:
2432 : : /* Nothing interesting happens. */
2433 : : return true;
2434 : 32948 : case BUILT_IN_ALLOCA:
2435 : 32948 : case BUILT_IN_ALLOCA_WITH_ALIGN:
2436 : 32948 : case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX:
2437 : 32948 : {
2438 : 32948 : tree ptr = gimple_call_lhs (t);
2439 : 32948 : if (ptr == NULL_TREE)
2440 : : return true;
2441 : 32947 : get_constraint_for (ptr, &lhsc);
2442 : 32947 : varinfo_t vi = make_heapvar ("HEAP", true);
2443 : : /* Alloca storage is never global. To exempt it from escaped
2444 : : handling make it a non-heap var. */
2445 : 32947 : DECL_EXTERNAL (vi->decl) = 0;
2446 : 32947 : vi->is_global_var = 0;
2447 : 32947 : vi->is_heap_var = 0;
2448 : 32947 : struct constraint_expr tmpc;
2449 : 32947 : tmpc.var = vi->id;
2450 : 32947 : tmpc.offset = 0;
2451 : 32947 : tmpc.type = ADDRESSOF;
2452 : 32947 : rhsc.safe_push (tmpc);
2453 : 32947 : process_all_all_constraints (lhsc, rhsc);
2454 : 32947 : return true;
2455 : : }
2456 : 132 : case BUILT_IN_POSIX_MEMALIGN:
2457 : 132 : {
2458 : 132 : tree ptrptr = gimple_call_arg (t, 0);
2459 : 132 : get_constraint_for (ptrptr, &lhsc);
2460 : 132 : do_deref (&lhsc);
2461 : 132 : varinfo_t vi = make_heapvar ("HEAP", true);
2462 : : /* We are marking allocated storage local, we deal with it becoming
2463 : : global by escaping and setting of vars_contains_escaped_heap. */
2464 : 132 : DECL_EXTERNAL (vi->decl) = 0;
2465 : 132 : vi->is_global_var = 0;
2466 : 132 : struct constraint_expr tmpc;
2467 : 132 : tmpc.var = vi->id;
2468 : 132 : tmpc.offset = 0;
2469 : 132 : tmpc.type = ADDRESSOF;
2470 : 132 : rhsc.safe_push (tmpc);
2471 : 132 : process_all_all_constraints (lhsc, rhsc);
2472 : 132 : return true;
2473 : : }
2474 : 1670 : case BUILT_IN_ASSUME_ALIGNED:
2475 : 1670 : {
2476 : 1670 : tree res = gimple_call_lhs (t);
2477 : 1670 : tree dest = gimple_call_arg (t, 0);
2478 : 1670 : if (res != NULL_TREE)
2479 : : {
2480 : 1670 : get_constraint_for (res, &lhsc);
2481 : 1670 : get_constraint_for (dest, &rhsc);
2482 : 1670 : process_all_all_constraints (lhsc, rhsc);
2483 : : }
2484 : 1670 : return true;
2485 : : }
2486 : : /* All the following functions do not return pointers, do not
2487 : : modify the points-to sets of memory reachable from their
2488 : : arguments and do not add to the ESCAPED solution. */
2489 : : case BUILT_IN_SINCOS:
2490 : : case BUILT_IN_SINCOSF:
2491 : : case BUILT_IN_SINCOSL:
2492 : : case BUILT_IN_FREXP:
2493 : : case BUILT_IN_FREXPF:
2494 : : case BUILT_IN_FREXPL:
2495 : : case BUILT_IN_GAMMA_R:
2496 : : case BUILT_IN_GAMMAF_R:
2497 : : case BUILT_IN_GAMMAL_R:
2498 : : case BUILT_IN_LGAMMA_R:
2499 : : case BUILT_IN_LGAMMAF_R:
2500 : : case BUILT_IN_LGAMMAL_R:
2501 : : case BUILT_IN_MODF:
2502 : : case BUILT_IN_MODFF:
2503 : : case BUILT_IN_MODFL:
2504 : : case BUILT_IN_REMQUO:
2505 : : case BUILT_IN_REMQUOF:
2506 : : case BUILT_IN_REMQUOL:
2507 : : case BUILT_IN_FREE:
2508 : : return true;
2509 : 15595 : case BUILT_IN_STRDUP:
2510 : 15595 : case BUILT_IN_STRNDUP:
2511 : 15595 : case BUILT_IN_REALLOC:
2512 : 15595 : if (gimple_call_lhs (t))
2513 : : {
2514 : 15559 : auto_vec<ce_s> rhsc;
2515 : 15559 : handle_lhs_call (t, gimple_call_lhs (t),
2516 : 15559 : gimple_call_return_flags (t) | ERF_NOALIAS,
2517 : : rhsc, fndecl);
2518 : 15559 : get_constraint_for_ptr_offset (gimple_call_lhs (t),
2519 : : NULL_TREE, &lhsc);
2520 : 15559 : get_constraint_for_ptr_offset (gimple_call_arg (t, 0),
2521 : : NULL_TREE, &rhsc);
2522 : 15559 : do_deref (&lhsc);
2523 : 15559 : do_deref (&rhsc);
2524 : 15559 : process_all_all_constraints (lhsc, rhsc);
2525 : 15559 : lhsc.truncate (0);
2526 : 15559 : rhsc.truncate (0);
2527 : : /* For realloc the resulting pointer can be equal to the
2528 : : argument as well. But only doing this wouldn't be
2529 : : correct because with ptr == 0 realloc behaves like malloc. */
2530 : 15559 : if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_REALLOC)
2531 : : {
2532 : 13911 : get_constraint_for (gimple_call_lhs (t), &lhsc);
2533 : 13911 : get_constraint_for (gimple_call_arg (t, 0), &rhsc);
2534 : 13911 : process_all_all_constraints (lhsc, rhsc);
2535 : : }
2536 : 15559 : return true;
2537 : 15559 : }
2538 : : break;
2539 : : /* String / character search functions return a pointer into the
2540 : : source string or NULL. */
2541 : 10740 : case BUILT_IN_INDEX:
2542 : 10740 : case BUILT_IN_STRCHR:
2543 : 10740 : case BUILT_IN_STRRCHR:
2544 : 10740 : case BUILT_IN_MEMCHR:
2545 : 10740 : case BUILT_IN_STRSTR:
2546 : 10740 : case BUILT_IN_STRPBRK:
2547 : 10740 : if (gimple_call_lhs (t))
2548 : : {
2549 : 10740 : tree src = gimple_call_arg (t, 0);
2550 : 10740 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
2551 : 10740 : constraint_expr nul;
2552 : 10740 : nul.var = nothing_id;
2553 : 10740 : nul.offset = 0;
2554 : 10740 : nul.type = ADDRESSOF;
2555 : 10740 : rhsc.safe_push (nul);
2556 : 10740 : get_constraint_for (gimple_call_lhs (t), &lhsc);
2557 : 10740 : process_all_all_constraints (lhsc, rhsc);
2558 : : }
2559 : 10740 : return true;
2560 : : /* Pure functions that return something not based on any object and
2561 : : that use the memory pointed to by their arguments (but not
2562 : : transitively). */
2563 : 665230 : case BUILT_IN_STRCMP:
2564 : 665230 : case BUILT_IN_STRCMP_EQ:
2565 : 665230 : case BUILT_IN_STRNCMP:
2566 : 665230 : case BUILT_IN_STRNCMP_EQ:
2567 : 665230 : case BUILT_IN_STRCASECMP:
2568 : 665230 : case BUILT_IN_STRNCASECMP:
2569 : 665230 : case BUILT_IN_MEMCMP:
2570 : 665230 : case BUILT_IN_BCMP:
2571 : 665230 : case BUILT_IN_STRSPN:
2572 : 665230 : case BUILT_IN_STRCSPN:
2573 : 665230 : {
2574 : 665230 : varinfo_t uses = get_call_use_vi (t);
2575 : 665230 : make_any_offset_constraints (uses);
2576 : 665230 : make_constraint_to (uses->id, gimple_call_arg (t, 0));
2577 : 665230 : make_constraint_to (uses->id, gimple_call_arg (t, 1));
2578 : : /* No constraints are necessary for the return value. */
2579 : 665230 : return true;
2580 : : }
2581 : 49277 : case BUILT_IN_STRLEN:
2582 : 49277 : {
2583 : 49277 : varinfo_t uses = get_call_use_vi (t);
2584 : 49277 : make_any_offset_constraints (uses);
2585 : 49277 : make_constraint_to (uses->id, gimple_call_arg (t, 0));
2586 : : /* No constraints are necessary for the return value. */
2587 : 49277 : return true;
2588 : : }
2589 : : case BUILT_IN_OBJECT_SIZE:
2590 : : case BUILT_IN_CONSTANT_P:
2591 : : {
2592 : : /* No constraints are necessary for the return value or the
2593 : : arguments. */
2594 : : return true;
2595 : : }
2596 : : /* Trampolines are special - they set up passing the static
2597 : : frame. */
2598 : 498 : case BUILT_IN_INIT_TRAMPOLINE:
2599 : 498 : {
2600 : 498 : tree tramp = gimple_call_arg (t, 0);
2601 : 498 : tree nfunc = gimple_call_arg (t, 1);
2602 : 498 : tree frame = gimple_call_arg (t, 2);
2603 : 498 : unsigned i;
2604 : 498 : struct constraint_expr lhs, *rhsp;
2605 : 498 : if (in_ipa_mode)
2606 : : {
2607 : 7 : varinfo_t nfi = NULL;
2608 : 7 : gcc_assert (TREE_CODE (nfunc) == ADDR_EXPR);
2609 : 7 : nfi = lookup_vi_for_tree (TREE_OPERAND (nfunc, 0));
2610 : 7 : if (nfi)
2611 : : {
2612 : 7 : lhs = get_function_part_constraint (nfi, fi_static_chain);
2613 : 7 : get_constraint_for (frame, &rhsc);
2614 : 21 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
2615 : 7 : process_constraint (new_constraint (lhs, *rhsp));
2616 : 7 : rhsc.truncate (0);
2617 : :
2618 : : /* Make the frame point to the function for
2619 : : the trampoline adjustment call. */
2620 : 7 : get_constraint_for (tramp, &lhsc);
2621 : 7 : do_deref (&lhsc);
2622 : 7 : get_constraint_for (nfunc, &rhsc);
2623 : 7 : process_all_all_constraints (lhsc, rhsc);
2624 : :
2625 : 7 : return true;
2626 : : }
2627 : : }
2628 : : /* Else fallthru to generic handling which will let
2629 : : the frame escape. */
2630 : 491 : break;
2631 : : }
2632 : 533 : case BUILT_IN_ADJUST_TRAMPOLINE:
2633 : 533 : {
2634 : 533 : tree tramp = gimple_call_arg (t, 0);
2635 : 533 : tree res = gimple_call_lhs (t);
2636 : 533 : if (in_ipa_mode && res)
2637 : : {
2638 : 7 : get_constraint_for (res, &lhsc);
2639 : 7 : get_constraint_for (tramp, &rhsc);
2640 : 7 : do_deref (&rhsc);
2641 : 7 : process_all_all_constraints (lhsc, rhsc);
2642 : : }
2643 : 533 : return true;
2644 : : }
2645 : 4 : CASE_BUILT_IN_TM_STORE (1):
2646 : 4 : CASE_BUILT_IN_TM_STORE (2):
2647 : 4 : CASE_BUILT_IN_TM_STORE (4):
2648 : 4 : CASE_BUILT_IN_TM_STORE (8):
2649 : 4 : CASE_BUILT_IN_TM_STORE (FLOAT):
2650 : 4 : CASE_BUILT_IN_TM_STORE (DOUBLE):
2651 : 4 : CASE_BUILT_IN_TM_STORE (LDOUBLE):
2652 : 4 : CASE_BUILT_IN_TM_STORE (M64):
2653 : 4 : CASE_BUILT_IN_TM_STORE (M128):
2654 : 4 : CASE_BUILT_IN_TM_STORE (M256):
2655 : 4 : {
2656 : 4 : tree addr = gimple_call_arg (t, 0);
2657 : 4 : tree src = gimple_call_arg (t, 1);
2658 : :
2659 : 4 : get_constraint_for (addr, &lhsc);
2660 : 4 : do_deref (&lhsc);
2661 : 4 : get_constraint_for (src, &rhsc);
2662 : 4 : process_all_all_constraints (lhsc, rhsc);
2663 : 4 : return true;
2664 : : }
2665 : 10 : CASE_BUILT_IN_TM_LOAD (1):
2666 : 10 : CASE_BUILT_IN_TM_LOAD (2):
2667 : 10 : CASE_BUILT_IN_TM_LOAD (4):
2668 : 10 : CASE_BUILT_IN_TM_LOAD (8):
2669 : 10 : CASE_BUILT_IN_TM_LOAD (FLOAT):
2670 : 10 : CASE_BUILT_IN_TM_LOAD (DOUBLE):
2671 : 10 : CASE_BUILT_IN_TM_LOAD (LDOUBLE):
2672 : 10 : CASE_BUILT_IN_TM_LOAD (M64):
2673 : 10 : CASE_BUILT_IN_TM_LOAD (M128):
2674 : 10 : CASE_BUILT_IN_TM_LOAD (M256):
2675 : 10 : {
2676 : 10 : tree dest = gimple_call_lhs (t);
2677 : 10 : tree addr = gimple_call_arg (t, 0);
2678 : :
2679 : 10 : get_constraint_for (dest, &lhsc);
2680 : 10 : get_constraint_for (addr, &rhsc);
2681 : 10 : do_deref (&rhsc);
2682 : 10 : process_all_all_constraints (lhsc, rhsc);
2683 : 10 : return true;
2684 : : }
2685 : : /* Variadic argument handling needs to be handled in IPA
2686 : : mode as well. */
2687 : 19805 : case BUILT_IN_VA_START:
2688 : 19805 : {
2689 : 19805 : tree valist = gimple_call_arg (t, 0);
2690 : 19805 : struct constraint_expr rhs, *lhsp;
2691 : 19805 : unsigned i;
2692 : 19805 : get_constraint_for_ptr_offset (valist, NULL_TREE, &lhsc);
2693 : 19805 : do_deref (&lhsc);
2694 : : /* The va_list gets access to pointers in variadic
2695 : : arguments. Which we know in the case of IPA analysis
2696 : : and otherwise are just all nonlocal variables. */
2697 : 19805 : if (in_ipa_mode)
2698 : : {
2699 : 7 : fi = lookup_vi_for_tree (fn->decl);
2700 : 7 : rhs = get_function_part_constraint (fi, ~0);
2701 : 7 : rhs.type = ADDRESSOF;
2702 : : }
2703 : : else
2704 : : {
2705 : : rhs.var = nonlocal_id;
2706 : : rhs.type = ADDRESSOF;
2707 : : rhs.offset = 0;
2708 : : }
2709 : 39777 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
2710 : 19972 : process_constraint (new_constraint (*lhsp, rhs));
2711 : : /* va_list is clobbered. */
2712 : 19805 : make_constraint_to (get_call_clobber_vi (t)->id, valist);
2713 : 19805 : return true;
2714 : : }
2715 : : /* va_end doesn't have any effect that matters. */
2716 : : case BUILT_IN_VA_END:
2717 : : return true;
2718 : : /* Alternate return. Simply give up for now. */
2719 : 940 : case BUILT_IN_RETURN:
2720 : 940 : {
2721 : 940 : fi = NULL;
2722 : 940 : if (!in_ipa_mode
2723 : 940 : || !(fi = get_vi_for_tree (fn->decl)))
2724 : 940 : make_constraint_from (get_varinfo (escaped_id), anything_id);
2725 : 0 : else if (in_ipa_mode
2726 : : && fi != NULL)
2727 : : {
2728 : 0 : struct constraint_expr lhs, rhs;
2729 : 0 : lhs = get_function_part_constraint (fi, fi_result);
2730 : 0 : rhs.var = anything_id;
2731 : 0 : rhs.offset = 0;
2732 : 0 : rhs.type = SCALAR;
2733 : 0 : process_constraint (new_constraint (lhs, rhs));
2734 : : }
2735 : 940 : return true;
2736 : : }
2737 : 54768 : case BUILT_IN_GOMP_PARALLEL:
2738 : 54768 : case BUILT_IN_GOACC_PARALLEL:
2739 : 54768 : {
2740 : 54768 : if (in_ipa_mode)
2741 : : {
2742 : 13798 : unsigned int fnpos, argpos;
2743 : 13798 : switch (DECL_FUNCTION_CODE (fndecl))
2744 : : {
2745 : : case BUILT_IN_GOMP_PARALLEL:
2746 : : /* __builtin_GOMP_parallel (fn, data, num_threads, flags). */
2747 : : fnpos = 0;
2748 : : argpos = 1;
2749 : : break;
2750 : 13785 : case BUILT_IN_GOACC_PARALLEL:
2751 : : /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs,
2752 : : sizes, kinds, ...). */
2753 : 13785 : fnpos = 1;
2754 : 13785 : argpos = 3;
2755 : 13785 : break;
2756 : 0 : default:
2757 : 0 : gcc_unreachable ();
2758 : : }
2759 : :
2760 : 13798 : tree fnarg = gimple_call_arg (t, fnpos);
2761 : 13798 : gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR);
2762 : 13798 : tree fndecl = TREE_OPERAND (fnarg, 0);
2763 : 13798 : if (fndecl_maybe_in_other_partition (fndecl))
2764 : : /* Fallthru to general call handling. */
2765 : : break;
2766 : :
2767 : 13755 : tree arg = gimple_call_arg (t, argpos);
2768 : :
2769 : 13755 : varinfo_t fi = get_vi_for_tree (fndecl);
2770 : 13755 : find_func_aliases_for_call_arg (fi, 0, arg);
2771 : 13755 : return true;
2772 : : }
2773 : : /* Else fallthru to generic call handling. */
2774 : : break;
2775 : : }
2776 : : /* printf-style functions may have hooks to set pointers to
2777 : : point to somewhere into the generated string. Leave them
2778 : : for a later exercise... */
2779 : 43 : default:
2780 : : /* Fallthru to general call handling. */;
2781 : : }
2782 : :
2783 : : return false;
2784 : 5065345 : }
2785 : :
2786 : : /* Create constraints for the call T. */
2787 : :
2788 : : static void
2789 : 17640171 : find_func_aliases_for_call (struct function *fn, gcall *t)
2790 : : {
2791 : 17640171 : tree fndecl = gimple_call_fndecl (t);
2792 : 17640171 : varinfo_t fi;
2793 : :
2794 : 17640171 : if (fndecl != NULL_TREE
2795 : 16576830 : && fndecl_built_in_p (fndecl)
2796 : 22705516 : && find_func_aliases_for_builtin_call (fn, t))
2797 : : return;
2798 : :
2799 : 16321981 : if (gimple_call_internal_p (t, IFN_DEFERRED_INIT))
2800 : : return;
2801 : :
2802 : 16321446 : fi = get_fi_for_callee (t);
2803 : 16321446 : if (!in_ipa_mode
2804 : 236462 : || (fi->decl && fndecl && !fi->is_fn_info))
2805 : : {
2806 : 16138957 : auto_vec<ce_s, 16> rhsc;
2807 : 16138957 : int flags = gimple_call_flags (t);
2808 : :
2809 : : /* Const functions can return their arguments and addresses
2810 : : of global memory but not of escaped memory. */
2811 : 16138957 : if (flags & (ECF_CONST|ECF_NOVOPS))
2812 : : {
2813 : 1575769 : if (gimple_call_lhs (t))
2814 : 919790 : handle_rhs_call (t, &rhsc, implicit_const_eaf_flags, false, false);
2815 : : }
2816 : : /* Pure functions can return addresses in and of memory
2817 : : reachable from their arguments, but they are not an escape
2818 : : point for reachable memory of their arguments. */
2819 : 14563188 : else if (flags & (ECF_PURE|ECF_LOOPING_CONST_OR_PURE))
2820 : 542954 : handle_rhs_call (t, &rhsc, implicit_pure_eaf_flags, false, true);
2821 : : /* If the call is to a replaceable operator delete and results
2822 : : from a delete expression as opposed to a direct call to
2823 : : such operator, then the effects for PTA (in particular
2824 : : the escaping of the pointer) can be ignored. */
2825 : 14020234 : else if (fndecl
2826 : 13396714 : && DECL_IS_OPERATOR_DELETE_P (fndecl)
2827 : 14364998 : && gimple_call_from_new_or_delete (t))
2828 : : ;
2829 : : else
2830 : 13680681 : handle_rhs_call (t, &rhsc, 0, true, true);
2831 : 16138957 : if (gimple_call_lhs (t))
2832 : 5794246 : handle_lhs_call (t, gimple_call_lhs (t),
2833 : : gimple_call_return_flags (t), rhsc, fndecl);
2834 : 16138957 : }
2835 : : else
2836 : : {
2837 : 182489 : auto_vec<ce_s, 2> rhsc;
2838 : 182489 : tree lhsop;
2839 : 182489 : unsigned j;
2840 : :
2841 : : /* Assign all the passed arguments to the appropriate incoming
2842 : : parameters of the function. */
2843 : 974180 : for (j = 0; j < gimple_call_num_args (t); j++)
2844 : : {
2845 : 791691 : tree arg = gimple_call_arg (t, j);
2846 : 791691 : find_func_aliases_for_call_arg (fi, j, arg);
2847 : : }
2848 : :
2849 : : /* If we are returning a value, assign it to the result. */
2850 : 182489 : lhsop = gimple_call_lhs (t);
2851 : 182489 : if (lhsop)
2852 : : {
2853 : 162433 : auto_vec<ce_s, 2> lhsc;
2854 : 162433 : struct constraint_expr rhs;
2855 : 162433 : struct constraint_expr *lhsp;
2856 : 163285 : bool aggr_p = aggregate_value_p (lhsop, gimple_call_fntype (t));
2857 : :
2858 : 162433 : get_constraint_for (lhsop, &lhsc);
2859 : 162433 : rhs = get_function_part_constraint (fi, fi_result);
2860 : 162433 : if (aggr_p)
2861 : : {
2862 : 10 : auto_vec<ce_s, 2> tem;
2863 : 10 : tem.quick_push (rhs);
2864 : 10 : do_deref (&tem);
2865 : 10 : gcc_checking_assert (tem.length () == 1);
2866 : 10 : rhs = tem[0];
2867 : 10 : }
2868 : 324869 : FOR_EACH_VEC_ELT (lhsc, j, lhsp)
2869 : 162436 : process_constraint (new_constraint (*lhsp, rhs));
2870 : :
2871 : : /* If we pass the result decl by reference, honor that. */
2872 : 162433 : if (aggr_p)
2873 : : {
2874 : 10 : struct constraint_expr lhs;
2875 : 10 : struct constraint_expr *rhsp;
2876 : :
2877 : 10 : get_constraint_for_address_of (lhsop, &rhsc);
2878 : 10 : lhs = get_function_part_constraint (fi, fi_result);
2879 : 30 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2880 : 10 : process_constraint (new_constraint (lhs, *rhsp));
2881 : 10 : rhsc.truncate (0);
2882 : : }
2883 : 162433 : }
2884 : :
2885 : : /* If we use a static chain, pass it along. */
2886 : 182489 : if (gimple_call_chain (t))
2887 : : {
2888 : 278 : struct constraint_expr lhs;
2889 : 278 : struct constraint_expr *rhsp;
2890 : :
2891 : 278 : get_constraint_for (gimple_call_chain (t), &rhsc);
2892 : 278 : lhs = get_function_part_constraint (fi, fi_static_chain);
2893 : 1112 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
2894 : 278 : process_constraint (new_constraint (lhs, *rhsp));
2895 : : }
2896 : 182489 : }
2897 : : }
2898 : :
2899 : : /* Walk statement T setting up aliasing constraints according to the
2900 : : references found in T. This function is the main part of the
2901 : : constraint builder. AI points to auxiliary alias information used
2902 : : when building alias sets and computing alias grouping heuristics. */
2903 : :
2904 : : static void
2905 : 259929467 : find_func_aliases (struct function *fn, gimple *origt)
2906 : : {
2907 : 259929467 : gimple *t = origt;
2908 : 259929467 : auto_vec<ce_s, 16> lhsc;
2909 : 259929467 : auto_vec<ce_s, 16> rhsc;
2910 : 259929467 : varinfo_t fi;
2911 : :
2912 : : /* Now build constraints expressions. */
2913 : 259929467 : if (gimple_code (t) == GIMPLE_PHI)
2914 : : {
2915 : : /* For a phi node, assign all the arguments to
2916 : : the result. */
2917 : 6367377 : get_constraint_for (gimple_phi_result (t), &lhsc);
2918 : 21350902 : for (unsigned i = 0; i < gimple_phi_num_args (t); i++)
2919 : : {
2920 : 14983525 : get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc);
2921 : 14983525 : process_all_all_constraints (lhsc, rhsc);
2922 : 14983525 : rhsc.truncate (0);
2923 : : }
2924 : : }
2925 : : /* In IPA mode, we need to generate constraints to pass call
2926 : : arguments through their calls. There are two cases,
2927 : : either a GIMPLE_CALL returning a value, or just a plain
2928 : : GIMPLE_CALL when we are not.
2929 : :
2930 : : In non-ipa mode, we need to generate constraints for each
2931 : : pointer passed by address. */
2932 : 253562090 : else if (is_gimple_call (t))
2933 : 17640171 : find_func_aliases_for_call (fn, as_a <gcall *> (t));
2934 : :
2935 : : /* Otherwise, just a regular assignment statement. Only care about
2936 : : operations with pointer result, others are dealt with as escape
2937 : : points if they have pointer operands. */
2938 : 235921919 : else if (is_gimple_assign (t))
2939 : : {
2940 : : /* Otherwise, just a regular assignment statement. */
2941 : 80915715 : tree lhsop = gimple_assign_lhs (t);
2942 : 80915715 : tree rhsop = (gimple_num_ops (t) == 2) ? gimple_assign_rhs1 (t) : NULL;
2943 : :
2944 : 63533175 : if (rhsop && TREE_CLOBBER_P (rhsop))
2945 : : /* Ignore clobbers, they don't actually store anything into
2946 : : the LHS. */
2947 : : ;
2948 : 57252704 : else if (rhsop && AGGREGATE_TYPE_P (TREE_TYPE (lhsop)))
2949 : 2753118 : do_structure_copy (lhsop, rhsop);
2950 : : else
2951 : : {
2952 : 71882126 : enum tree_code code = gimple_assign_rhs_code (t);
2953 : :
2954 : 71882126 : get_constraint_for (lhsop, &lhsc);
2955 : :
2956 : 71882126 : if (code == POINTER_PLUS_EXPR)
2957 : 2667206 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2958 : : gimple_assign_rhs2 (t), &rhsc);
2959 : 69214920 : else if (code == POINTER_DIFF_EXPR)
2960 : : /* The result is not a pointer (part). */
2961 : : ;
2962 : 68863431 : else if (code == BIT_AND_EXPR
2963 : 68863431 : && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST)
2964 : : {
2965 : : /* Aligning a pointer via a BIT_AND_EXPR is offsetting
2966 : : the pointer. Handle it by offsetting it by UNKNOWN. */
2967 : 633718 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2968 : : NULL_TREE, &rhsc);
2969 : : }
2970 : 68229713 : else if (code == TRUNC_DIV_EXPR
2971 : : || code == CEIL_DIV_EXPR
2972 : : || code == FLOOR_DIV_EXPR
2973 : 68229713 : || code == ROUND_DIV_EXPR
2974 : 68229713 : || code == EXACT_DIV_EXPR
2975 : : || code == TRUNC_MOD_EXPR
2976 : 67853488 : || code == CEIL_MOD_EXPR
2977 : : || code == FLOOR_MOD_EXPR
2978 : 67685314 : || code == ROUND_MOD_EXPR)
2979 : : /* Division and modulo transfer the pointer from the LHS. */
2980 : 545535 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
2981 : : NULL_TREE, &rhsc);
2982 : 67684178 : else if (CONVERT_EXPR_CODE_P (code)
2983 : 67684178 : || gimple_assign_single_p (t))
2984 : : /* See through conversions, single RHS are handled by
2985 : : get_constraint_for_rhs. */
2986 : 53802258 : get_constraint_for_rhs (rhsop, &rhsc);
2987 : 13881920 : else if (code == COND_EXPR)
2988 : : {
2989 : : /* The result is a merge of both COND_EXPR arms. */
2990 : 9894 : auto_vec<ce_s, 2> tmp;
2991 : 9894 : struct constraint_expr *rhsp;
2992 : 9894 : unsigned i;
2993 : 9894 : get_constraint_for_rhs (gimple_assign_rhs2 (t), &rhsc);
2994 : 9894 : get_constraint_for_rhs (gimple_assign_rhs3 (t), &tmp);
2995 : 39576 : FOR_EACH_VEC_ELT (tmp, i, rhsp)
2996 : 9894 : rhsc.safe_push (*rhsp);
2997 : 9894 : }
2998 : 13872026 : else if (truth_value_p (code))
2999 : : /* Truth value results are not pointer (parts). Or at least
3000 : : very unreasonable obfuscation of a part. */
3001 : : ;
3002 : : else
3003 : : {
3004 : : /* All other operations are possibly offsetting merges. */
3005 : 12486435 : auto_vec<ce_s, 4> tmp;
3006 : 12486435 : struct constraint_expr *rhsp;
3007 : 12486435 : unsigned i, j;
3008 : 12486435 : get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
3009 : : NULL_TREE, &rhsc);
3010 : 36849735 : for (i = 2; i < gimple_num_ops (t); ++i)
3011 : : {
3012 : 11876865 : get_constraint_for_ptr_offset (gimple_op (t, i),
3013 : : NULL_TREE, &tmp);
3014 : 35630595 : FOR_EACH_VEC_ELT (tmp, j, rhsp)
3015 : 11876865 : rhsc.safe_push (*rhsp);
3016 : 11876865 : tmp.truncate (0);
3017 : : }
3018 : 12486435 : }
3019 : 71882126 : process_all_all_constraints (lhsc, rhsc);
3020 : : }
3021 : : /* If there is a store to a global variable the rhs escapes. */
3022 : 80915715 : if ((lhsop = get_base_address (lhsop)) != NULL_TREE
3023 : 80915715 : && DECL_P (lhsop))
3024 : : {
3025 : 23003098 : varinfo_t vi = get_vi_for_tree (lhsop);
3026 : 23003098 : if ((! in_ipa_mode && vi->is_global_var)
3027 : 21404540 : || vi->is_ipa_escape_point)
3028 : 1601130 : make_escape_constraint (rhsop);
3029 : : }
3030 : : }
3031 : : /* Handle escapes through return. */
3032 : 155006204 : else if (gimple_code (t) == GIMPLE_RETURN
3033 : 155006204 : && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE)
3034 : : {
3035 : 2482105 : greturn *return_stmt = as_a <greturn *> (t);
3036 : 2482105 : tree retval = gimple_return_retval (return_stmt);
3037 : 2482105 : if (!in_ipa_mode)
3038 : 2477847 : make_constraint_to (escaped_return_id, retval);
3039 : : else
3040 : : {
3041 : 4258 : struct constraint_expr lhs ;
3042 : 4258 : struct constraint_expr *rhsp;
3043 : 4258 : unsigned i;
3044 : :
3045 : 4258 : fi = lookup_vi_for_tree (fn->decl);
3046 : 4258 : lhs = get_function_part_constraint (fi, fi_result);
3047 : 4258 : get_constraint_for_rhs (retval, &rhsc);
3048 : 17032 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
3049 : 4258 : process_constraint (new_constraint (lhs, *rhsp));
3050 : : }
3051 : : }
3052 : : /* Handle asms conservatively by adding escape constraints to everything. */
3053 : 260163301 : else if (gasm *asm_stmt = dyn_cast <gasm *> (t))
3054 : : {
3055 : 233834 : unsigned i, noutputs;
3056 : 233834 : const char **oconstraints;
3057 : 233834 : const char *constraint;
3058 : 233834 : bool allows_mem, allows_reg, is_inout;
3059 : :
3060 : 233834 : noutputs = gimple_asm_noutputs (asm_stmt);
3061 : 233834 : oconstraints = XALLOCAVEC (const char *, noutputs);
3062 : :
3063 : 458496 : for (i = 0; i < noutputs; ++i)
3064 : : {
3065 : 224662 : tree link = gimple_asm_output_op (asm_stmt, i);
3066 : 224662 : tree op = TREE_VALUE (link);
3067 : :
3068 : 224662 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
3069 : 224662 : oconstraints[i] = constraint;
3070 : 224662 : parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
3071 : : &allows_reg, &is_inout, nullptr);
3072 : :
3073 : : /* A memory constraint makes the address of the operand escape. */
3074 : 224662 : if (!allows_reg && allows_mem)
3075 : : {
3076 : 10911 : auto_vec<ce_s> tmpc;
3077 : 10911 : get_constraint_for_address_of (op, &tmpc);
3078 : 10911 : make_constraints_to (escaped_id, tmpc);
3079 : 10911 : }
3080 : :
3081 : : /* The asm may read global memory, so outputs may point to
3082 : : any global memory. */
3083 : 224662 : if (op)
3084 : : {
3085 : 224662 : auto_vec<ce_s, 2> lhsc;
3086 : 224662 : struct constraint_expr rhsc, *lhsp;
3087 : 224662 : unsigned j;
3088 : 224662 : get_constraint_for (op, &lhsc);
3089 : 224662 : rhsc.var = nonlocal_id;
3090 : 224662 : rhsc.offset = 0;
3091 : 224662 : rhsc.type = SCALAR;
3092 : 898651 : FOR_EACH_VEC_ELT (lhsc, j, lhsp)
3093 : 224665 : process_constraint (new_constraint (*lhsp, rhsc));
3094 : 224662 : }
3095 : : }
3096 : 374102 : for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
3097 : : {
3098 : 140268 : tree link = gimple_asm_input_op (asm_stmt, i);
3099 : 140268 : tree op = TREE_VALUE (link);
3100 : :
3101 : 140268 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
3102 : :
3103 : 140268 : parse_input_constraint (&constraint, 0, 0, noutputs, 0, oconstraints,
3104 : : &allows_mem, &allows_reg, nullptr);
3105 : :
3106 : : /* A memory constraint makes the address of the operand escape. */
3107 : 140268 : if (!allows_reg && allows_mem)
3108 : : {
3109 : 12085 : auto_vec<ce_s> tmpc;
3110 : 12085 : get_constraint_for_address_of (op, &tmpc);
3111 : 12085 : make_constraints_to (escaped_id, tmpc);
3112 : 12085 : }
3113 : : /* Strictly we'd only need the constraint to ESCAPED if
3114 : : the asm clobbers memory, otherwise using something
3115 : : along the lines of per-call clobbers/uses would be enough. */
3116 : 128183 : else if (op)
3117 : 128183 : make_escape_constraint (op);
3118 : : }
3119 : : }
3120 : 259929467 : }
3121 : :
3122 : :
3123 : : /* Create a constraint adding to the clobber set of FI the memory
3124 : : pointed to by PTR. */
3125 : :
3126 : : static void
3127 : 0 : process_ipa_clobber (varinfo_t fi, tree ptr)
3128 : : {
3129 : 0 : vec<ce_s> ptrc = vNULL;
3130 : 0 : struct constraint_expr *c, lhs;
3131 : 0 : unsigned i;
3132 : 0 : get_constraint_for_rhs (ptr, &ptrc);
3133 : 0 : lhs = get_function_part_constraint (fi, fi_clobbers);
3134 : 0 : FOR_EACH_VEC_ELT (ptrc, i, c)
3135 : 0 : process_constraint (new_constraint (lhs, *c));
3136 : 0 : ptrc.release ();
3137 : 0 : }
3138 : :
3139 : : /* Walk statement T setting up clobber and use constraints according to the
3140 : : references found in T. This function is a main part of the
3141 : : IPA constraint builder. */
3142 : :
3143 : : static void
3144 : 956204 : find_func_clobbers (struct function *fn, gimple *origt)
3145 : : {
3146 : 956204 : gimple *t = origt;
3147 : 956204 : auto_vec<ce_s, 16> lhsc;
3148 : 956204 : auto_vec<ce_s, 16> rhsc;
3149 : 956204 : varinfo_t fi;
3150 : :
3151 : : /* Add constraints for clobbered/used in IPA mode.
3152 : : We are not interested in what automatic variables are clobbered
3153 : : or used as we only use the information in the caller to which
3154 : : they do not escape. */
3155 : 956204 : gcc_assert (in_ipa_mode);
3156 : :
3157 : : /* If the stmt refers to memory in any way it better had a VUSE. */
3158 : 2040264 : if (gimple_vuse (t) == NULL_TREE)
3159 : : return;
3160 : :
3161 : : /* We'd better have function information for the current function. */
3162 : 626081 : fi = lookup_vi_for_tree (fn->decl);
3163 : 626081 : gcc_assert (fi != NULL);
3164 : :
3165 : : /* Account for stores in assignments and calls. */
3166 : 626081 : if (gimple_vdef (t) != NULL_TREE
3167 : 822893 : && gimple_has_lhs (t))
3168 : : {
3169 : 329146 : tree lhs = gimple_get_lhs (t);
3170 : 329146 : tree tem = lhs;
3171 : 832052 : while (handled_component_p (tem))
3172 : 173760 : tem = TREE_OPERAND (tem, 0);
3173 : 329146 : if ((DECL_P (tem)
3174 : 187099 : && !auto_var_in_fn_p (tem, fn->decl))
3175 : 323977 : || INDIRECT_REF_P (tem)
3176 : 653123 : || (TREE_CODE (tem) == MEM_REF
3177 : 29822 : && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
3178 : : && auto_var_in_fn_p
3179 : 4201 : (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl))))
3180 : : {
3181 : 27489 : struct constraint_expr lhsc, *rhsp;
3182 : 27489 : unsigned i;
3183 : 27489 : lhsc = get_function_part_constraint (fi, fi_clobbers);
3184 : 27489 : get_constraint_for_address_of (lhs, &rhsc);
3185 : 82467 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
3186 : 27489 : process_constraint (new_constraint (lhsc, *rhsp));
3187 : 27489 : rhsc.truncate (0);
3188 : : }
3189 : : }
3190 : :
3191 : : /* Account for uses in assigments and returns. */
3192 : 626081 : if (gimple_assign_single_p (t)
3193 : 626081 : || (gimple_code (t) == GIMPLE_RETURN
3194 : 23047 : && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE))
3195 : : {
3196 : 357297 : tree rhs = (gimple_assign_single_p (t)
3197 : 357297 : ? gimple_assign_rhs1 (t)
3198 : 4258 : : gimple_return_retval (as_a <greturn *> (t)));
3199 : 357297 : tree tem = rhs;
3200 : 512278 : while (handled_component_p (tem))
3201 : 154981 : tem = TREE_OPERAND (tem, 0);
3202 : 357297 : if ((DECL_P (tem)
3203 : 53277 : && !auto_var_in_fn_p (tem, fn->decl))
3204 : 348554 : || INDIRECT_REF_P (tem)
3205 : 705851 : || (TREE_CODE (tem) == MEM_REF
3206 : 88809 : && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR
3207 : : && auto_var_in_fn_p
3208 : 1214 : (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl))))
3209 : : {
3210 : 95716 : struct constraint_expr lhs, *rhsp;
3211 : 95716 : unsigned i;
3212 : 95716 : lhs = get_function_part_constraint (fi, fi_uses);
3213 : 95716 : get_constraint_for_address_of (rhs, &rhsc);
3214 : 287148 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
3215 : 95716 : process_constraint (new_constraint (lhs, *rhsp));
3216 : 95716 : rhsc.truncate (0);
3217 : : }
3218 : : }
3219 : :
3220 : 626081 : if (gcall *call_stmt = dyn_cast <gcall *> (t))
3221 : : {
3222 : 249953 : varinfo_t cfi = NULL;
3223 : 249953 : tree decl = gimple_call_fndecl (t);
3224 : 249953 : struct constraint_expr lhs, rhs;
3225 : 249953 : unsigned i, j;
3226 : :
3227 : : /* For builtins we do not have separate function info. For those
3228 : : we do not generate escapes for we have to generate clobbers/uses. */
3229 : 249953 : if (gimple_call_builtin_p (t, BUILT_IN_NORMAL))
3230 : 36252 : switch (DECL_FUNCTION_CODE (decl))
3231 : : {
3232 : : /* The following functions use and clobber memory pointed to
3233 : : by their arguments. */
3234 : 162 : case BUILT_IN_STRCPY:
3235 : 162 : case BUILT_IN_STRNCPY:
3236 : 162 : case BUILT_IN_BCOPY:
3237 : 162 : case BUILT_IN_MEMCPY:
3238 : 162 : case BUILT_IN_MEMMOVE:
3239 : 162 : case BUILT_IN_MEMPCPY:
3240 : 162 : case BUILT_IN_STPCPY:
3241 : 162 : case BUILT_IN_STPNCPY:
3242 : 162 : case BUILT_IN_STRCAT:
3243 : 162 : case BUILT_IN_STRNCAT:
3244 : 162 : case BUILT_IN_STRCPY_CHK:
3245 : 162 : case BUILT_IN_STRNCPY_CHK:
3246 : 162 : case BUILT_IN_MEMCPY_CHK:
3247 : 162 : case BUILT_IN_MEMMOVE_CHK:
3248 : 162 : case BUILT_IN_MEMPCPY_CHK:
3249 : 162 : case BUILT_IN_STPCPY_CHK:
3250 : 162 : case BUILT_IN_STPNCPY_CHK:
3251 : 162 : case BUILT_IN_STRCAT_CHK:
3252 : 162 : case BUILT_IN_STRNCAT_CHK:
3253 : 162 : {
3254 : 324 : tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
3255 : : == BUILT_IN_BCOPY ? 1 : 0));
3256 : 324 : tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
3257 : 162 : == BUILT_IN_BCOPY ? 0 : 1));
3258 : 162 : unsigned i;
3259 : 162 : struct constraint_expr *rhsp, *lhsp;
3260 : 162 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
3261 : 162 : lhs = get_function_part_constraint (fi, fi_clobbers);
3262 : 486 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
3263 : 162 : process_constraint (new_constraint (lhs, *lhsp));
3264 : 162 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
3265 : 162 : lhs = get_function_part_constraint (fi, fi_uses);
3266 : 486 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
3267 : 162 : process_constraint (new_constraint (lhs, *rhsp));
3268 : : return;
3269 : : }
3270 : : /* The following function clobbers memory pointed to by
3271 : : its argument. */
3272 : 890 : case BUILT_IN_MEMSET:
3273 : 890 : case BUILT_IN_MEMSET_CHK:
3274 : 890 : case BUILT_IN_POSIX_MEMALIGN:
3275 : 890 : {
3276 : 890 : tree dest = gimple_call_arg (t, 0);
3277 : 890 : unsigned i;
3278 : 890 : ce_s *lhsp;
3279 : 890 : get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc);
3280 : 890 : lhs = get_function_part_constraint (fi, fi_clobbers);
3281 : 2670 : FOR_EACH_VEC_ELT (lhsc, i, lhsp)
3282 : 890 : process_constraint (new_constraint (lhs, *lhsp));
3283 : : return;
3284 : : }
3285 : : /* The following functions clobber their second and third
3286 : : arguments. */
3287 : 0 : case BUILT_IN_SINCOS:
3288 : 0 : case BUILT_IN_SINCOSF:
3289 : 0 : case BUILT_IN_SINCOSL:
3290 : 0 : {
3291 : 0 : process_ipa_clobber (fi, gimple_call_arg (t, 1));
3292 : 0 : process_ipa_clobber (fi, gimple_call_arg (t, 2));
3293 : 0 : return;
3294 : : }
3295 : : /* The following functions clobber their second argument. */
3296 : 0 : case BUILT_IN_FREXP:
3297 : 0 : case BUILT_IN_FREXPF:
3298 : 0 : case BUILT_IN_FREXPL:
3299 : 0 : case BUILT_IN_LGAMMA_R:
3300 : 0 : case BUILT_IN_LGAMMAF_R:
3301 : 0 : case BUILT_IN_LGAMMAL_R:
3302 : 0 : case BUILT_IN_GAMMA_R:
3303 : 0 : case BUILT_IN_GAMMAF_R:
3304 : 0 : case BUILT_IN_GAMMAL_R:
3305 : 0 : case BUILT_IN_MODF:
3306 : 0 : case BUILT_IN_MODFF:
3307 : 0 : case BUILT_IN_MODFL:
3308 : 0 : {
3309 : 0 : process_ipa_clobber (fi, gimple_call_arg (t, 1));
3310 : 0 : return;
3311 : : }
3312 : : /* The following functions clobber their third argument. */
3313 : 0 : case BUILT_IN_REMQUO:
3314 : 0 : case BUILT_IN_REMQUOF:
3315 : 0 : case BUILT_IN_REMQUOL:
3316 : 0 : {
3317 : 0 : process_ipa_clobber (fi, gimple_call_arg (t, 2));
3318 : 0 : return;
3319 : : }
3320 : : /* The following functions use what their first argument
3321 : : points to. */
3322 : 60 : case BUILT_IN_STRDUP:
3323 : 60 : case BUILT_IN_STRNDUP:
3324 : 60 : case BUILT_IN_REALLOC:
3325 : 60 : case BUILT_IN_INDEX:
3326 : 60 : case BUILT_IN_STRCHR:
3327 : 60 : case BUILT_IN_STRRCHR:
3328 : 60 : case BUILT_IN_MEMCHR:
3329 : 60 : {
3330 : 60 : tree src = gimple_call_arg (t, 0);
3331 : 60 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
3332 : 60 : lhs = get_function_part_constraint (fi, fi_uses);
3333 : 60 : struct constraint_expr *rhsp;
3334 : 180 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
3335 : 60 : process_constraint (new_constraint (lhs, *rhsp));
3336 : : return;
3337 : : }
3338 : : /* The following functions use what their first and second argument
3339 : : point to. */
3340 : 16 : case BUILT_IN_STRSTR:
3341 : 16 : case BUILT_IN_STRPBRK:
3342 : 16 : {
3343 : 16 : tree src = gimple_call_arg (t, 0);
3344 : 16 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
3345 : 16 : lhs = get_function_part_constraint (fi, fi_uses);
3346 : 16 : struct constraint_expr *rhsp;
3347 : 48 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
3348 : 16 : process_constraint (new_constraint (lhs, *rhsp));
3349 : 16 : rhsc.truncate (0);
3350 : 16 : src = gimple_call_arg (t, 1);
3351 : 16 : get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc);
3352 : 243272 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
3353 : 16 : process_constraint (new_constraint (lhs, *rhsp));
3354 : : return;
3355 : : }
3356 : : /* The following functions neither read nor clobber memory. */
3357 : : case BUILT_IN_ASSUME_ALIGNED:
3358 : : case BUILT_IN_FREE:
3359 : : return;
3360 : : /* Trampolines are of no interest to us. */
3361 : : case BUILT_IN_INIT_TRAMPOLINE:
3362 : : case BUILT_IN_ADJUST_TRAMPOLINE:
3363 : : return;
3364 : : case BUILT_IN_VA_START:
3365 : : case BUILT_IN_VA_END:
3366 : : return;
3367 : 13798 : case BUILT_IN_GOMP_PARALLEL:
3368 : 13798 : case BUILT_IN_GOACC_PARALLEL:
3369 : 13798 : {
3370 : 13798 : unsigned int fnpos, argpos;
3371 : 13798 : unsigned int implicit_use_args[2];
3372 : 13798 : unsigned int num_implicit_use_args = 0;
3373 : 13798 : switch (DECL_FUNCTION_CODE (decl))
3374 : : {
3375 : : case BUILT_IN_GOMP_PARALLEL:
3376 : : /* __builtin_GOMP_parallel (fn, data, num_threads, flags). */
3377 : : fnpos = 0;
3378 : : argpos = 1;
3379 : : break;
3380 : 13785 : case BUILT_IN_GOACC_PARALLEL:
3381 : : /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs,
3382 : : sizes, kinds, ...). */
3383 : 13785 : fnpos = 1;
3384 : 13785 : argpos = 3;
3385 : 13785 : implicit_use_args[num_implicit_use_args++] = 4;
3386 : 13785 : implicit_use_args[num_implicit_use_args++] = 5;
3387 : 13785 : break;
3388 : 0 : default:
3389 : 0 : gcc_unreachable ();
3390 : : }
3391 : :
3392 : 13798 : tree fnarg = gimple_call_arg (t, fnpos);
3393 : 13798 : gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR);
3394 : 13798 : tree fndecl = TREE_OPERAND (fnarg, 0);
3395 : 13798 : if (fndecl_maybe_in_other_partition (fndecl))
3396 : : /* Fallthru to general call handling. */
3397 : : break;
3398 : :
3399 : 13755 : varinfo_t cfi = get_vi_for_tree (fndecl);
3400 : :
3401 : 13755 : tree arg = gimple_call_arg (t, argpos);
3402 : :
3403 : : /* Parameter passed by value is used. */
3404 : 13755 : lhs = get_function_part_constraint (fi, fi_uses);
3405 : 13755 : struct constraint_expr *rhsp;
3406 : 13755 : get_constraint_for (arg, &rhsc);
3407 : 41265 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
3408 : 13755 : process_constraint (new_constraint (lhs, *rhsp));
3409 : 13755 : rhsc.truncate (0);
3410 : :
3411 : : /* Handle parameters used by the call, but not used in cfi, as
3412 : : implicitly used by cfi. */
3413 : 13755 : lhs = get_function_part_constraint (cfi, fi_uses);
3414 : 41245 : for (unsigned i = 0; i < num_implicit_use_args; ++i)
3415 : : {
3416 : 27490 : tree arg = gimple_call_arg (t, implicit_use_args[i]);
3417 : 27490 : get_constraint_for (arg, &rhsc);
3418 : 82470 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
3419 : 27490 : process_constraint (new_constraint (lhs, *rhsp));
3420 : 27490 : rhsc.truncate (0);
3421 : : }
3422 : :
3423 : : /* The caller clobbers what the callee does. */
3424 : 13755 : lhs = get_function_part_constraint (fi, fi_clobbers);
3425 : 13755 : rhs = get_function_part_constraint (cfi, fi_clobbers);
3426 : 13755 : process_constraint (new_constraint (lhs, rhs));
3427 : :
3428 : : /* The caller uses what the callee does. */
3429 : 13755 : lhs = get_function_part_constraint (fi, fi_uses);
3430 : 13755 : rhs = get_function_part_constraint (cfi, fi_uses);
3431 : 13755 : process_constraint (new_constraint (lhs, rhs));
3432 : :
3433 : 13755 : return;
3434 : : }
3435 : : /* printf-style functions may have hooks to set pointers to
3436 : : point to somewhere into the generated string. Leave them
3437 : : for a later exercise... */
3438 : : default:
3439 : : /* Fallthru to general call handling. */;
3440 : : }
3441 : :
3442 : : /* Parameters passed by value are used. */
3443 : 233140 : lhs = get_function_part_constraint (fi, fi_uses);
3444 : 1144884 : for (i = 0; i < gimple_call_num_args (t); i++)
3445 : : {
3446 : 911744 : struct constraint_expr *rhsp;
3447 : 911744 : tree arg = gimple_call_arg (t, i);
3448 : :
3449 : 1803451 : if (TREE_CODE (arg) == SSA_NAME
3450 : 911744 : || is_gimple_min_invariant (arg))
3451 : 891707 : continue;
3452 : :
3453 : 20037 : get_constraint_for_address_of (arg, &rhsc);
3454 : 60112 : FOR_EACH_VEC_ELT (rhsc, j, rhsp)
3455 : 20038 : process_constraint (new_constraint (lhs, *rhsp));
3456 : 20037 : rhsc.truncate (0);
3457 : : }
3458 : :
3459 : : /* Build constraints for propagating clobbers/uses along the
3460 : : callgraph edges. */
3461 : 233140 : cfi = get_fi_for_callee (call_stmt);
3462 : 233140 : if (cfi->id == anything_id)
3463 : : {
3464 : 347102 : if (gimple_vdef (t))
3465 : 121675 : make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
3466 : : anything_id);
3467 : 173551 : make_constraint_from (first_vi_for_offset (fi, fi_uses),
3468 : : anything_id);
3469 : 173551 : return;
3470 : : }
3471 : :
3472 : : /* For callees without function info (that's external functions),
3473 : : ESCAPED is clobbered and used. */
3474 : 59589 : if (cfi->decl
3475 : 59588 : && TREE_CODE (cfi->decl) == FUNCTION_DECL
3476 : 58910 : && !cfi->is_fn_info)
3477 : : {
3478 : 52860 : varinfo_t vi;
3479 : :
3480 : 105720 : if (gimple_vdef (t))
3481 : 52625 : make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
3482 : : escaped_id);
3483 : 52860 : make_copy_constraint (first_vi_for_offset (fi, fi_uses), escaped_id);
3484 : :
3485 : : /* Also honor the call statement use/clobber info. */
3486 : 52860 : if ((vi = lookup_call_clobber_vi (call_stmt)) != NULL)
3487 : 52584 : make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
3488 : 52584 : vi->id);
3489 : 52860 : if ((vi = lookup_call_use_vi (call_stmt)) != NULL)
3490 : 52584 : make_copy_constraint (first_vi_for_offset (fi, fi_uses),
3491 : 52584 : vi->id);
3492 : 52860 : return;
3493 : : }
3494 : :
3495 : : /* Otherwise the caller clobbers and uses what the callee does.
3496 : : ??? This should use a new complex constraint that filters
3497 : : local variables of the callee. */
3498 : 13458 : if (gimple_vdef (t))
3499 : : {
3500 : 5715 : lhs = get_function_part_constraint (fi, fi_clobbers);
3501 : 5715 : rhs = get_function_part_constraint (cfi, fi_clobbers);
3502 : 5715 : process_constraint (new_constraint (lhs, rhs));
3503 : : }
3504 : 6729 : lhs = get_function_part_constraint (fi, fi_uses);
3505 : 6729 : rhs = get_function_part_constraint (cfi, fi_uses);
3506 : 6729 : process_constraint (new_constraint (lhs, rhs));
3507 : : }
3508 : 376128 : else if (gimple_code (t) == GIMPLE_ASM)
3509 : : {
3510 : : /* ??? Ick. We can do better. */
3511 : 42 : if (gimple_vdef (t))
3512 : 42 : make_constraint_from (first_vi_for_offset (fi, fi_clobbers),
3513 : : anything_id);
3514 : 42 : make_constraint_from (first_vi_for_offset (fi, fi_uses),
3515 : : anything_id);
3516 : : }
3517 : 956204 : }
3518 : :
3519 : :
3520 : : /* This structure is used during pushing fields onto the fieldstack
3521 : : to track the offset of the field, since bitpos_of_field gives it
3522 : : relative to its immediate containing type, and we want it relative
3523 : : to the ultimate containing object. */
3524 : :
3525 : : struct fieldoff
3526 : : {
3527 : : /* Offset from the base of the base containing object to this field. */
3528 : : HOST_WIDE_INT offset;
3529 : :
3530 : : /* Size, in bits, of the field. */
3531 : : unsigned HOST_WIDE_INT size;
3532 : :
3533 : : unsigned has_unknown_size : 1;
3534 : :
3535 : : unsigned must_have_pointers : 1;
3536 : :
3537 : : unsigned may_have_pointers : 1;
3538 : :
3539 : : unsigned only_restrict_pointers : 1;
3540 : :
3541 : : tree restrict_pointed_type;
3542 : : };
3543 : : typedef struct fieldoff fieldoff_s;
3544 : :
3545 : :
3546 : : /* qsort comparison function for two fieldoff's PA and PB. */
3547 : :
3548 : : static int
3549 : 190185978 : fieldoff_compare (const void *pa, const void *pb)
3550 : : {
3551 : 190185978 : const fieldoff_s *foa = (const fieldoff_s *)pa;
3552 : 190185978 : const fieldoff_s *fob = (const fieldoff_s *)pb;
3553 : 190185978 : unsigned HOST_WIDE_INT foasize, fobsize;
3554 : :
3555 : 190185978 : if (foa->offset < fob->offset)
3556 : : return -1;
3557 : 99178502 : else if (foa->offset > fob->offset)
3558 : : return 1;
3559 : :
3560 : 1358284 : foasize = foa->size;
3561 : 1358284 : fobsize = fob->size;
3562 : 1358284 : if (foasize < fobsize)
3563 : : return -1;
3564 : 1129345 : else if (foasize > fobsize)
3565 : 130773 : return 1;
3566 : : return 0;
3567 : : }
3568 : :
3569 : : /* Sort a fieldstack according to the field offset and sizes. */
3570 : : static void
3571 : 7670097 : sort_fieldstack (vec<fieldoff_s> &fieldstack)
3572 : : {
3573 : 7670097 : fieldstack.qsort (fieldoff_compare);
3574 : 7670097 : }
3575 : :
3576 : : /* Return true if T is a type that can have subvars. */
3577 : :
3578 : : static inline bool
3579 : 66400690 : type_can_have_subvars (const_tree t)
3580 : : {
3581 : : /* Aggregates without overlapping fields can have subvars. */
3582 : 5827146 : return TREE_CODE (t) == RECORD_TYPE;
3583 : : }
3584 : :
3585 : : /* Return true if V is a tree that we can have subvars for.
3586 : : Normally, this is any aggregate type. Also complex
3587 : : types which are not gimple registers can have subvars. */
3588 : :
3589 : : static inline bool
3590 : 121005896 : var_can_have_subvars (const_tree v)
3591 : : {
3592 : : /* Volatile variables should never have subvars. */
3593 : 121005896 : if (TREE_THIS_VOLATILE (v))
3594 : : return false;
3595 : :
3596 : : /* Non decls or memory tags can never have subvars. */
3597 : 120715297 : if (!DECL_P (v))
3598 : : return false;
3599 : :
3600 : 60573544 : return type_can_have_subvars (TREE_TYPE (v));
3601 : : }
3602 : :
3603 : : /* Return true if T is a type that does contain pointers. */
3604 : :
3605 : : static bool
3606 : 34068009 : type_must_have_pointers (tree type)
3607 : : {
3608 : 34808792 : if (POINTER_TYPE_P (type))
3609 : : return true;
3610 : :
3611 : 19529886 : if (TREE_CODE (type) == ARRAY_TYPE)
3612 : 740783 : return type_must_have_pointers (TREE_TYPE (type));
3613 : :
3614 : : /* A function or method can have pointers as arguments, so track
3615 : : those separately. */
3616 : 18789103 : if (FUNC_OR_METHOD_TYPE_P (type))
3617 : 0 : return true;
3618 : :
3619 : : return false;
3620 : : }
3621 : :
3622 : : static bool
3623 : 34068009 : field_must_have_pointers (tree t)
3624 : : {
3625 : 34068009 : return type_must_have_pointers (TREE_TYPE (t));
3626 : : }
3627 : :
3628 : : /* Given a TYPE, and a vector of field offsets FIELDSTACK, push all
3629 : : the fields of TYPE onto fieldstack, recording their offsets along
3630 : : the way.
3631 : :
3632 : : OFFSET is used to keep track of the offset in this entire
3633 : : structure, rather than just the immediately containing structure.
3634 : : Returns false if the caller is supposed to handle the field we
3635 : : recursed for. */
3636 : :
3637 : : static bool
3638 : 14311543 : push_fields_onto_fieldstack (tree type, vec<fieldoff_s> *fieldstack,
3639 : : unsigned HOST_WIDE_INT offset)
3640 : : {
3641 : 14311543 : tree field;
3642 : 14311543 : bool empty_p = true;
3643 : :
3644 : 14311543 : if (TREE_CODE (type) != RECORD_TYPE)
3645 : : return false;
3646 : :
3647 : : /* If the vector of fields is growing too big, bail out early.
3648 : : Callers check for vec::length <= param_max_fields_for_field_sensitive, make
3649 : : sure this fails. */
3650 : 14311543 : if (fieldstack->length () > (unsigned)param_max_fields_for_field_sensitive)
3651 : : return false;
3652 : :
3653 : 331500751 : for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
3654 : 317377161 : if (TREE_CODE (field) == FIELD_DECL)
3655 : : {
3656 : 40469316 : bool push = false;
3657 : 40469316 : unsigned HOST_WIDE_INT foff = bitpos_of_field (field);
3658 : 40469316 : tree field_type = TREE_TYPE (field);
3659 : :
3660 : 40469316 : if (!var_can_have_subvars (field)
3661 : 6610559 : || TREE_CODE (field_type) == QUAL_UNION_TYPE
3662 : 47079875 : || TREE_CODE (field_type) == UNION_TYPE)
3663 : : push = true;
3664 : 6610559 : else if (!push_fields_onto_fieldstack
3665 : 6610559 : (field_type, fieldstack, offset + foff)
3666 : 6610559 : && (DECL_SIZE (field)
3667 : 1137687 : && !integer_zerop (DECL_SIZE (field))))
3668 : : /* Empty structures may have actual size, like in C++. So
3669 : : see if we didn't push any subfields and the size is
3670 : : nonzero, push the field onto the stack. */
3671 : : push = true;
3672 : :
3673 : : if (push)
3674 : : {
3675 : 34068009 : fieldoff_s *pair = NULL;
3676 : 34068009 : bool has_unknown_size = false;
3677 : 34068009 : bool must_have_pointers_p;
3678 : :
3679 : 34068009 : if (!fieldstack->is_empty ())
3680 : 26638716 : pair = &fieldstack->last ();
3681 : :
3682 : : /* If there isn't anything at offset zero, create sth. */
3683 : 26638716 : if (!pair
3684 : 7429293 : && offset + foff != 0)
3685 : : {
3686 : 8982 : fieldoff_s e
3687 : 8982 : = {0, offset + foff, false, false, true, false, NULL_TREE};
3688 : 8982 : pair = fieldstack->safe_push (e);
3689 : : }
3690 : :
3691 : 34068009 : if (!DECL_SIZE (field)
3692 : 34068009 : || !tree_fits_uhwi_p (DECL_SIZE (field)))
3693 : : has_unknown_size = true;
3694 : :
3695 : : /* If adjacent fields do not contain pointers merge them. */
3696 : 34068009 : must_have_pointers_p = field_must_have_pointers (field);
3697 : 34068009 : if (pair
3698 : 34068009 : && !has_unknown_size
3699 : 26616838 : && !must_have_pointers_p
3700 : 16583945 : && !pair->must_have_pointers
3701 : 11833976 : && !pair->has_unknown_size
3702 : 11833973 : && pair->offset + pair->size == offset + foff)
3703 : : {
3704 : 11241958 : pair->size += tree_to_uhwi (DECL_SIZE (field));
3705 : : }
3706 : : else
3707 : : {
3708 : 22826051 : fieldoff_s e;
3709 : 22826051 : e.offset = offset + foff;
3710 : 22826051 : e.has_unknown_size = has_unknown_size;
3711 : 22826051 : if (!has_unknown_size)
3712 : 22795164 : e.size = tree_to_uhwi (DECL_SIZE (field));
3713 : : else
3714 : 30887 : e.size = -1;
3715 : 22826051 : e.must_have_pointers = must_have_pointers_p;
3716 : 22826051 : e.may_have_pointers = true;
3717 : 22826051 : e.only_restrict_pointers
3718 : 22826051 : = (!has_unknown_size
3719 : 22795164 : && POINTER_TYPE_P (field_type)
3720 : 38096552 : && TYPE_RESTRICT (field_type));
3721 : 22826051 : if (e.only_restrict_pointers)
3722 : 105594 : e.restrict_pointed_type = TREE_TYPE (field_type);
3723 : 22826051 : fieldstack->safe_push (e);
3724 : : }
3725 : : }
3726 : :
3727 : : empty_p = false;
3728 : : }
3729 : :
3730 : 14123590 : return !empty_p;
3731 : : }
3732 : :
3733 : : /* Count the number of arguments DECL has, and set IS_VARARGS to true
3734 : : if it is a varargs function. */
3735 : :
3736 : : static unsigned int
3737 : 23449 : count_num_arguments (tree decl, bool *is_varargs)
3738 : : {
3739 : 23449 : unsigned int num = 0;
3740 : 23449 : tree t;
3741 : :
3742 : : /* Capture named arguments for K&R functions. They do not
3743 : : have a prototype and thus no TYPE_ARG_TYPES. */
3744 : 48625 : for (t = DECL_ARGUMENTS (decl); t; t = DECL_CHAIN (t))
3745 : 25176 : ++num;
3746 : :
3747 : : /* Check if the function has variadic arguments. */
3748 : 48625 : for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
3749 : 48618 : if (TREE_VALUE (t) == void_type_node)
3750 : : break;
3751 : 23449 : if (!t)
3752 : 7 : *is_varargs = true;
3753 : :
3754 : 23449 : return num;
3755 : : }
3756 : :
3757 : : /* Creation function node for DECL, using NAME, and return the index
3758 : : of the variable we've created for the function. If NONLOCAL_p, create
3759 : : initial constraints. */
3760 : :
3761 : : static varinfo_t
3762 : 23449 : create_function_info_for (tree decl, const char *name, bool add_id,
3763 : : bool nonlocal_p)
3764 : : {
3765 : 23449 : struct function *fn = DECL_STRUCT_FUNCTION (decl);
3766 : 23449 : varinfo_t vi, prev_vi;
3767 : 23449 : tree arg;
3768 : 23449 : unsigned int i;
3769 : 23449 : bool is_varargs = false;
3770 : 23449 : unsigned int num_args = count_num_arguments (decl, &is_varargs);
3771 : :
3772 : : /* Create the variable info. */
3773 : :
3774 : 23449 : vi = new_var_info (decl, name, add_id);
3775 : 23449 : vi->offset = 0;
3776 : 23449 : vi->size = 1;
3777 : 23449 : vi->fullsize = fi_parm_base + num_args;
3778 : 23449 : vi->is_fn_info = 1;
3779 : 23449 : vi->may_have_pointers = false;
3780 : 23449 : if (is_varargs)
3781 : 7 : vi->fullsize = ~0;
3782 : 23449 : insert_vi_for_tree (vi->decl, vi);
3783 : :
3784 : 23449 : prev_vi = vi;
3785 : :
3786 : : /* Create a variable for things the function clobbers and one for
3787 : : things the function uses. */
3788 : 23449 : {
3789 : 23449 : varinfo_t clobbervi, usevi;
3790 : 23449 : const char *newname;
3791 : 23449 : char *tempname;
3792 : :
3793 : 23449 : tempname = xasprintf ("%s.clobber", name);
3794 : 23449 : newname = ggc_strdup (tempname);
3795 : 23449 : free (tempname);
3796 : :
3797 : 23449 : clobbervi = new_var_info (NULL, newname, false);
3798 : 23449 : clobbervi->offset = fi_clobbers;
3799 : 23449 : clobbervi->size = 1;
3800 : 23449 : clobbervi->fullsize = vi->fullsize;
3801 : 23449 : clobbervi->is_full_var = true;
3802 : 23449 : clobbervi->is_global_var = false;
3803 : 23449 : clobbervi->is_reg_var = true;
3804 : :
3805 : 23449 : gcc_assert (prev_vi->offset < clobbervi->offset);
3806 : 23449 : prev_vi->next = clobbervi->id;
3807 : 23449 : prev_vi = clobbervi;
3808 : :
3809 : 23449 : tempname = xasprintf ("%s.use", name);
3810 : 23449 : newname = ggc_strdup (tempname);
3811 : 23449 : free (tempname);
3812 : :
3813 : 23449 : usevi = new_var_info (NULL, newname, false);
3814 : 23449 : usevi->offset = fi_uses;
3815 : 23449 : usevi->size = 1;
3816 : 23449 : usevi->fullsize = vi->fullsize;
3817 : 23449 : usevi->is_full_var = true;
3818 : 23449 : usevi->is_global_var = false;
3819 : 23449 : usevi->is_reg_var = true;
3820 : :
3821 : 23449 : gcc_assert (prev_vi->offset < usevi->offset);
3822 : 23449 : prev_vi->next = usevi->id;
3823 : 23449 : prev_vi = usevi;
3824 : : }
3825 : :
3826 : : /* And one for the static chain. */
3827 : 23449 : if (fn->static_chain_decl != NULL_TREE)
3828 : : {
3829 : 139 : varinfo_t chainvi;
3830 : 139 : const char *newname;
3831 : 139 : char *tempname;
3832 : :
3833 : 139 : tempname = xasprintf ("%s.chain", name);
3834 : 139 : newname = ggc_strdup (tempname);
3835 : 139 : free (tempname);
3836 : :
3837 : 139 : chainvi = new_var_info (fn->static_chain_decl, newname, false);
3838 : 139 : chainvi->offset = fi_static_chain;
3839 : 139 : chainvi->size = 1;
3840 : 139 : chainvi->fullsize = vi->fullsize;
3841 : 139 : chainvi->is_full_var = true;
3842 : 139 : chainvi->is_global_var = false;
3843 : :
3844 : 139 : insert_vi_for_tree (fn->static_chain_decl, chainvi);
3845 : :
3846 : 139 : if (nonlocal_p
3847 : 0 : && chainvi->may_have_pointers)
3848 : 0 : make_constraint_from (chainvi, nonlocal_id);
3849 : :
3850 : 139 : gcc_assert (prev_vi->offset < chainvi->offset);
3851 : 139 : prev_vi->next = chainvi->id;
3852 : 139 : prev_vi = chainvi;
3853 : : }
3854 : :
3855 : : /* Create a variable for the return var. */
3856 : 23449 : if (DECL_RESULT (decl) != NULL
3857 : 23449 : || !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
3858 : : {
3859 : 23449 : varinfo_t resultvi;
3860 : 23449 : const char *newname;
3861 : 23449 : char *tempname;
3862 : 23449 : tree resultdecl = decl;
3863 : :
3864 : 23449 : if (DECL_RESULT (decl))
3865 : 23449 : resultdecl = DECL_RESULT (decl);
3866 : :
3867 : 23449 : tempname = xasprintf ("%s.result", name);
3868 : 23449 : newname = ggc_strdup (tempname);
3869 : 23449 : free (tempname);
3870 : :
3871 : 23449 : resultvi = new_var_info (resultdecl, newname, false);
3872 : 23449 : resultvi->offset = fi_result;
3873 : 23449 : resultvi->size = 1;
3874 : 23449 : resultvi->fullsize = vi->fullsize;
3875 : 23449 : resultvi->is_full_var = true;
3876 : 23449 : if (DECL_RESULT (decl))
3877 : 23449 : resultvi->may_have_pointers = true;
3878 : :
3879 : 23449 : if (DECL_RESULT (decl))
3880 : 23449 : insert_vi_for_tree (DECL_RESULT (decl), resultvi);
3881 : :
3882 : 23449 : if (nonlocal_p
3883 : 6991 : && DECL_RESULT (decl)
3884 : 30440 : && DECL_BY_REFERENCE (DECL_RESULT (decl)))
3885 : 6 : make_constraint_from (resultvi, nonlocal_id);
3886 : :
3887 : 23449 : gcc_assert (prev_vi->offset < resultvi->offset);
3888 : 23449 : prev_vi->next = resultvi->id;
3889 : 23449 : prev_vi = resultvi;
3890 : : }
3891 : :
3892 : : /* We also need to make function return values escape. Nothing
3893 : : escapes by returning from main though. */
3894 : 23449 : if (nonlocal_p
3895 : 23449 : && !MAIN_NAME_P (DECL_NAME (decl)))
3896 : : {
3897 : 3480 : varinfo_t fi, rvi;
3898 : 3480 : fi = lookup_vi_for_tree (decl);
3899 : 3480 : rvi = first_vi_for_offset (fi, fi_result);
3900 : 3480 : if (rvi && rvi->offset == fi_result)
3901 : 3480 : make_copy_constraint (get_varinfo (escaped_id), rvi->id);
3902 : : }
3903 : :
3904 : : /* Set up variables for each argument. */
3905 : 23449 : arg = DECL_ARGUMENTS (decl);
3906 : 48625 : for (i = 0; i < num_args; i++)
3907 : : {
3908 : 25176 : varinfo_t argvi;
3909 : 25176 : const char *newname;
3910 : 25176 : char *tempname;
3911 : 25176 : tree argdecl = decl;
3912 : :
3913 : 25176 : if (arg)
3914 : 25176 : argdecl = arg;
3915 : :
3916 : 25176 : tempname = xasprintf ("%s.arg%d", name, i);
3917 : 25176 : newname = ggc_strdup (tempname);
3918 : 25176 : free (tempname);
3919 : :
3920 : 25176 : argvi = new_var_info (argdecl, newname, false);
3921 : 25176 : argvi->offset = fi_parm_base + i;
3922 : 25176 : argvi->size = 1;
3923 : 25176 : argvi->is_full_var = true;
3924 : 25176 : argvi->fullsize = vi->fullsize;
3925 : 25176 : if (arg)
3926 : 25176 : argvi->may_have_pointers = true;
3927 : :
3928 : 25176 : if (arg)
3929 : 25176 : insert_vi_for_tree (arg, argvi);
3930 : :
3931 : 25176 : if (nonlocal_p
3932 : 9138 : && argvi->may_have_pointers)
3933 : 9138 : make_constraint_from (argvi, nonlocal_id);
3934 : :
3935 : 25176 : gcc_assert (prev_vi->offset < argvi->offset);
3936 : 25176 : prev_vi->next = argvi->id;
3937 : 25176 : prev_vi = argvi;
3938 : 25176 : if (arg)
3939 : 25176 : arg = DECL_CHAIN (arg);
3940 : : }
3941 : :
3942 : : /* Add one representative for all further args. */
3943 : 23449 : if (is_varargs)
3944 : : {
3945 : 7 : varinfo_t argvi;
3946 : 7 : const char *newname;
3947 : 7 : char *tempname;
3948 : 7 : tree decl;
3949 : :
3950 : 7 : tempname = xasprintf ("%s.varargs", name);
3951 : 7 : newname = ggc_strdup (tempname);
3952 : 7 : free (tempname);
3953 : :
3954 : : /* We need sth that can be pointed to for va_start. */
3955 : 7 : decl = build_fake_var_decl (ptr_type_node);
3956 : :
3957 : 7 : argvi = new_var_info (decl, newname, false);
3958 : 7 : argvi->offset = fi_parm_base + num_args;
3959 : 7 : argvi->size = ~0;
3960 : 7 : argvi->is_full_var = true;
3961 : 7 : argvi->is_heap_var = true;
3962 : 7 : argvi->fullsize = vi->fullsize;
3963 : :
3964 : 7 : if (nonlocal_p
3965 : 6 : && argvi->may_have_pointers)
3966 : 6 : make_constraint_from (argvi, nonlocal_id);
3967 : :
3968 : 7 : gcc_assert (prev_vi->offset < argvi->offset);
3969 : 7 : prev_vi->next = argvi->id;
3970 : : }
3971 : :
3972 : 23449 : return vi;
3973 : : }
3974 : :
3975 : :
3976 : : /* Return true if FIELDSTACK contains fields that overlap.
3977 : : FIELDSTACK is assumed to be sorted by offset. */
3978 : :
3979 : : static bool
3980 : 7670097 : check_for_overlaps (const vec<fieldoff_s> &fieldstack)
3981 : : {
3982 : 7670097 : fieldoff_s *fo = NULL;
3983 : 7670097 : unsigned int i;
3984 : 7670097 : HOST_WIDE_INT lastoffset = -1;
3985 : :
3986 : 29669468 : FOR_EACH_VEC_ELT (fieldstack, i, fo)
3987 : : {
3988 : 22018554 : if (fo->offset == lastoffset)
3989 : : return true;
3990 : 21999371 : lastoffset = fo->offset;
3991 : : }
3992 : : return false;
3993 : : }
3994 : :
3995 : : /* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
3996 : : This will also create any varinfo structures necessary for fields
3997 : : of DECL. DECL is a function parameter if HANDLE_PARAM is set.
3998 : : HANDLED_STRUCT_TYPE is used to register struct types reached by following
3999 : : restrict pointers. This is needed to prevent infinite recursion.
4000 : : If ADD_RESTRICT, pretend that the pointer NAME is restrict even if DECL
4001 : : does not advertise it. */
4002 : :
4003 : : static varinfo_t
4004 : 91466769 : create_variable_info_for_1 (tree decl, const char *name, bool add_id,
4005 : : bool handle_param, bitmap handled_struct_type,
4006 : : bool add_restrict = false)
4007 : : {
4008 : 91466769 : varinfo_t vi, newvi;
4009 : 91466769 : tree decl_type = TREE_TYPE (decl);
4010 : 91466769 : tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type);
4011 : 91466769 : auto_vec<fieldoff_s> fieldstack;
4012 : 91466769 : fieldoff_s *fo;
4013 : 91466769 : unsigned int i;
4014 : :
4015 : 91466769 : if (!declsize
4016 : 83171958 : || !tree_fits_uhwi_p (declsize))
4017 : : {
4018 : 8308304 : vi = new_var_info (decl, name, add_id);
4019 : 8308304 : vi->offset = 0;
4020 : 8308304 : vi->size = ~0;
4021 : 8308304 : vi->fullsize = ~0;
4022 : 8308304 : vi->is_unknown_size_var = true;
4023 : 8308304 : vi->is_full_var = true;
4024 : 8308304 : vi->may_have_pointers = true;
4025 : 8308304 : return vi;
4026 : : }
4027 : :
4028 : : /* Collect field information. */
4029 : 83158465 : if (use_field_sensitive
4030 : 79335946 : && var_can_have_subvars (decl)
4031 : : /* ??? Force us to not use subfields for globals in IPA mode.
4032 : : Else we'd have to parse arbitrary initializers. */
4033 : 90879573 : && !(in_ipa_mode
4034 : 19661 : && is_global_var (decl)))
4035 : : {
4036 : 7700984 : fieldoff_s *fo = NULL;
4037 : 7700984 : bool notokay = false;
4038 : 7700984 : unsigned int i;
4039 : :
4040 : 7700984 : push_fields_onto_fieldstack (decl_type, &fieldstack, 0);
4041 : :
4042 : 38206111 : for (i = 0; !notokay && fieldstack.iterate (i, &fo); i++)
4043 : 22835030 : if (fo->has_unknown_size
4044 : 22804143 : || fo->offset < 0)
4045 : : {
4046 : : notokay = true;
4047 : : break;
4048 : : }
4049 : :
4050 : : /* We can't sort them if we have a field with a variable sized type,
4051 : : which will make notokay = true. In that case, we are going to return
4052 : : without creating varinfos for the fields anyway, so sorting them is a
4053 : : waste to boot. */
4054 : 7700984 : if (!notokay)
4055 : : {
4056 : 7670097 : sort_fieldstack (fieldstack);
4057 : : /* Due to some C++ FE issues, like PR 22488, we might end up
4058 : : what appear to be overlapping fields even though they,
4059 : : in reality, do not overlap. Until the C++ FE is fixed,
4060 : : we will simply disable field-sensitivity for these cases. */
4061 : 7670097 : notokay = check_for_overlaps (fieldstack);
4062 : : }
4063 : :
4064 : 7670097 : if (notokay)
4065 : 50070 : fieldstack.release ();
4066 : : }
4067 : :
4068 : : /* If we didn't end up collecting sub-variables create a full
4069 : : variable for the decl. */
4070 : 83158465 : if (fieldstack.length () == 0
4071 : 7379223 : || fieldstack.length () > (unsigned)param_max_fields_for_field_sensitive)
4072 : : {
4073 : 75779660 : vi = new_var_info (decl, name, add_id);
4074 : 75779660 : vi->offset = 0;
4075 : 75779660 : vi->may_have_pointers = true;
4076 : 75779660 : vi->fullsize = tree_to_uhwi (declsize);
4077 : 75779660 : vi->size = vi->fullsize;
4078 : 75779660 : vi->is_full_var = true;
4079 : 75779660 : if (POINTER_TYPE_P (decl_type)
4080 : 75779660 : && (TYPE_RESTRICT (decl_type) || add_restrict))
4081 : 851805 : vi->only_restrict_pointers = 1;
4082 : 75779660 : if (vi->only_restrict_pointers
4083 : 851805 : && !type_contains_placeholder_p (TREE_TYPE (decl_type))
4084 : 851805 : && handle_param
4085 : 76355088 : && !bitmap_bit_p (handled_struct_type,
4086 : 575428 : TYPE_UID (TREE_TYPE (decl_type))))
4087 : : {
4088 : 575428 : varinfo_t rvi;
4089 : 575428 : tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type));
4090 : 575428 : DECL_EXTERNAL (heapvar) = 1;
4091 : 575428 : if (var_can_have_subvars (heapvar))
4092 : 903660 : bitmap_set_bit (handled_struct_type,
4093 : 451830 : TYPE_UID (TREE_TYPE (decl_type)));
4094 : 575428 : rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
4095 : : true, handled_struct_type);
4096 : 575428 : if (var_can_have_subvars (heapvar))
4097 : 903660 : bitmap_clear_bit (handled_struct_type,
4098 : 451830 : TYPE_UID (TREE_TYPE (decl_type)));
4099 : 575428 : rvi->is_restrict_var = 1;
4100 : 575428 : insert_vi_for_tree (heapvar, rvi);
4101 : 575428 : make_constraint_from (vi, rvi->id);
4102 : 575428 : make_param_constraints (rvi);
4103 : : }
4104 : 75779660 : fieldstack.release ();
4105 : 75779660 : return vi;
4106 : : }
4107 : :
4108 : 7378805 : vi = new_var_info (decl, name, add_id);
4109 : 7378805 : vi->fullsize = tree_to_uhwi (declsize);
4110 : 7378805 : if (fieldstack.length () == 1)
4111 : 1587447 : vi->is_full_var = true;
4112 : : for (i = 0, newvi = vi;
4113 : 120753617 : fieldstack.iterate (i, &fo);
4114 : 21908043 : ++i, newvi = vi_next (newvi))
4115 : : {
4116 : 21908043 : const char *newname = NULL;
4117 : 21908043 : char *tempname;
4118 : :
4119 : 21908043 : if (dump_file)
4120 : : {
4121 : 331 : if (fieldstack.length () != 1)
4122 : : {
4123 : 301 : tempname
4124 : 301 : = xasprintf ("%s." HOST_WIDE_INT_PRINT_DEC
4125 : : "+" HOST_WIDE_INT_PRINT_DEC, name,
4126 : : fo->offset, fo->size);
4127 : 301 : newname = ggc_strdup (tempname);
4128 : 301 : free (tempname);
4129 : : }
4130 : : }
4131 : : else
4132 : : newname = "NULL";
4133 : :
4134 : 301 : if (newname)
4135 : 21908013 : newvi->name = newname;
4136 : 21908043 : newvi->offset = fo->offset;
4137 : 21908043 : newvi->size = fo->size;
4138 : 21908043 : newvi->fullsize = vi->fullsize;
4139 : 21908043 : newvi->may_have_pointers = fo->may_have_pointers;
4140 : 21908043 : newvi->only_restrict_pointers = fo->only_restrict_pointers;
4141 : 21908043 : if (handle_param
4142 : 1713660 : && newvi->only_restrict_pointers
4143 : 24892 : && !type_contains_placeholder_p (fo->restrict_pointed_type)
4144 : 21932935 : && !bitmap_bit_p (handled_struct_type,
4145 : 24892 : TYPE_UID (fo->restrict_pointed_type)))
4146 : : {
4147 : 24889 : varinfo_t rvi;
4148 : 24889 : tree heapvar = build_fake_var_decl (fo->restrict_pointed_type);
4149 : 24889 : DECL_EXTERNAL (heapvar) = 1;
4150 : 24889 : if (var_can_have_subvars (heapvar))
4151 : 80 : bitmap_set_bit (handled_struct_type,
4152 : 40 : TYPE_UID (fo->restrict_pointed_type));
4153 : 24889 : rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true,
4154 : : true, handled_struct_type);
4155 : 24889 : if (var_can_have_subvars (heapvar))
4156 : 80 : bitmap_clear_bit (handled_struct_type,
4157 : 40 : TYPE_UID (fo->restrict_pointed_type));
4158 : 24889 : rvi->is_restrict_var = 1;
4159 : 24889 : insert_vi_for_tree (heapvar, rvi);
4160 : 24889 : make_constraint_from (newvi, rvi->id);
4161 : 24889 : make_param_constraints (rvi);
4162 : : }
4163 : 36437281 : if (i + 1 < fieldstack.length ())
4164 : : {
4165 : 14529238 : varinfo_t tem = new_var_info (decl, name, false);
4166 : 14529238 : newvi->next = tem->id;
4167 : 14529238 : tem->head = vi->id;
4168 : : }
4169 : : }
4170 : :
4171 : : return vi;
4172 : 91466769 : }
4173 : :
4174 : : static unsigned int
4175 : 81448899 : create_variable_info_for (tree decl, const char *name, bool add_id)
4176 : : {
4177 : : /* First see if we are dealing with an ifunc resolver call and
4178 : : assiociate that with a call to the resolver function result. */
4179 : 81448899 : cgraph_node *node;
4180 : 81448899 : if (in_ipa_mode
4181 : 692759 : && TREE_CODE (decl) == FUNCTION_DECL
4182 : 17674 : && (node = cgraph_node::get (decl))
4183 : 81466571 : && node->ifunc_resolver)
4184 : : {
4185 : 1 : varinfo_t fi = get_vi_for_tree (node->get_alias_target ()->decl);
4186 : 1 : constraint_expr rhs
4187 : 1 : = get_function_part_constraint (fi, fi_result);
4188 : 1 : fi = new_var_info (NULL_TREE, "ifuncres", true);
4189 : 1 : fi->is_reg_var = true;
4190 : 1 : constraint_expr lhs;
4191 : 1 : lhs.type = SCALAR;
4192 : 1 : lhs.var = fi->id;
4193 : 1 : lhs.offset = 0;
4194 : 1 : process_constraint (new_constraint (lhs, rhs));
4195 : 1 : insert_vi_for_tree (decl, fi);
4196 : 1 : return fi->id;
4197 : : }
4198 : :
4199 : 81448898 : varinfo_t vi = create_variable_info_for_1 (decl, name, add_id, false, NULL);
4200 : 81448898 : unsigned int id = vi->id;
4201 : :
4202 : 81448898 : insert_vi_for_tree (decl, vi);
4203 : :
4204 : 81448898 : if (!VAR_P (decl))
4205 : : return id;
4206 : :
4207 : : /* Create initial constraints for globals. */
4208 : 32910535 : for (; vi; vi = vi_next (vi))
4209 : : {
4210 : 23138242 : if (!vi->may_have_pointers
4211 : 23138242 : || !vi->is_global_var)
4212 : 15203079 : continue;
4213 : :
4214 : : /* Mark global restrict qualified pointers. */
4215 : 15518377 : if ((POINTER_TYPE_P (TREE_TYPE (decl))
4216 : 352111 : && TYPE_RESTRICT (TREE_TYPE (decl)))
4217 : 15863797 : || vi->only_restrict_pointers)
4218 : : {
4219 : 11220 : varinfo_t rvi
4220 : 11220 : = make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT",
4221 : : true);
4222 : : /* ??? For now exclude reads from globals as restrict sources
4223 : : if those are not (indirectly) from incoming parameters. */
4224 : 11220 : rvi->is_restrict_var = false;
4225 : 11220 : continue;
4226 : 11220 : }
4227 : :
4228 : : /* In non-IPA mode the initializer from nonlocal is all we need. */
4229 : 7923943 : if (!in_ipa_mode
4230 : 7960641 : || DECL_HARD_REGISTER (decl))
4231 : 7887245 : make_copy_constraint (vi, nonlocal_id);
4232 : :
4233 : : /* In IPA mode parse the initializer and generate proper constraints
4234 : : for it. */
4235 : : else
4236 : : {
4237 : 36698 : varpool_node *vnode = varpool_node::get (decl);
4238 : :
4239 : : /* For escaped variables initialize them from nonlocal. */
4240 : 36698 : if (!vnode || !vnode->all_refs_explicit_p ())
4241 : 1466 : make_copy_constraint (vi, nonlocal_id);
4242 : :
4243 : : /* While we can in theory walk references for the varpool
4244 : : node that does not cover zero-initialization or references
4245 : : to the constant pool. */
4246 : 36698 : if (DECL_INITIAL (decl))
4247 : : {
4248 : 35594 : auto_vec<ce_s> rhsc;
4249 : 35594 : struct constraint_expr lhs, *rhsp;
4250 : 35594 : unsigned i;
4251 : 35594 : lhs.var = vi->id;
4252 : 35594 : lhs.offset = 0;
4253 : 35594 : lhs.type = SCALAR;
4254 : 35594 : get_constraint_for (DECL_INITIAL (decl), &rhsc);
4255 : 182665 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
4256 : 111477 : process_constraint (new_constraint (lhs, *rhsp));
4257 : : /* If this is a variable that escapes from the unit
4258 : : the initializer escapes as well. */
4259 : 35594 : if (!vnode || !vnode->all_refs_explicit_p ())
4260 : : {
4261 : 2199 : lhs.var = escaped_id;
4262 : 2199 : lhs.offset = 0;
4263 : 2199 : lhs.type = SCALAR;
4264 : 37793 : FOR_EACH_VEC_ELT (rhsc, i, rhsp)
4265 : 1584 : process_constraint (new_constraint (lhs, *rhsp));
4266 : : }
4267 : 35594 : }
4268 : : }
4269 : : }
4270 : :
4271 : : return id;
4272 : : }
4273 : :
4274 : : /* Register the constraints for function parameter related VI. */
4275 : :
4276 : : static void
4277 : 10017871 : make_param_constraints (varinfo_t vi)
4278 : : {
4279 : 11422743 : for (; vi; vi = vi_next (vi))
4280 : : {
4281 : 10934660 : if (vi->only_restrict_pointers)
4282 : : ;
4283 : 10334340 : else if (vi->may_have_pointers)
4284 : 10334340 : make_constraint_from (vi, nonlocal_id);
4285 : :
4286 : 10934660 : if (vi->is_full_var)
4287 : : break;
4288 : : }
4289 : 10017871 : }
4290 : :
4291 : : /* Create varinfo structures for all of the variables in the
4292 : : function for intraprocedural mode. */
4293 : :
4294 : : static void
4295 : 4485192 : intra_create_variable_infos (struct function *fn)
4296 : : {
4297 : 4485192 : tree t;
4298 : 4485192 : bitmap handled_struct_type = NULL;
4299 : 4485192 : bool this_parm_in_ctor = DECL_CXX_CONSTRUCTOR_P (fn->decl);
4300 : :
4301 : : /* For each incoming pointer argument arg, create the constraint ARG
4302 : : = NONLOCAL or a dummy variable if it is a restrict qualified
4303 : : passed-by-reference argument. */
4304 : 13902746 : for (t = DECL_ARGUMENTS (fn->decl); t; t = DECL_CHAIN (t))
4305 : : {
4306 : 9417554 : if (handled_struct_type == NULL)
4307 : 3796289 : handled_struct_type = BITMAP_ALLOC (NULL);
4308 : :
4309 : 9417554 : varinfo_t p
4310 : 9417554 : = create_variable_info_for_1 (t, alias_get_name (t), false, true,
4311 : : handled_struct_type, this_parm_in_ctor);
4312 : 9417554 : insert_vi_for_tree (t, p);
4313 : :
4314 : 9417554 : make_param_constraints (p);
4315 : :
4316 : 9417554 : this_parm_in_ctor = false;
4317 : : }
4318 : :
4319 : 4485192 : if (handled_struct_type != NULL)
4320 : 3796289 : BITMAP_FREE (handled_struct_type);
4321 : :
4322 : : /* Add a constraint for a result decl that is passed by reference. */
4323 : 4485192 : if (DECL_RESULT (fn->decl)
4324 : 4485192 : && DECL_BY_REFERENCE (DECL_RESULT (fn->decl)))
4325 : : {
4326 : 59286 : varinfo_t p, result_vi = get_vi_for_tree (DECL_RESULT (fn->decl));
4327 : :
4328 : 177858 : for (p = result_vi; p; p = vi_next (p))
4329 : 59286 : make_constraint_from (p, nonlocal_id);
4330 : : }
4331 : :
4332 : : /* Add a constraint for the incoming static chain parameter. */
4333 : 4485192 : if (fn->static_chain_decl != NULL_TREE)
4334 : : {
4335 : 47226 : varinfo_t p, chain_vi = get_vi_for_tree (fn->static_chain_decl);
4336 : :
4337 : 141678 : for (p = chain_vi; p; p = vi_next (p))
4338 : 47226 : make_constraint_from (p, nonlocal_id);
4339 : : }
4340 : 4485192 : }
4341 : :
4342 : : /* Structure used to put solution bitmaps in a hashtable so they can
4343 : : be shared among variables with the same points-to set. */
4344 : :
4345 : : typedef struct shared_bitmap_info
4346 : : {
4347 : : bitmap pt_vars;
4348 : : hashval_t hashcode;
4349 : : } *shared_bitmap_info_t;
4350 : : typedef const struct shared_bitmap_info *const_shared_bitmap_info_t;
4351 : :
4352 : : /* Shared_bitmap hashtable helpers. */
4353 : :
4354 : : struct shared_bitmap_hasher : free_ptr_hash <shared_bitmap_info>
4355 : : {
4356 : : static inline hashval_t hash (const shared_bitmap_info *);
4357 : : static inline bool equal (const shared_bitmap_info *,
4358 : : const shared_bitmap_info *);
4359 : : };
4360 : :
4361 : : /* Hash function for a shared_bitmap_info_t. */
4362 : :
4363 : : inline hashval_t
4364 : 5098138 : shared_bitmap_hasher::hash (const shared_bitmap_info *bi)
4365 : : {
4366 : 5098138 : return bi->hashcode;
4367 : : }
4368 : :
4369 : : /* Equality function for two shared_bitmap_info_t's. */
4370 : :
4371 : : inline bool
4372 : 43077620 : shared_bitmap_hasher::equal (const shared_bitmap_info *sbi1,
4373 : : const shared_bitmap_info *sbi2)
4374 : : {
4375 : 43077620 : return bitmap_equal_p (sbi1->pt_vars, sbi2->pt_vars);
4376 : : }
4377 : :
4378 : : /* Shared_bitmap hashtable. */
4379 : :
4380 : : static hash_table<shared_bitmap_hasher> *shared_bitmap_table;
4381 : :
4382 : : /* Lookup a bitmap in the shared bitmap hashtable, and return an already
4383 : : existing instance if there is one, NULL otherwise. */
4384 : :
4385 : : static bitmap
4386 : 46514832 : shared_bitmap_lookup (bitmap pt_vars)
4387 : : {
4388 : 46514832 : shared_bitmap_info **slot;
4389 : 46514832 : struct shared_bitmap_info sbi;
4390 : :
4391 : 46514832 : sbi.pt_vars = pt_vars;
4392 : 46514832 : sbi.hashcode = bitmap_hash (pt_vars);
4393 : :
4394 : 46514832 : slot = shared_bitmap_table->find_slot (&sbi, NO_INSERT);
4395 : 46514832 : if (!slot)
4396 : : return NULL;
4397 : : else
4398 : 37660087 : return (*slot)->pt_vars;
4399 : : }
4400 : :
4401 : :
4402 : : /* Add a bitmap to the shared bitmap hashtable. */
4403 : :
4404 : : static void
4405 : 8854745 : shared_bitmap_add (bitmap pt_vars)
4406 : : {
4407 : 8854745 : shared_bitmap_info **slot;
4408 : 8854745 : shared_bitmap_info_t sbi = XNEW (struct shared_bitmap_info);
4409 : :
4410 : 8854745 : sbi->pt_vars = pt_vars;
4411 : 8854745 : sbi->hashcode = bitmap_hash (pt_vars);
4412 : :
4413 : 8854745 : slot = shared_bitmap_table->find_slot (sbi, INSERT);
4414 : 8854745 : gcc_assert (!*slot);
4415 : 8854745 : *slot = sbi;
4416 : 8854745 : }
4417 : :
4418 : :
4419 : : /* Set bits in INTO corresponding to the variable uids in solution set FROM. */
4420 : :
4421 : : static void
4422 : 46514832 : set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt,
4423 : : tree fndecl)
4424 : : {
4425 : 46514832 : unsigned int i;
4426 : 46514832 : bitmap_iterator bi;
4427 : 46514832 : varinfo_t escaped_vi = get_varinfo (var_rep[escaped_id]);
4428 : 46514832 : varinfo_t escaped_return_vi = get_varinfo (var_rep[escaped_return_id]);
4429 : 46514832 : bool everything_escaped
4430 : 46514832 : = escaped_vi->solution && bitmap_bit_p (escaped_vi->solution, anything_id);
4431 : :
4432 : 269910249 : EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
4433 : : {
4434 : 223395417 : varinfo_t vi = get_varinfo (i);
4435 : :
4436 : 223395417 : if (vi->is_artificial_var)
4437 : 83368870 : continue;
4438 : :
4439 : 140026547 : if (everything_escaped
4440 : 140026547 : || (escaped_vi->solution
4441 : 139479593 : && bitmap_bit_p (escaped_vi->solution, i)))
4442 : : {
4443 : 121506819 : pt->vars_contains_escaped = true;
4444 : 121506819 : pt->vars_contains_escaped_heap |= vi->is_heap_var;
4445 : : }
4446 : 140026547 : if (escaped_return_vi->solution
4447 : 140026547 : && bitmap_bit_p (escaped_return_vi->solution, i))
4448 : 16995585 : pt->vars_contains_escaped_heap |= vi->is_heap_var;
4449 : :
4450 : 140026547 : if (vi->is_restrict_var)
4451 : 1784548 : pt->vars_contains_restrict = true;
4452 : :
4453 : 140026547 : if (VAR_P (vi->decl)
4454 : 2445299 : || TREE_CODE (vi->decl) == PARM_DECL
4455 : 1923330 : || TREE_CODE (vi->decl) == RESULT_DECL)
4456 : : {
4457 : : /* If we are in IPA mode we will not recompute points-to
4458 : : sets after inlining so make sure they stay valid. */
4459 : 138115329 : if (in_ipa_mode
4460 : 138115329 : && !DECL_PT_UID_SET_P (vi->decl))
4461 : 33392 : SET_DECL_PT_UID (vi->decl, DECL_UID (vi->decl));
4462 : :
4463 : : /* Add the decl to the points-to set. Note that the points-to
4464 : : set contains global variables. */
4465 : 138115329 : bitmap_set_bit (into, DECL_PT_UID (vi->decl));
4466 : 138115329 : if (vi->is_global_var
4467 : : /* In IPA mode the escaped_heap trick doesn't work as
4468 : : ESCAPED is escaped from the unit but
4469 : : pt_solution_includes_global needs to answer true for
4470 : : all variables not automatic within a function.
4471 : : For the same reason is_global_var is not the
4472 : : correct flag to track - local variables from other
4473 : : functions also need to be considered global.
4474 : : Conveniently all HEAP vars are not put in function
4475 : : scope. */
4476 : 138115329 : || (in_ipa_mode
4477 : 272843 : && fndecl
4478 : 247765 : && ! auto_var_in_fn_p (vi->decl, fndecl)))
4479 : 78353802 : pt->vars_contains_nonlocal = true;
4480 : :
4481 : : /* If we have a variable that is interposable record that fact
4482 : : for pointer comparison simplification. */
4483 : 138115329 : if (VAR_P (vi->decl)
4484 : 137581248 : && (TREE_STATIC (vi->decl) || DECL_EXTERNAL (vi->decl))
4485 : 216324272 : && ! decl_binds_to_current_def_p (vi->decl))
4486 : 55712407 : pt->vars_contains_interposable = true;
4487 : :
4488 : : /* If this is a local variable we can have overlapping lifetime
4489 : : of different function invocations through recursion duplicate
4490 : : it with its shadow variable. */
4491 : 138115329 : if (in_ipa_mode
4492 : 331854 : && vi->shadow_var_uid != 0)
4493 : : {
4494 : 204432 : bitmap_set_bit (into, vi->shadow_var_uid);
4495 : 204432 : pt->vars_contains_nonlocal = true;
4496 : : }
4497 : : }
4498 : :
4499 : 1911218 : else if (TREE_CODE (vi->decl) == FUNCTION_DECL
4500 : 1911218 : || TREE_CODE (vi->decl) == LABEL_DECL)
4501 : : {
4502 : : /* Nothing should read/write from/to code so we can
4503 : : save bits by not including them in the points-to bitmaps.
4504 : : Still mark the points-to set as containing global memory
4505 : : to make code-patching possible - see PR70128. */
4506 : 1757310 : pt->vars_contains_nonlocal = true;
4507 : : }
4508 : : }
4509 : 46514832 : }
4510 : :
4511 : :
4512 : : /* Compute the points-to solution *PT for the variable VI. */
4513 : :
4514 : : static struct pt_solution
4515 : 61179042 : find_what_var_points_to (tree fndecl, varinfo_t orig_vi)
4516 : : {
4517 : 61179042 : unsigned int i;
4518 : 61179042 : bitmap_iterator bi;
4519 : 61179042 : bitmap finished_solution;
4520 : 61179042 : bitmap result;
4521 : 61179042 : varinfo_t vi;
4522 : 61179042 : struct pt_solution *pt;
4523 : :
4524 : : /* This variable may have been collapsed, let's get the real
4525 : : variable. */
4526 : 61179042 : vi = get_varinfo (var_rep[orig_vi->id]);
4527 : :
4528 : : /* See if we have already computed the solution and return it. */
4529 : 61179042 : pt_solution **slot = &final_solutions->get_or_insert (vi);
4530 : 61179042 : if (*slot != NULL)
4531 : 14059745 : return **slot;
4532 : :
4533 : 47119297 : *slot = pt = XOBNEW (&final_solutions_obstack, struct pt_solution);
4534 : 47119297 : memset (pt, 0, sizeof (struct pt_solution));
4535 : :
4536 : : /* Translate artificial variables into SSA_NAME_PTR_INFO
4537 : : attributes. */
4538 : 275892829 : EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
4539 : : {
4540 : 228773532 : varinfo_t vi = get_varinfo (i);
4541 : :
4542 : 228773532 : if (vi->is_artificial_var)
4543 : : {
4544 : 85402250 : if (vi->id == nothing_id)
4545 : 10189568 : pt->null = 1;
4546 : : else if (vi->id == escaped_id)
4547 : : {
4548 : 32448861 : if (in_ipa_mode)
4549 : 134093 : pt->ipa_escaped = 1;
4550 : : else
4551 : 32314768 : pt->escaped = 1;
4552 : : /* Expand some special vars of ESCAPED in-place here. */
4553 : 32448861 : varinfo_t evi = get_varinfo (var_rep[escaped_id]);
4554 : 32448861 : if (bitmap_bit_p (evi->solution, nonlocal_id))
4555 : 30157340 : pt->nonlocal = 1;
4556 : : }
4557 : : else if (vi->id == nonlocal_id)
4558 : 36153030 : pt->nonlocal = 1;
4559 : : else if (vi->id == string_id)
4560 : 6005335 : pt->const_pool = 1;
4561 : : else if (vi->id == anything_id
4562 : : || vi->id == integer_id)
4563 : 604480 : pt->anything = 1;
4564 : : }
4565 : : }
4566 : :
4567 : : /* Instead of doing extra work, simply do not create
4568 : : elaborate points-to information for pt_anything pointers. */
4569 : 47119297 : if (pt->anything)
4570 : 604465 : return *pt;
4571 : :
4572 : : /* Share the final set of variables when possible. */
4573 : 46514832 : finished_solution = BITMAP_GGC_ALLOC ();
4574 : 46514832 : stats.points_to_sets_created++;
4575 : :
4576 : 46514832 : set_uids_in_ptset (finished_solution, vi->solution, pt, fndecl);
4577 : 46514832 : result = shared_bitmap_lookup (finished_solution);
4578 : 46514832 : if (!result)
4579 : : {
4580 : 8854745 : shared_bitmap_add (finished_solution);
4581 : 8854745 : pt->vars = finished_solution;
4582 : : }
4583 : : else
4584 : : {
4585 : 37660087 : pt->vars = result;
4586 : 37660087 : bitmap_clear (finished_solution);
4587 : : }
4588 : :
4589 : 46514832 : return *pt;
4590 : : }
4591 : :
4592 : : /* Given a pointer variable P, fill in its points-to set. */
4593 : :
4594 : : static void
4595 : 24464218 : find_what_p_points_to (tree fndecl, tree p)
4596 : : {
4597 : 24464218 : struct ptr_info_def *pi;
4598 : 24464218 : tree lookup_p = p;
4599 : 24464218 : varinfo_t vi;
4600 : 24464218 : prange vr;
4601 : 48928436 : get_range_query (DECL_STRUCT_FUNCTION (fndecl))->range_of_expr (vr, p);
4602 : 24464218 : bool nonnull = vr.nonzero_p ();
4603 : :
4604 : : /* For parameters, get at the points-to set for the actual parm
4605 : : decl. */
4606 : 24464218 : if (TREE_CODE (p) == SSA_NAME
4607 : 24464218 : && SSA_NAME_IS_DEFAULT_DEF (p)
4608 : 29656932 : && (TREE_CODE (SSA_NAME_VAR (p)) == PARM_DECL
4609 : 938875 : || TREE_CODE (SSA_NAME_VAR (p)) == RESULT_DECL))
4610 : 4312978 : lookup_p = SSA_NAME_VAR (p);
4611 : :
4612 : 24464218 : vi = lookup_vi_for_tree (lookup_p);
4613 : 24464218 : if (!vi)
4614 : 969194 : return;
4615 : :
4616 : 23495024 : pi = get_ptr_info (p);
4617 : 23495024 : pi->pt = find_what_var_points_to (fndecl, vi);
4618 : : /* Conservatively set to NULL from PTA (to true). */
4619 : 23495024 : pi->pt.null = 1;
4620 : : /* Preserve pointer nonnull globally computed. */
4621 : 23495024 : if (nonnull)
4622 : 3714840 : set_ptr_nonnull (p);
4623 : 24464218 : }
4624 : :
4625 : :
4626 : : /* Query statistics for points-to solutions. */
4627 : :
4628 : : static struct {
4629 : : unsigned HOST_WIDE_INT pt_solution_includes_may_alias;
4630 : : unsigned HOST_WIDE_INT pt_solution_includes_no_alias;
4631 : : unsigned HOST_WIDE_INT pt_solutions_intersect_may_alias;
4632 : : unsigned HOST_WIDE_INT pt_solutions_intersect_no_alias;
4633 : : } pta_stats;
4634 : :
4635 : : void
4636 : 0 : dump_pta_stats (FILE *s)
4637 : : {
4638 : 0 : fprintf (s, "\nPTA query stats:\n");
4639 : 0 : fprintf (s, " pt_solution_includes: "
4640 : : HOST_WIDE_INT_PRINT_DEC" disambiguations, "
4641 : : HOST_WIDE_INT_PRINT_DEC" queries\n",
4642 : : pta_stats.pt_solution_includes_no_alias,
4643 : 0 : pta_stats.pt_solution_includes_no_alias
4644 : 0 : + pta_stats.pt_solution_includes_may_alias);
4645 : 0 : fprintf (s, " pt_solutions_intersect: "
4646 : : HOST_WIDE_INT_PRINT_DEC" disambiguations, "
4647 : : HOST_WIDE_INT_PRINT_DEC" queries\n",
4648 : : pta_stats.pt_solutions_intersect_no_alias,
4649 : 0 : pta_stats.pt_solutions_intersect_no_alias
4650 : 0 : + pta_stats.pt_solutions_intersect_may_alias);
4651 : 0 : }
4652 : :
4653 : :
4654 : : /* Reset the points-to solution *PT to a conservative default
4655 : : (point to anything). */
4656 : :
4657 : : void
4658 : 67577199 : pt_solution_reset (struct pt_solution *pt)
4659 : : {
4660 : 67577199 : memset (pt, 0, sizeof (struct pt_solution));
4661 : 67577199 : pt->anything = true;
4662 : 67577199 : pt->null = true;
4663 : 67577199 : }
4664 : :
4665 : : /* Set the points-to solution *PT to point only to the variables
4666 : : in VARS. VARS_CONTAINS_GLOBAL specifies whether that contains
4667 : : global variables and VARS_CONTAINS_RESTRICT specifies whether
4668 : : it contains restrict tag variables. */
4669 : :
4670 : : void
4671 : 73130 : pt_solution_set (struct pt_solution *pt, bitmap vars,
4672 : : bool vars_contains_nonlocal)
4673 : : {
4674 : 73130 : memset (pt, 0, sizeof (struct pt_solution));
4675 : 73130 : pt->vars = vars;
4676 : 73130 : pt->vars_contains_nonlocal = vars_contains_nonlocal;
4677 : 73130 : pt->vars_contains_escaped
4678 : 146260 : = (cfun->gimple_df->escaped.anything
4679 : 73130 : || bitmap_intersect_p (cfun->gimple_df->escaped.vars, vars));
4680 : 73130 : }
4681 : :
4682 : : /* Set the points-to solution *PT to point only to the variable VAR. */
4683 : :
4684 : : void
4685 : 68932 : pt_solution_set_var (struct pt_solution *pt, tree var)
4686 : : {
4687 : 68932 : memset (pt, 0, sizeof (struct pt_solution));
4688 : 68932 : pt->vars = BITMAP_GGC_ALLOC ();
4689 : 68932 : bitmap_set_bit (pt->vars, DECL_PT_UID (var));
4690 : 68932 : pt->vars_contains_nonlocal = is_global_var (var);
4691 : 68932 : pt->vars_contains_escaped
4692 : 137864 : = (cfun->gimple_df->escaped.anything
4693 : 68932 : || bitmap_bit_p (cfun->gimple_df->escaped.vars, DECL_PT_UID (var)));
4694 : 68932 : }
4695 : :
4696 : : /* Computes the union of the points-to solutions *DEST and *SRC and
4697 : : stores the result in *DEST. This changes the points-to bitmap
4698 : : of *DEST and thus may not be used if that might be shared.
4699 : : The points-to bitmap of *SRC and *DEST will not be shared after
4700 : : this function if they were not before. */
4701 : :
4702 : : static void
4703 : 34 : pt_solution_ior_into (struct pt_solution *dest, struct pt_solution *src)
4704 : : {
4705 : 34 : dest->anything |= src->anything;
4706 : 34 : if (dest->anything)
4707 : : {
4708 : 0 : pt_solution_reset (dest);
4709 : 0 : return;
4710 : : }
4711 : :
4712 : 34 : dest->nonlocal |= src->nonlocal;
4713 : 34 : dest->escaped |= src->escaped;
4714 : 34 : dest->ipa_escaped |= src->ipa_escaped;
4715 : 34 : dest->null |= src->null;
4716 : 34 : dest->const_pool |= src->const_pool ;
4717 : 34 : dest->vars_contains_nonlocal |= src->vars_contains_nonlocal;
4718 : 34 : dest->vars_contains_escaped |= src->vars_contains_escaped;
4719 : 34 : dest->vars_contains_escaped_heap |= src->vars_contains_escaped_heap;
4720 : 34 : if (!src->vars)
4721 : : return;
4722 : :
4723 : 34 : if (!dest->vars)
4724 : 20 : dest->vars = BITMAP_GGC_ALLOC ();
4725 : 34 : bitmap_ior_into (dest->vars, src->vars);
4726 : : }
4727 : :
4728 : : /* Return true if the points-to solution *PT is empty. */
4729 : :
4730 : : bool
4731 : 11650 : pt_solution_empty_p (const pt_solution *pt)
4732 : : {
4733 : 11650 : if (pt->anything
4734 : 8222 : || pt->nonlocal)
4735 : : return false;
4736 : :
4737 : 233 : if (pt->vars
4738 : 233 : && !bitmap_empty_p (pt->vars))
4739 : : return false;
4740 : :
4741 : : /* If the solution includes ESCAPED, check if that is empty. */
4742 : 231 : if (pt->escaped
4743 : 231 : && !pt_solution_empty_p (&cfun->gimple_df->escaped))
4744 : : return false;
4745 : :
4746 : : /* If the solution includes ESCAPED, check if that is empty. */
4747 : 231 : if (pt->ipa_escaped
4748 : 231 : && !pt_solution_empty_p (&ipa_escaped_pt))
4749 : : return false;
4750 : :
4751 : : return true;
4752 : : }
4753 : :
4754 : : /* Return true if the points-to solution *PT only point to a single var, and
4755 : : return the var uid in *UID. */
4756 : :
4757 : : bool
4758 : 912750 : pt_solution_singleton_or_null_p (struct pt_solution *pt, unsigned *uid)
4759 : : {
4760 : 907621 : if (pt->anything || pt->nonlocal || pt->escaped || pt->ipa_escaped
4761 : 196437 : || pt->vars == NULL
4762 : 1109187 : || !bitmap_single_bit_set_p (pt->vars))
4763 : 722594 : return false;
4764 : :
4765 : 190156 : *uid = bitmap_first_set_bit (pt->vars);
4766 : 190156 : return true;
4767 : : }
4768 : :
4769 : : /* Return true if the points-to solution *PT includes global memory.
4770 : : If ESCAPED_LOCAL_P is true then escaped local variables are also
4771 : : considered global. */
4772 : :
4773 : : bool
4774 : 47481607 : pt_solution_includes_global (struct pt_solution *pt, bool escaped_local_p)
4775 : : {
4776 : 47481607 : if (pt->anything
4777 : 46654307 : || pt->nonlocal
4778 : 11868078 : || pt->vars_contains_nonlocal
4779 : : /* The following is a hack to make the malloc escape hack work.
4780 : : In reality we'd need different sets for escaped-through-return
4781 : : and escaped-to-callees and passes would need to be updated. */
4782 : 4156233 : || pt->vars_contains_escaped_heap)
4783 : : return true;
4784 : :
4785 : 2223972 : if (escaped_local_p && pt->vars_contains_escaped)
4786 : : return true;
4787 : :
4788 : : /* 'escaped' is also a placeholder so we have to look into it. */
4789 : 2223051 : if (pt->escaped)
4790 : 92 : return pt_solution_includes_global (&cfun->gimple_df->escaped,
4791 : 92 : escaped_local_p);
4792 : :
4793 : 2222959 : if (pt->ipa_escaped)
4794 : 23850 : return pt_solution_includes_global (&ipa_escaped_pt,
4795 : 23850 : escaped_local_p);
4796 : :
4797 : : return false;
4798 : : }
4799 : :
4800 : : /* Return true if the points-to solution *PT includes the variable
4801 : : declaration DECL. */
4802 : :
4803 : : static bool
4804 : 255935865 : pt_solution_includes_1 (struct pt_solution *pt, const_tree decl)
4805 : : {
4806 : 255935865 : if (pt->anything)
4807 : : return true;
4808 : :
4809 : 250280059 : if (pt->nonlocal
4810 : 250280059 : && is_global_var (decl))
4811 : : return true;
4812 : :
4813 : 231950005 : if (pt->vars
4814 : 231950005 : && bitmap_bit_p (pt->vars, DECL_PT_UID (decl)))
4815 : : return true;
4816 : :
4817 : : /* If the solution includes ESCAPED, check it. */
4818 : 180497410 : if (pt->escaped
4819 : 180497410 : && pt_solution_includes_1 (&cfun->gimple_df->escaped, decl))
4820 : : return true;
4821 : :
4822 : : /* If the solution includes ESCAPED, check it. */
4823 : 154533576 : if (pt->ipa_escaped
4824 : 154533576 : && pt_solution_includes_1 (&ipa_escaped_pt, decl))
4825 : : return true;
4826 : :
4827 : : return false;
4828 : : }
4829 : :
4830 : : bool
4831 : 170714281 : pt_solution_includes (struct pt_solution *pt, const_tree decl)
4832 : : {
4833 : 170714281 : bool res = pt_solution_includes_1 (pt, decl);
4834 : 170714281 : if (res)
4835 : 75438455 : ++pta_stats.pt_solution_includes_may_alias;
4836 : : else
4837 : 95275826 : ++pta_stats.pt_solution_includes_no_alias;
4838 : 170714281 : return res;
4839 : : }
4840 : :
4841 : : /* Return true if the points-to solution *PT contains a reference to a
4842 : : constant pool entry. */
4843 : :
4844 : : bool
4845 : 7159062 : pt_solution_includes_const_pool (struct pt_solution *pt)
4846 : : {
4847 : 7159062 : return (pt->const_pool
4848 : 7015227 : || pt->nonlocal
4849 : 453724 : || (pt->escaped && (!cfun || cfun->gimple_df->escaped.const_pool))
4850 : 7612786 : || (pt->ipa_escaped && ipa_escaped_pt.const_pool));
4851 : : }
4852 : :
4853 : : /* Return true if both points-to solutions PT1 and PT2 have a non-empty
4854 : : intersection. */
4855 : :
4856 : : static bool
4857 : 82952498 : pt_solutions_intersect_1 (struct pt_solution *pt1, struct pt_solution *pt2)
4858 : : {
4859 : 82952498 : if (pt1->anything || pt2->anything)
4860 : : return true;
4861 : :
4862 : : /* If either points to unknown global memory and the other points to
4863 : : any global memory they alias. */
4864 : 80468597 : if ((pt1->nonlocal
4865 : 56664577 : && (pt2->nonlocal
4866 : 12660254 : || pt2->vars_contains_nonlocal))
4867 : 34591773 : || (pt2->nonlocal
4868 : 9236615 : && pt1->vars_contains_nonlocal))
4869 : : return true;
4870 : :
4871 : : /* If either points to all escaped memory and the other points to
4872 : : any escaped memory they alias. */
4873 : 34238391 : if ((pt1->escaped
4874 : 7624445 : && (pt2->escaped
4875 : 7624445 : || pt2->vars_contains_escaped))
4876 : 30967335 : || (pt2->escaped
4877 : 7342589 : && pt1->vars_contains_escaped))
4878 : : return true;
4879 : :
4880 : : /* Check the escaped solution if required.
4881 : : ??? Do we need to check the local against the IPA escaped sets? */
4882 : 28890076 : if ((pt1->ipa_escaped || pt2->ipa_escaped)
4883 : 28900748 : && !pt_solution_empty_p (&ipa_escaped_pt))
4884 : : {
4885 : : /* If both point to escaped memory and that solution
4886 : : is not empty they alias. */
4887 : 10665 : if (pt1->ipa_escaped && pt2->ipa_escaped)
4888 : : return true;
4889 : :
4890 : : /* If either points to escaped memory see if the escaped solution
4891 : : intersects with the other. */
4892 : 10665 : if ((pt1->ipa_escaped
4893 : 1237 : && pt_solutions_intersect_1 (&ipa_escaped_pt, pt2))
4894 : 10873 : || (pt2->ipa_escaped
4895 : 9428 : && pt_solutions_intersect_1 (&ipa_escaped_pt, pt1)))
4896 : 10085 : return true;
4897 : : }
4898 : :
4899 : : /* Now both pointers alias if their points-to solution intersects. */
4900 : 28881235 : return (pt1->vars
4901 : 28881219 : && pt2->vars
4902 : 57762454 : && bitmap_intersect_p (pt1->vars, pt2->vars));
4903 : : }
4904 : :
4905 : : bool
4906 : 82941833 : pt_solutions_intersect (struct pt_solution *pt1, struct pt_solution *pt2)
4907 : : {
4908 : 82941833 : bool res = pt_solutions_intersect_1 (pt1, pt2);
4909 : 82941833 : if (res)
4910 : 57542174 : ++pta_stats.pt_solutions_intersect_may_alias;
4911 : : else
4912 : 25399659 : ++pta_stats.pt_solutions_intersect_no_alias;
4913 : 82941833 : return res;
4914 : : }
4915 : :
4916 : :
4917 : : /* Initialize the always-existing constraint variables for NULL
4918 : : ANYTHING, READONLY, and INTEGER */
4919 : :
4920 : : static void
4921 : 4489616 : init_base_vars (void)
4922 : : {
4923 : 4489616 : struct constraint_expr lhs, rhs;
4924 : 4489616 : varinfo_t var_anything;
4925 : 4489616 : varinfo_t var_nothing;
4926 : 4489616 : varinfo_t var_string;
4927 : 4489616 : varinfo_t var_escaped;
4928 : 4489616 : varinfo_t var_nonlocal;
4929 : 4489616 : varinfo_t var_escaped_return;
4930 : 4489616 : varinfo_t var_storedanything;
4931 : 4489616 : varinfo_t var_integer;
4932 : :
4933 : : /* Variable ID zero is reserved and should be NULL. */
4934 : 4489616 : varmap.safe_push (NULL);
4935 : :
4936 : : /* Create the NULL variable, used to represent that a variable points
4937 : : to NULL. */
4938 : 4489616 : var_nothing = new_var_info (NULL_TREE, "NULL", false);
4939 : 4489616 : gcc_assert (var_nothing->id == nothing_id);
4940 : 4489616 : var_nothing->is_artificial_var = 1;
4941 : 4489616 : var_nothing->offset = 0;
4942 : 4489616 : var_nothing->size = ~0;
4943 : 4489616 : var_nothing->fullsize = ~0;
4944 : 4489616 : var_nothing->is_special_var = 1;
4945 : 4489616 : var_nothing->may_have_pointers = 0;
4946 : 4489616 : var_nothing->is_global_var = 0;
4947 : :
4948 : : /* Create the ANYTHING variable, used to represent that a variable
4949 : : points to some unknown piece of memory. */
4950 : 4489616 : var_anything = new_var_info (NULL_TREE, "ANYTHING", false);
4951 : 4489616 : gcc_assert (var_anything->id == anything_id);
4952 : 4489616 : var_anything->is_artificial_var = 1;
4953 : 4489616 : var_anything->size = ~0;
4954 : 4489616 : var_anything->offset = 0;
4955 : 4489616 : var_anything->fullsize = ~0;
4956 : 4489616 : var_anything->is_special_var = 1;
4957 : :
4958 : : /* Anything points to anything. This makes deref constraints just
4959 : : work in the presence of linked list and other p = *p type loops,
4960 : : by saying that *ANYTHING = ANYTHING. */
4961 : 4489616 : lhs.type = SCALAR;
4962 : 4489616 : lhs.var = anything_id;
4963 : 4489616 : lhs.offset = 0;
4964 : 4489616 : rhs.type = ADDRESSOF;
4965 : 4489616 : rhs.var = anything_id;
4966 : 4489616 : rhs.offset = 0;
4967 : :
4968 : : /* This specifically does not use process_constraint because
4969 : : process_constraint ignores all anything = anything constraints, since all
4970 : : but this one are redundant. */
4971 : 4489616 : constraints.safe_push (new_constraint (lhs, rhs));
4972 : :
4973 : : /* Create the STRING variable, used to represent that a variable
4974 : : points to a string literal. String literals don't contain
4975 : : pointers so STRING doesn't point to anything. */
4976 : 4489616 : var_string = new_var_info (NULL_TREE, "STRING", false);
4977 : 4489616 : gcc_assert (var_string->id == string_id);
4978 : 4489616 : var_string->is_artificial_var = 1;
4979 : 4489616 : var_string->offset = 0;
4980 : 4489616 : var_string->size = ~0;
4981 : 4489616 : var_string->fullsize = ~0;
4982 : 4489616 : var_string->is_special_var = 1;
4983 : 4489616 : var_string->may_have_pointers = 0;
4984 : :
4985 : : /* Create the ESCAPED variable, used to represent the set of escaped
4986 : : memory. */
4987 : 4489616 : var_escaped = new_var_info (NULL_TREE, "ESCAPED", false);
4988 : 4489616 : gcc_assert (var_escaped->id == escaped_id);
4989 : 4489616 : var_escaped->is_artificial_var = 1;
4990 : 4489616 : var_escaped->offset = 0;
4991 : 4489616 : var_escaped->size = ~0;
4992 : 4489616 : var_escaped->fullsize = ~0;
4993 : 4489616 : var_escaped->is_special_var = 0;
4994 : :
4995 : : /* Create the NONLOCAL variable, used to represent the set of nonlocal
4996 : : memory. */
4997 : 4489616 : var_nonlocal = new_var_info (NULL_TREE, "NONLOCAL", false);
4998 : 4489616 : gcc_assert (var_nonlocal->id == nonlocal_id);
4999 : 4489616 : var_nonlocal->is_artificial_var = 1;
5000 : 4489616 : var_nonlocal->offset = 0;
5001 : 4489616 : var_nonlocal->size = ~0;
5002 : 4489616 : var_nonlocal->fullsize = ~0;
5003 : 4489616 : var_nonlocal->is_special_var = 1;
5004 : :
5005 : : /* Create the ESCAPED_RETURN variable, used to represent the set of escaped
5006 : : memory via a regular return stmt. */
5007 : 4489616 : var_escaped_return = new_var_info (NULL_TREE, "ESCAPED_RETURN", false);
5008 : 4489616 : gcc_assert (var_escaped_return->id == escaped_return_id);
5009 : 4489616 : var_escaped_return->is_artificial_var = 1;
5010 : 4489616 : var_escaped_return->offset = 0;
5011 : 4489616 : var_escaped_return->size = ~0;
5012 : 4489616 : var_escaped_return->fullsize = ~0;
5013 : 4489616 : var_escaped_return->is_special_var = 0;
5014 : :
5015 : : /* ESCAPED = *ESCAPED, because escaped is may-deref'd at calls, etc. */
5016 : 4489616 : lhs.type = SCALAR;
5017 : 4489616 : lhs.var = escaped_id;
5018 : 4489616 : lhs.offset = 0;
5019 : 4489616 : rhs.type = DEREF;
5020 : 4489616 : rhs.var = escaped_id;
5021 : 4489616 : rhs.offset = 0;
5022 : 4489616 : process_constraint (new_constraint (lhs, rhs));
5023 : :
5024 : : /* ESCAPED = ESCAPED + UNKNOWN_OFFSET, because if a sub-field escapes the
5025 : : whole variable escapes. */
5026 : 4489616 : lhs.type = SCALAR;
5027 : 4489616 : lhs.var = escaped_id;
5028 : 4489616 : lhs.offset = 0;
5029 : 4489616 : rhs.type = SCALAR;
5030 : 4489616 : rhs.var = escaped_id;
5031 : 4489616 : rhs.offset = UNKNOWN_OFFSET;
5032 : 4489616 : process_constraint (new_constraint (lhs, rhs));
5033 : :
5034 : : /* *ESCAPED = NONLOCAL. This is true because we have to assume
5035 : : everything pointed to by escaped points to what global memory can
5036 : : point to. */
5037 : 4489616 : lhs.type = DEREF;
5038 : 4489616 : lhs.var = escaped_id;
5039 : 4489616 : lhs.offset = 0;
5040 : 4489616 : rhs.type = SCALAR;
5041 : 4489616 : rhs.var = nonlocal_id;
5042 : 4489616 : rhs.offset = 0;
5043 : 4489616 : process_constraint (new_constraint (lhs, rhs));
5044 : :
5045 : : /* NONLOCAL = &NONLOCAL, NONLOCAL = &ESCAPED. This is true because
5046 : : global memory may point to global memory and escaped memory. */
5047 : 4489616 : lhs.type = SCALAR;
5048 : 4489616 : lhs.var = nonlocal_id;
5049 : 4489616 : lhs.offset = 0;
5050 : 4489616 : rhs.type = ADDRESSOF;
5051 : 4489616 : rhs.var = nonlocal_id;
5052 : 4489616 : rhs.offset = 0;
5053 : 4489616 : process_constraint (new_constraint (lhs, rhs));
5054 : 4489616 : rhs.type = ADDRESSOF;
5055 : 4489616 : rhs.var = escaped_id;
5056 : 4489616 : rhs.offset = 0;
5057 : 4489616 : process_constraint (new_constraint (lhs, rhs));
5058 : :
5059 : : /* Transitively close ESCAPED_RETURN.
5060 : : ESCAPED_RETURN = ESCAPED_RETURN + UNKNOWN_OFFSET
5061 : : ESCAPED_RETURN = *ESCAPED_RETURN. */
5062 : 4489616 : lhs.type = SCALAR;
5063 : 4489616 : lhs.var = escaped_return_id;
5064 : 4489616 : lhs.offset = 0;
5065 : 4489616 : rhs.type = SCALAR;
5066 : 4489616 : rhs.var = escaped_return_id;
5067 : 4489616 : rhs.offset = UNKNOWN_OFFSET;
5068 : 4489616 : process_constraint (new_constraint (lhs, rhs));
5069 : 4489616 : lhs.type = SCALAR;
5070 : 4489616 : lhs.var = escaped_return_id;
5071 : 4489616 : lhs.offset = 0;
5072 : 4489616 : rhs.type = DEREF;
5073 : 4489616 : rhs.var = escaped_return_id;
5074 : 4489616 : rhs.offset = 0;
5075 : 4489616 : process_constraint (new_constraint (lhs, rhs));
5076 : :
5077 : : /* Create the STOREDANYTHING variable, used to represent the set of
5078 : : variables stored to *ANYTHING. */
5079 : 4489616 : var_storedanything = new_var_info (NULL_TREE, "STOREDANYTHING", false);
5080 : 4489616 : gcc_assert (var_storedanything->id == storedanything_id);
5081 : 4489616 : var_storedanything->is_artificial_var = 1;
5082 : 4489616 : var_storedanything->offset = 0;
5083 : 4489616 : var_storedanything->size = ~0;
5084 : 4489616 : var_storedanything->fullsize = ~0;
5085 : 4489616 : var_storedanything->is_special_var = 0;
5086 : :
5087 : : /* Create the INTEGER variable, used to represent that a variable points
5088 : : to what an INTEGER "points to". */
5089 : 4489616 : var_integer = new_var_info (NULL_TREE, "INTEGER", false);
5090 : 4489616 : gcc_assert (var_integer->id == integer_id);
5091 : 4489616 : var_integer->is_artificial_var = 1;
5092 : 4489616 : var_integer->size = ~0;
5093 : 4489616 : var_integer->fullsize = ~0;
5094 : 4489616 : var_integer->offset = 0;
5095 : 4489616 : var_integer->is_special_var = 1;
5096 : :
5097 : : /* INTEGER = ANYTHING, because we don't know where a dereference of
5098 : : a random integer will point to. */
5099 : 4489616 : lhs.type = SCALAR;
5100 : 4489616 : lhs.var = integer_id;
5101 : 4489616 : lhs.offset = 0;
5102 : 4489616 : rhs.type = ADDRESSOF;
5103 : 4489616 : rhs.var = anything_id;
5104 : 4489616 : rhs.offset = 0;
5105 : 4489616 : process_constraint (new_constraint (lhs, rhs));
5106 : 4489616 : }
5107 : :
5108 : : /* Initialize things necessary to perform PTA. */
5109 : :
5110 : : static void
5111 : 4489616 : init_alias_vars (void)
5112 : : {
5113 : 4489616 : use_field_sensitive = (param_max_fields_for_field_sensitive > 1);
5114 : :
5115 : 4489616 : bitmap_obstack_initialize (&pta_obstack);
5116 : 4489616 : bitmap_obstack_initialize (&oldpta_obstack);
5117 : :
5118 : 4489616 : constraints.create (8);
5119 : 4489616 : varmap.create (8);
5120 : 4489616 : vi_for_tree = new hash_map<tree, varinfo_t>;
5121 : 4489616 : call_stmt_vars = new hash_map<gimple *, varinfo_t>;
5122 : :
5123 : 4489616 : memset (&stats, 0, sizeof (stats));
5124 : 4489616 : shared_bitmap_table = new hash_table<shared_bitmap_hasher> (511);
5125 : 4489616 : init_base_vars ();
5126 : :
5127 : 4489616 : gcc_obstack_init (&fake_var_decl_obstack);
5128 : :
5129 : 4489616 : final_solutions = new hash_map<varinfo_t, pt_solution *>;
5130 : 4489616 : gcc_obstack_init (&final_solutions_obstack);
5131 : 4489616 : }
5132 : :
5133 : : /* Create points-to sets for the current function. See the comments
5134 : : at the start of the file for an algorithmic overview. */
5135 : :
5136 : : static void
5137 : 4485192 : compute_points_to_sets (void)
5138 : : {
5139 : 4485192 : basic_block bb;
5140 : 4485192 : varinfo_t vi;
5141 : :
5142 : 4485192 : timevar_push (TV_TREE_PTA);
5143 : :
5144 : 4485192 : init_alias_vars ();
5145 : :
5146 : 4485192 : intra_create_variable_infos (cfun);
5147 : :
5148 : : /* Now walk all statements and build the constraint set. */
5149 : 39926891 : FOR_EACH_BB_FN (bb, cfun)
5150 : : {
5151 : 47549532 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
5152 : 12107833 : gsi_next (&gsi))
5153 : : {
5154 : 12107833 : gphi *phi = gsi.phi ();
5155 : :
5156 : 24215666 : if (! virtual_operand_p (gimple_phi_result (phi)))
5157 : 6303561 : find_func_aliases (cfun, phi);
5158 : : }
5159 : :
5160 : 323489284 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
5161 : 252605886 : gsi_next (&gsi))
5162 : : {
5163 : 252605886 : gimple *stmt = gsi_stmt (gsi);
5164 : :
5165 : 252605886 : find_func_aliases (cfun, stmt);
5166 : : }
5167 : : }
5168 : :
5169 : 4485192 : if (dump_file && (dump_flags & TDF_DETAILS))
5170 : : {
5171 : 282 : fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n");
5172 : 282 : dump_constraints (dump_file, 0);
5173 : : }
5174 : :
5175 : : /* From the constraints compute the points-to sets. */
5176 : 4485192 : solve_constraints ();
5177 : :
5178 : 4485192 : if (dump_file && (dump_flags & TDF_STATS))
5179 : 149 : dump_sa_stats (dump_file);
5180 : :
5181 : 4485192 : if (dump_file && (dump_flags & TDF_DETAILS))
5182 : 282 : dump_sa_points_to_info (dump_file);
5183 : :
5184 : : /* Compute the points-to set for ESCAPED used for call-clobber analysis. */
5185 : 4485192 : cfun->gimple_df->escaped = find_what_var_points_to (cfun->decl,
5186 : : get_varinfo (escaped_id));
5187 : :
5188 : : /* Make sure the ESCAPED solution (which is used as placeholder in
5189 : : other solutions) does not reference itself. This simplifies
5190 : : points-to solution queries. */
5191 : 4485192 : cfun->gimple_df->escaped.escaped = 0;
5192 : :
5193 : : /* The ESCAPED_RETURN solution is what contains all memory that needs
5194 : : to be considered global. */
5195 : 4485192 : cfun->gimple_df->escaped_return
5196 : 4485192 : = find_what_var_points_to (cfun->decl, get_varinfo (escaped_return_id));
5197 : 4485192 : cfun->gimple_df->escaped_return.escaped = 1;
5198 : :
5199 : : /* Compute the points-to sets for pointer SSA_NAMEs. */
5200 : 4485192 : unsigned i;
5201 : 4485192 : tree ptr;
5202 : :
5203 : 164091781 : FOR_EACH_SSA_NAME (i, ptr, cfun)
5204 : : {
5205 : 126009127 : if (POINTER_TYPE_P (TREE_TYPE (ptr)))
5206 : 24357109 : find_what_p_points_to (cfun->decl, ptr);
5207 : : }
5208 : :
5209 : : /* Compute the call-used/clobbered sets. */
5210 : 39926891 : FOR_EACH_BB_FN (bb, cfun)
5211 : : {
5212 : 35441699 : gimple_stmt_iterator gsi;
5213 : :
5214 : 323489284 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5215 : : {
5216 : 252605886 : gcall *stmt;
5217 : 252605886 : struct pt_solution *pt;
5218 : :
5219 : 252605886 : stmt = dyn_cast <gcall *> (gsi_stmt (gsi));
5220 : 252605886 : if (!stmt)
5221 : 235219401 : continue;
5222 : :
5223 : 17386485 : pt = gimple_call_use_set (stmt);
5224 : 17386485 : if (gimple_call_flags (stmt) & ECF_CONST)
5225 : 1577491 : memset (pt, 0, sizeof (struct pt_solution));
5226 : : else
5227 : : {
5228 : 15808994 : bool uses_global_memory = true;
5229 : 15808994 : bool reads_global_memory = true;
5230 : :
5231 : 15808994 : determine_global_memory_access (stmt, NULL,
5232 : : &reads_global_memory,
5233 : : &uses_global_memory);
5234 : 15808994 : if ((vi = lookup_call_use_vi (stmt)) != NULL)
5235 : : {
5236 : 14916431 : *pt = find_what_var_points_to (cfun->decl, vi);
5237 : : /* Escaped (and thus nonlocal) variables are always
5238 : : implicitly used by calls. */
5239 : : /* ??? ESCAPED can be empty even though NONLOCAL
5240 : : always escaped. */
5241 : 14916431 : if (uses_global_memory)
5242 : : {
5243 : 13434659 : pt->nonlocal = 1;
5244 : 13434659 : pt->escaped = 1;
5245 : : }
5246 : : }
5247 : 892563 : else if (uses_global_memory)
5248 : : {
5249 : : /* If there is nothing special about this call then
5250 : : we have made everything that is used also escape. */
5251 : 1809 : *pt = cfun->gimple_df->escaped;
5252 : 1809 : pt->nonlocal = 1;
5253 : : }
5254 : : else
5255 : 890754 : memset (pt, 0, sizeof (struct pt_solution));
5256 : : }
5257 : :
5258 : 17386485 : pt = gimple_call_clobber_set (stmt);
5259 : 17386485 : if (gimple_call_flags (stmt) & (ECF_CONST|ECF_PURE|ECF_NOVOPS))
5260 : 2862389 : memset (pt, 0, sizeof (struct pt_solution));
5261 : : else
5262 : : {
5263 : 14524096 : bool writes_global_memory = true;
5264 : :
5265 : 14524096 : determine_global_memory_access (stmt, &writes_global_memory,
5266 : : NULL, NULL);
5267 : :
5268 : 14524096 : if ((vi = lookup_call_clobber_vi (stmt)) != NULL)
5269 : : {
5270 : 13648130 : *pt = find_what_var_points_to (cfun->decl, vi);
5271 : : /* Escaped (and thus nonlocal) variables are always
5272 : : implicitly clobbered by calls. */
5273 : : /* ??? ESCAPED can be empty even though NONLOCAL
5274 : : always escaped. */
5275 : 13648130 : if (writes_global_memory)
5276 : : {
5277 : 12862402 : pt->nonlocal = 1;
5278 : 12862402 : pt->escaped = 1;
5279 : : }
5280 : : }
5281 : 875966 : else if (writes_global_memory)
5282 : : {
5283 : : /* If there is nothing special about this call then
5284 : : we have made everything that is used also escape. */
5285 : 484 : *pt = cfun->gimple_df->escaped;
5286 : 484 : pt->nonlocal = 1;
5287 : : }
5288 : : else
5289 : 875482 : memset (pt, 0, sizeof (struct pt_solution));
5290 : : }
5291 : : }
5292 : : }
5293 : :
5294 : 4485192 : timevar_pop (TV_TREE_PTA);
5295 : 4485192 : }
5296 : :
5297 : :
5298 : : /* Delete created points-to sets. */
5299 : :
5300 : : static void
5301 : 4489616 : delete_points_to_sets (void)
5302 : : {
5303 : 4489616 : delete shared_bitmap_table;
5304 : 4489616 : shared_bitmap_table = NULL;
5305 : 4489616 : if (dump_file && (dump_flags & TDF_STATS))
5306 : 149 : fprintf (dump_file, "Points to sets created:%d\n",
5307 : : stats.points_to_sets_created);
5308 : :
5309 : 8979232 : delete vi_for_tree;
5310 : 8979232 : delete call_stmt_vars;
5311 : 4489616 : bitmap_obstack_release (&pta_obstack);
5312 : 4489616 : constraints.release ();
5313 : :
5314 : 4489616 : free (var_rep);
5315 : :
5316 : 4489616 : varmap.release ();
5317 : 4489616 : variable_info_pool.release ();
5318 : 4489616 : constraint_pool.release ();
5319 : :
5320 : 4489616 : obstack_free (&fake_var_decl_obstack, NULL);
5321 : :
5322 : 8979232 : delete final_solutions;
5323 : 4489616 : obstack_free (&final_solutions_obstack, NULL);
5324 : 4489616 : }
5325 : :
5326 : : struct vls_data
5327 : : {
5328 : : unsigned short clique;
5329 : : bool escaped_p;
5330 : : bitmap rvars;
5331 : : };
5332 : :
5333 : : /* Mark "other" loads and stores as belonging to CLIQUE and with
5334 : : base zero. */
5335 : :
5336 : : static bool
5337 : 4498781 : visit_loadstore (gimple *, tree base, tree ref, void *data)
5338 : : {
5339 : 4498781 : unsigned short clique = ((vls_data *) data)->clique;
5340 : 4498781 : bitmap rvars = ((vls_data *) data)->rvars;
5341 : 4498781 : bool escaped_p = ((vls_data *) data)->escaped_p;
5342 : 4498781 : if (TREE_CODE (base) == MEM_REF
5343 : 4498781 : || TREE_CODE (base) == TARGET_MEM_REF)
5344 : : {
5345 : 3319358 : tree ptr = TREE_OPERAND (base, 0);
5346 : 3319358 : if (TREE_CODE (ptr) == SSA_NAME)
5347 : : {
5348 : : /* For parameters, get at the points-to set for the actual parm
5349 : : decl. */
5350 : 3145520 : if (SSA_NAME_IS_DEFAULT_DEF (ptr)
5351 : 3145520 : && (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL
5352 : 62 : || TREE_CODE (SSA_NAME_VAR (ptr)) == RESULT_DECL))
5353 : 2288319 : ptr = SSA_NAME_VAR (ptr);
5354 : :
5355 : : /* We need to make sure 'ptr' doesn't include any of
5356 : : the restrict tags we added bases for in its points-to set. */
5357 : 3145520 : varinfo_t vi = lookup_vi_for_tree (ptr);
5358 : 3145520 : if (! vi)
5359 : : return false;
5360 : :
5361 : 3145458 : vi = get_varinfo (var_rep[vi->id]);
5362 : 3145458 : if (bitmap_intersect_p (rvars, vi->solution)
5363 : 3145458 : || (escaped_p && bitmap_bit_p (vi->solution, escaped_id)))
5364 : 2274984 : return false;
5365 : : }
5366 : :
5367 : : /* Do not overwrite existing cliques (that includes clique, base
5368 : : pairs we just set). */
5369 : 1044312 : if (MR_DEPENDENCE_CLIQUE (base) == 0)
5370 : : {
5371 : 877940 : MR_DEPENDENCE_CLIQUE (base) = clique;
5372 : 877940 : MR_DEPENDENCE_BASE (base) = 0;
5373 : : }
5374 : : }
5375 : :
5376 : : /* For plain decl accesses see whether they are accesses to globals
5377 : : and rewrite them to MEM_REFs with { clique, 0 }. */
5378 : 2223735 : if (VAR_P (base)
5379 : 1146606 : && is_global_var (base)
5380 : : /* ??? We can't rewrite a plain decl with the walk_stmt_load_store
5381 : : ops callback. */
5382 : 2281921 : && base != ref)
5383 : : {
5384 : : tree *basep = &ref;
5385 : 88508 : while (handled_component_p (*basep))
5386 : 56123 : basep = &TREE_OPERAND (*basep, 0);
5387 : 32385 : gcc_assert (VAR_P (*basep));
5388 : 32385 : tree ptr = build_fold_addr_expr (*basep);
5389 : 32385 : tree zero = build_int_cst (TREE_TYPE (ptr), 0);
5390 : 32385 : *basep = build2 (MEM_REF, TREE_TYPE (*basep), ptr, zero);
5391 : 32385 : MR_DEPENDENCE_CLIQUE (*basep) = clique;
5392 : 32385 : MR_DEPENDENCE_BASE (*basep) = 0;
5393 : : }
5394 : :
5395 : : return false;
5396 : : }
5397 : :
5398 : : struct msdi_data {
5399 : : tree ptr;
5400 : : unsigned short *clique;
5401 : : unsigned short *last_ruid;
5402 : : varinfo_t restrict_var;
5403 : : };
5404 : :
5405 : : /* If BASE is a MEM_REF then assign a clique, base pair to it, updating
5406 : : CLIQUE, *RESTRICT_VAR and LAST_RUID as passed via DATA.
5407 : : Return whether dependence info was assigned to BASE. */
5408 : :
5409 : : static bool
5410 : 2323593 : maybe_set_dependence_info (gimple *, tree base, tree, void *data)
5411 : : {
5412 : 2323593 : tree ptr = ((msdi_data *)data)->ptr;
5413 : 2323593 : unsigned short &clique = *((msdi_data *)data)->clique;
5414 : 2323593 : unsigned short &last_ruid = *((msdi_data *)data)->last_ruid;
5415 : 2323593 : varinfo_t restrict_var = ((msdi_data *)data)->restrict_var;
5416 : 2323593 : if ((TREE_CODE (base) == MEM_REF
5417 : 2323593 : || TREE_CODE (base) == TARGET_MEM_REF)
5418 : 2323593 : && TREE_OPERAND (base, 0) == ptr)
5419 : : {
5420 : : /* Do not overwrite existing cliques. This avoids overwriting dependence
5421 : : info inlined from a function with restrict parameters inlined
5422 : : into a function with restrict parameters. This usually means we
5423 : : prefer to be precise in innermost loops. */
5424 : 2194397 : if (MR_DEPENDENCE_CLIQUE (base) == 0)
5425 : : {
5426 : 1670848 : if (clique == 0)
5427 : : {
5428 : 367167 : if (cfun->last_clique == 0)
5429 : 167766 : cfun->last_clique = 1;
5430 : 367167 : clique = 1;
5431 : : }
5432 : 1670848 : if (restrict_var->ruid == 0)
5433 : 453925 : restrict_var->ruid = ++last_ruid;
5434 : 1670848 : MR_DEPENDENCE_CLIQUE (base) = clique;
5435 : 1670848 : MR_DEPENDENCE_BASE (base) = restrict_var->ruid;
5436 : 1670848 : return true;
5437 : : }
5438 : : }
5439 : : return false;
5440 : : }
5441 : :
5442 : : /* Clear dependence info for the clique DATA. */
5443 : :
5444 : : static bool
5445 : 18719116 : clear_dependence_clique (gimple *, tree base, tree, void *data)
5446 : : {
5447 : 18719116 : unsigned short clique = (uintptr_t)data;
5448 : 18719116 : if ((TREE_CODE (base) == MEM_REF
5449 : 18719116 : || TREE_CODE (base) == TARGET_MEM_REF)
5450 : 18719116 : && MR_DEPENDENCE_CLIQUE (base) == clique)
5451 : : {
5452 : 1062376 : MR_DEPENDENCE_CLIQUE (base) = 0;
5453 : 1062376 : MR_DEPENDENCE_BASE (base) = 0;
5454 : : }
5455 : :
5456 : 18719116 : return false;
5457 : : }
5458 : :
5459 : : /* Compute the set of independend memory references based on restrict
5460 : : tags and their conservative propagation to the points-to sets. */
5461 : :
5462 : : static void
5463 : 4485192 : compute_dependence_clique (void)
5464 : : {
5465 : : /* First clear the special "local" clique. */
5466 : 4485192 : basic_block bb;
5467 : 4485192 : if (cfun->last_clique != 0)
5468 : 10920379 : FOR_EACH_BB_FN (bb, cfun)
5469 : 20742904 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
5470 : 141805084 : !gsi_end_p (gsi); gsi_next (&gsi))
5471 : : {
5472 : 131433632 : gimple *stmt = gsi_stmt (gsi);
5473 : 131433632 : walk_stmt_load_store_ops (stmt, (void *)(uintptr_t) 1,
5474 : : clear_dependence_clique,
5475 : : clear_dependence_clique);
5476 : : }
5477 : :
5478 : 4485192 : unsigned short clique = 0;
5479 : 4485192 : unsigned short last_ruid = 0;
5480 : 4485192 : bitmap rvars = BITMAP_ALLOC (NULL);
5481 : 4485192 : bool escaped_p = false;
5482 : 168576973 : for (unsigned i = 0; i < num_ssa_names; ++i)
5483 : : {
5484 : 164091781 : tree ptr = ssa_name (i);
5485 : 164091781 : if (!ptr || !POINTER_TYPE_P (TREE_TYPE (ptr)))
5486 : 140703715 : continue;
5487 : :
5488 : : /* Avoid all this when ptr is not dereferenced? */
5489 : 24357109 : tree p = ptr;
5490 : 24357109 : if (SSA_NAME_IS_DEFAULT_DEF (ptr)
5491 : 24357109 : && (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL
5492 : 938768 : || TREE_CODE (SSA_NAME_VAR (ptr)) == RESULT_DECL))
5493 : 4295083 : p = SSA_NAME_VAR (ptr);
5494 : 24357109 : varinfo_t vi = lookup_vi_for_tree (p);
5495 : 24357109 : if (!vi)
5496 : 969043 : continue;
5497 : 23388066 : vi = get_varinfo (var_rep[vi->id]);
5498 : 23388066 : bitmap_iterator bi;
5499 : 23388066 : unsigned j;
5500 : 23388066 : varinfo_t restrict_var = NULL;
5501 : 29396862 : EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi)
5502 : : {
5503 : 28100795 : varinfo_t oi = get_varinfo (j);
5504 : 28100795 : if (oi->head != j)
5505 : 1008066 : oi = get_varinfo (oi->head);
5506 : 28100795 : if (oi->is_restrict_var)
5507 : : {
5508 : 1861095 : if (restrict_var
5509 : 1861095 : && restrict_var != oi)
5510 : : {
5511 : 40 : if (dump_file && (dump_flags & TDF_DETAILS))
5512 : : {
5513 : 0 : fprintf (dump_file, "found restrict pointed-to "
5514 : : "for ");
5515 : 0 : print_generic_expr (dump_file, ptr);
5516 : 0 : fprintf (dump_file, " but not exclusively\n");
5517 : : }
5518 : : restrict_var = NULL;
5519 : : break;
5520 : : }
5521 : : restrict_var = oi;
5522 : : }
5523 : : /* NULL is the only other valid points-to entry. */
5524 : 26239700 : else if (oi->id != nothing_id)
5525 : : {
5526 : : restrict_var = NULL;
5527 : : break;
5528 : : }
5529 : : }
5530 : : /* Ok, found that ptr must(!) point to a single(!) restrict
5531 : : variable. */
5532 : : /* ??? PTA isn't really a proper propagation engine to compute
5533 : : this property.
5534 : : ??? We could handle merging of two restricts by unifying them. */
5535 : 23388026 : if (restrict_var)
5536 : : {
5537 : : /* Now look at possible dereferences of ptr. */
5538 : 862777 : imm_use_iterator ui;
5539 : 862777 : gimple *use_stmt;
5540 : 862777 : bool used = false;
5541 : 862777 : msdi_data data = { ptr, &clique, &last_ruid, restrict_var };
5542 : 4193085 : FOR_EACH_IMM_USE_STMT (use_stmt, ui, ptr)
5543 : 3330308 : used |= walk_stmt_load_store_ops (use_stmt, &data,
5544 : : maybe_set_dependence_info,
5545 : 862777 : maybe_set_dependence_info);
5546 : 862777 : if (used)
5547 : : {
5548 : : /* Add all subvars to the set of restrict pointed-to set. */
5549 : 2661948 : for (unsigned sv = restrict_var->head; sv != 0;
5550 : 1084262 : sv = get_varinfo (sv)->next)
5551 : 1084262 : bitmap_set_bit (rvars, sv);
5552 : 493424 : varinfo_t escaped = get_varinfo (var_rep[escaped_id]);
5553 : 493424 : if (bitmap_bit_p (escaped->solution, restrict_var->id))
5554 : 862777 : escaped_p = true;
5555 : : }
5556 : : }
5557 : : }
5558 : :
5559 : 4485192 : if (clique != 0)
5560 : : {
5561 : : /* Assign the BASE id zero to all accesses not based on a restrict
5562 : : pointer. That way they get disambiguated against restrict
5563 : : accesses but not against each other. */
5564 : : /* ??? For restricts derived from globals (thus not incoming
5565 : : parameters) we can't restrict scoping properly thus the following
5566 : : is too aggressive there. For now we have excluded those globals from
5567 : : getting into the MR_DEPENDENCE machinery. */
5568 : 367167 : vls_data data = { clique, escaped_p, rvars };
5569 : 367167 : basic_block bb;
5570 : 2979887 : FOR_EACH_BB_FN (bb, cfun)
5571 : 5225440 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
5572 : 21147234 : !gsi_end_p (gsi); gsi_next (&gsi))
5573 : : {
5574 : 18534514 : gimple *stmt = gsi_stmt (gsi);
5575 : 18534514 : walk_stmt_load_store_ops (stmt, &data,
5576 : : visit_loadstore, visit_loadstore);
5577 : : }
5578 : : }
5579 : :
5580 : 4485192 : BITMAP_FREE (rvars);
5581 : 4485192 : }
5582 : :
5583 : : /* Compute points-to information for every SSA_NAME pointer in the
5584 : : current function and compute the transitive closure of escaped
5585 : : variables to re-initialize the call-clobber states of local variables. */
5586 : :
5587 : : unsigned int
5588 : 4511779 : compute_may_aliases (void)
5589 : : {
5590 : 4511779 : if (cfun->gimple_df->ipa_pta)
5591 : : {
5592 : 26587 : if (dump_file)
5593 : : {
5594 : 0 : fprintf (dump_file, "\nNot re-computing points-to information "
5595 : : "because IPA points-to information is available.\n\n");
5596 : :
5597 : : /* But still dump what we have remaining it. */
5598 : 0 : if (dump_flags & (TDF_DETAILS|TDF_ALIAS))
5599 : 0 : dump_alias_info (dump_file);
5600 : : }
5601 : :
5602 : 26587 : return 0;
5603 : : }
5604 : :
5605 : : /* For each pointer P_i, determine the sets of variables that P_i may
5606 : : point-to. Compute the reachability set of escaped and call-used
5607 : : variables. */
5608 : 4485192 : compute_points_to_sets ();
5609 : :
5610 : : /* Debugging dumps. */
5611 : 4485192 : if (dump_file && (dump_flags & (TDF_DETAILS|TDF_ALIAS)))
5612 : 282 : dump_alias_info (dump_file);
5613 : :
5614 : : /* Compute restrict-based memory disambiguations. */
5615 : 4485192 : compute_dependence_clique ();
5616 : :
5617 : : /* Deallocate memory used by aliasing data structures and the internal
5618 : : points-to solution. */
5619 : 4485192 : delete_points_to_sets ();
5620 : :
5621 : 4485192 : gcc_assert (!need_ssa_update_p (cfun));
5622 : :
5623 : : return 0;
5624 : : }
5625 : :
5626 : : /* A dummy pass to cause points-to information to be computed via
5627 : : TODO_rebuild_alias. */
5628 : :
5629 : : namespace {
5630 : :
5631 : : const pass_data pass_data_build_alias =
5632 : : {
5633 : : GIMPLE_PASS, /* type */
5634 : : "alias", /* name */
5635 : : OPTGROUP_NONE, /* optinfo_flags */
5636 : : TV_NONE, /* tv_id */
5637 : : ( PROP_cfg | PROP_ssa ), /* properties_required */
5638 : : 0, /* properties_provided */
5639 : : 0, /* properties_destroyed */
5640 : : 0, /* todo_flags_start */
5641 : : TODO_rebuild_alias, /* todo_flags_finish */
5642 : : };
5643 : :
5644 : : class pass_build_alias : public gimple_opt_pass
5645 : : {
5646 : : public:
5647 : 281414 : pass_build_alias (gcc::context *ctxt)
5648 : 562828 : : gimple_opt_pass (pass_data_build_alias, ctxt)
5649 : : {}
5650 : :
5651 : : /* opt_pass methods: */
5652 : 1033487 : bool gate (function *) final override { return flag_tree_pta; }
5653 : :
5654 : : }; // class pass_build_alias
5655 : :
5656 : : } // anon namespace
5657 : :
5658 : : gimple_opt_pass *
5659 : 281414 : make_pass_build_alias (gcc::context *ctxt)
5660 : : {
5661 : 281414 : return new pass_build_alias (ctxt);
5662 : : }
5663 : :
5664 : : /* A dummy pass to cause points-to information to be computed via
5665 : : TODO_rebuild_alias. */
5666 : :
5667 : : namespace {
5668 : :
5669 : : const pass_data pass_data_build_ealias =
5670 : : {
5671 : : GIMPLE_PASS, /* type */
5672 : : "ealias", /* name */
5673 : : OPTGROUP_NONE, /* optinfo_flags */
5674 : : TV_NONE, /* tv_id */
5675 : : ( PROP_cfg | PROP_ssa ), /* properties_required */
5676 : : 0, /* properties_provided */
5677 : : 0, /* properties_destroyed */
5678 : : 0, /* todo_flags_start */
5679 : : TODO_rebuild_alias, /* todo_flags_finish */
5680 : : };
5681 : :
5682 : : class pass_build_ealias : public gimple_opt_pass
5683 : : {
5684 : : public:
5685 : 281414 : pass_build_ealias (gcc::context *ctxt)
5686 : 562828 : : gimple_opt_pass (pass_data_build_ealias, ctxt)
5687 : : {}
5688 : :
5689 : : /* opt_pass methods: */
5690 : 2498360 : bool gate (function *) final override { return flag_tree_pta; }
5691 : :
5692 : : }; // class pass_build_ealias
5693 : :
5694 : : } // anon namespace
5695 : :
5696 : : gimple_opt_pass *
5697 : 281414 : make_pass_build_ealias (gcc::context *ctxt)
5698 : : {
5699 : 281414 : return new pass_build_ealias (ctxt);
5700 : : }
5701 : :
5702 : :
5703 : : /* IPA PTA solutions for ESCAPED. */
5704 : : struct pt_solution ipa_escaped_pt
5705 : : = { true, false, false, false, false, false,
5706 : : false, false, false, false, false, NULL };
5707 : :
5708 : : /* Associate node with varinfo DATA. Worker for
5709 : : cgraph_for_symbol_thunks_and_aliases. */
5710 : : static bool
5711 : 23505 : associate_varinfo_to_alias (struct cgraph_node *node, void *data)
5712 : : {
5713 : 23505 : if ((node->alias
5714 : 23452 : || (node->thunk
5715 : 3 : && ! node->inlined_to))
5716 : 53 : && node->analyzed
5717 : 53 : && !node->ifunc_resolver)
5718 : 52 : insert_vi_for_tree (node->decl, (varinfo_t)data);
5719 : 23505 : return false;
5720 : : }
5721 : :
5722 : : /* Compute whether node is refered to non-locally. Worker for
5723 : : cgraph_for_symbol_thunks_and_aliases. */
5724 : : static bool
5725 : 23505 : refered_from_nonlocal_fn (struct cgraph_node *node, void *data)
5726 : : {
5727 : 23505 : bool *nonlocal_p = (bool *)data;
5728 : 47010 : *nonlocal_p |= (node->used_from_other_partition
5729 : 23459 : || DECL_EXTERNAL (node->decl)
5730 : 23454 : || TREE_PUBLIC (node->decl)
5731 : 16473 : || node->force_output
5732 : 39968 : || lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)));
5733 : 23505 : return false;
5734 : : }
5735 : :
5736 : : /* Same for varpool nodes. */
5737 : : static bool
5738 : 36901 : refered_from_nonlocal_var (struct varpool_node *node, void *data)
5739 : : {
5740 : 36901 : bool *nonlocal_p = (bool *)data;
5741 : 73802 : *nonlocal_p |= (node->used_from_other_partition
5742 : 36800 : || DECL_EXTERNAL (node->decl)
5743 : 36314 : || TREE_PUBLIC (node->decl)
5744 : 72153 : || node->force_output);
5745 : 36901 : return false;
5746 : : }
5747 : :
5748 : : /* Execute the driver for IPA PTA. */
5749 : : static unsigned int
5750 : 4424 : ipa_pta_execute (void)
5751 : : {
5752 : 4424 : struct cgraph_node *node;
5753 : 4424 : varpool_node *var;
5754 : 4424 : unsigned int from = 0;
5755 : :
5756 : 4424 : in_ipa_mode = 1;
5757 : :
5758 : 4424 : init_alias_vars ();
5759 : :
5760 : 4424 : if (dump_file && (dump_flags & TDF_DETAILS))
5761 : : {
5762 : 17 : symtab->dump (dump_file);
5763 : 17 : fprintf (dump_file, "\n");
5764 : : }
5765 : :
5766 : 4424 : if (dump_file && (dump_flags & TDF_DETAILS))
5767 : : {
5768 : 17 : fprintf (dump_file, "Generating generic constraints\n\n");
5769 : 17 : dump_constraints (dump_file, from);
5770 : 17 : fprintf (dump_file, "\n");
5771 : 17 : from = constraints.length ();
5772 : : }
5773 : :
5774 : : /* Build the constraints. */
5775 : 29124 : FOR_EACH_DEFINED_FUNCTION (node)
5776 : : {
5777 : 24700 : varinfo_t vi;
5778 : : /* Nodes without a body in this partition are not interesting.
5779 : : Especially do not visit clones at this point for now - we
5780 : : get duplicate decls there for inline clones at least. */
5781 : 25951 : if (!node->has_gimple_body_p ()
5782 : 24599 : || node->in_other_partition
5783 : 49299 : || node->inlined_to)
5784 : 1251 : continue;
5785 : 23449 : node->get_body ();
5786 : :
5787 : 23449 : gcc_assert (!node->clone_of);
5788 : :
5789 : : /* For externally visible or attribute used annotated functions use
5790 : : local constraints for their arguments.
5791 : : For local functions we see all callers and thus do not need initial
5792 : : constraints for parameters. */
5793 : 23449 : bool nonlocal_p = (node->used_from_other_partition
5794 : 23403 : || DECL_EXTERNAL (node->decl)
5795 : 23399 : || TREE_PUBLIC (node->decl)
5796 : 16469 : || node->force_output
5797 : 39908 : || lookup_attribute ("noipa",
5798 : 16459 : DECL_ATTRIBUTES (node->decl)));
5799 : 23449 : node->call_for_symbol_thunks_and_aliases (refered_from_nonlocal_fn,
5800 : : &nonlocal_p, true);
5801 : :
5802 : 23449 : vi = create_function_info_for (node->decl,
5803 : : alias_get_name (node->decl), false,
5804 : : nonlocal_p);
5805 : 54 : if (dump_file && (dump_flags & TDF_DETAILS)
5806 : 23501 : && from != constraints.length ())
5807 : : {
5808 : 22 : fprintf (dump_file,
5809 : : "Generating initial constraints for %s",
5810 : : node->dump_name ());
5811 : 22 : if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
5812 : 44 : fprintf (dump_file, " (%s)",
5813 : 22 : IDENTIFIER_POINTER
5814 : : (DECL_ASSEMBLER_NAME (node->decl)));
5815 : 22 : fprintf (dump_file, "\n\n");
5816 : 22 : dump_constraints (dump_file, from);
5817 : 22 : fprintf (dump_file, "\n");
5818 : :
5819 : 22 : from = constraints.length ();
5820 : : }
5821 : :
5822 : 23449 : node->call_for_symbol_thunks_and_aliases
5823 : 23449 : (associate_varinfo_to_alias, vi, true);
5824 : : }
5825 : :
5826 : : /* Create constraints for global variables and their initializers. */
5827 : 82650 : FOR_EACH_VARIABLE (var)
5828 : : {
5829 : 36901 : if (var->alias && var->analyzed)
5830 : 17 : continue;
5831 : :
5832 : 36884 : varinfo_t vi = get_vi_for_tree (var->decl);
5833 : :
5834 : : /* For the purpose of IPA PTA unit-local globals are not
5835 : : escape points. */
5836 : 36884 : bool nonlocal_p = (DECL_EXTERNAL (var->decl)
5837 : 36398 : || TREE_PUBLIC (var->decl)
5838 : 35236 : || var->used_from_other_partition
5839 : 72120 : || var->force_output);
5840 : 36884 : var->call_for_symbol_and_aliases (refered_from_nonlocal_var,
5841 : : &nonlocal_p, true);
5842 : 36884 : if (nonlocal_p)
5843 : 1653 : vi->is_ipa_escape_point = true;
5844 : : }
5845 : :
5846 : 19 : if (dump_file && (dump_flags & TDF_DETAILS)
5847 : 4441 : && from != constraints.length ())
5848 : : {
5849 : 11 : fprintf (dump_file,
5850 : : "Generating constraints for global initializers\n\n");
5851 : 11 : dump_constraints (dump_file, from);
5852 : 11 : fprintf (dump_file, "\n");
5853 : 11 : from = constraints.length ();
5854 : : }
5855 : :
5856 : 27926 : FOR_EACH_DEFINED_FUNCTION (node)
5857 : : {
5858 : 23502 : struct function *func;
5859 : 23502 : basic_block bb;
5860 : :
5861 : : /* Nodes without a body in this partition are not interesting. */
5862 : 23555 : if (!node->has_gimple_body_p ()
5863 : 23449 : || node->in_other_partition
5864 : 46951 : || node->clone_of)
5865 : 53 : continue;
5866 : :
5867 : 23449 : if (dump_file && (dump_flags & TDF_DETAILS))
5868 : : {
5869 : 52 : fprintf (dump_file,
5870 : : "Generating constraints for %s", node->dump_name ());
5871 : 52 : if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
5872 : 104 : fprintf (dump_file, " (%s)",
5873 : 52 : IDENTIFIER_POINTER
5874 : : (DECL_ASSEMBLER_NAME (node->decl)));
5875 : 52 : fprintf (dump_file, "\n");
5876 : : }
5877 : :
5878 : 23449 : func = DECL_STRUCT_FUNCTION (node->decl);
5879 : 23449 : gcc_assert (cfun == NULL);
5880 : :
5881 : : /* Build constriants for the function body. */
5882 : 355106 : FOR_EACH_BB_FN (bb, func)
5883 : : {
5884 : 438900 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
5885 : 107243 : gsi_next (&gsi))
5886 : : {
5887 : 107243 : gphi *phi = gsi.phi ();
5888 : :
5889 : 214486 : if (! virtual_operand_p (gimple_phi_result (phi)))
5890 : 63816 : find_func_aliases (func, phi);
5891 : : }
5892 : :
5893 : 1619518 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
5894 : 956204 : gsi_next (&gsi))
5895 : : {
5896 : 956204 : gimple *stmt = gsi_stmt (gsi);
5897 : :
5898 : 956204 : find_func_aliases (func, stmt);
5899 : 956204 : find_func_clobbers (func, stmt);
5900 : : }
5901 : : }
5902 : :
5903 : 23449 : if (dump_file && (dump_flags & TDF_DETAILS))
5904 : : {
5905 : 52 : fprintf (dump_file, "\n");
5906 : 52 : dump_constraints (dump_file, from);
5907 : 52 : fprintf (dump_file, "\n");
5908 : 23554 : from = constraints.length ();
5909 : : }
5910 : : }
5911 : :
5912 : : /* From the constraints compute the points-to sets. */
5913 : 4424 : solve_constraints ();
5914 : :
5915 : 4424 : if (dump_file && (dump_flags & TDF_STATS))
5916 : 0 : dump_sa_stats (dump_file);
5917 : :
5918 : 4424 : if (dump_file && (dump_flags & TDF_DETAILS))
5919 : 17 : dump_sa_points_to_info (dump_file);
5920 : :
5921 : : /* Now post-process solutions to handle locals from different
5922 : : runtime instantiations coming in through recursive invocations. */
5923 : : unsigned shadow_var_cnt = 0;
5924 : 1195756 : for (unsigned i = 1; i < varmap.length (); ++i)
5925 : : {
5926 : 1191332 : varinfo_t fi = get_varinfo (i);
5927 : 1191332 : if (fi->is_fn_info
5928 : 23449 : && fi->decl)
5929 : : /* Automatic variables pointed to by their containing functions
5930 : : parameters need this treatment. */
5931 : 23449 : for (varinfo_t ai = first_vi_for_offset (fi, fi_parm_base);
5932 : 48632 : ai; ai = vi_next (ai))
5933 : : {
5934 : 25183 : varinfo_t vi = get_varinfo (var_rep[ai->id]);
5935 : 25183 : bitmap_iterator bi;
5936 : 25183 : unsigned j;
5937 : 67258 : EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi)
5938 : : {
5939 : 42075 : varinfo_t pt = get_varinfo (j);
5940 : 42075 : if (pt->shadow_var_uid == 0
5941 : 40775 : && pt->decl
5942 : 58355 : && auto_var_in_fn_p (pt->decl, fi->decl))
5943 : : {
5944 : 56 : pt->shadow_var_uid = allocate_decl_uid ();
5945 : 56 : shadow_var_cnt++;
5946 : : }
5947 : : }
5948 : : }
5949 : : /* As well as global variables which are another way of passing
5950 : : arguments to recursive invocations. */
5951 : 1167883 : else if (fi->is_global_var)
5952 : : {
5953 : 832077 : for (varinfo_t ai = fi; ai; ai = vi_next (ai))
5954 : : {
5955 : 443018 : varinfo_t vi = get_varinfo (var_rep[ai->id]);
5956 : 443018 : bitmap_iterator bi;
5957 : 443018 : unsigned j;
5958 : 1797156 : EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi)
5959 : : {
5960 : 1354138 : varinfo_t pt = get_varinfo (j);
5961 : 1354138 : if (pt->shadow_var_uid == 0
5962 : 1081266 : && pt->decl
5963 : 1507728 : && auto_var_p (pt->decl))
5964 : : {
5965 : 39653 : pt->shadow_var_uid = allocate_decl_uid ();
5966 : 39653 : shadow_var_cnt++;
5967 : : }
5968 : : }
5969 : : }
5970 : : }
5971 : : }
5972 : 4424 : if (shadow_var_cnt && dump_file && (dump_flags & TDF_DETAILS))
5973 : 10 : fprintf (dump_file, "Allocated %u shadow variables for locals "
5974 : : "maybe leaking into recursive invocations of their containing "
5975 : : "functions\n", shadow_var_cnt);
5976 : :
5977 : : /* Compute the global points-to sets for ESCAPED.
5978 : : ??? Note that the computed escape set is not correct
5979 : : for the whole unit as we fail to consider graph edges to
5980 : : externally visible functions. */
5981 : 4424 : ipa_escaped_pt = find_what_var_points_to (NULL, get_varinfo (escaped_id));
5982 : :
5983 : : /* Make sure the ESCAPED solution (which is used as placeholder in
5984 : : other solutions) does not reference itself. This simplifies
5985 : : points-to solution queries. */
5986 : 4424 : ipa_escaped_pt.ipa_escaped = 0;
5987 : :
5988 : : /* Assign the points-to sets to the SSA names in the unit. */
5989 : 27926 : FOR_EACH_DEFINED_FUNCTION (node)
5990 : : {
5991 : 23502 : tree ptr;
5992 : 23502 : struct function *fn;
5993 : 23502 : unsigned i;
5994 : 23502 : basic_block bb;
5995 : :
5996 : : /* Nodes without a body in this partition are not interesting. */
5997 : 23555 : if (!node->has_gimple_body_p ()
5998 : 23449 : || node->in_other_partition
5999 : 46951 : || node->clone_of)
6000 : 53 : continue;
6001 : :
6002 : 23449 : fn = DECL_STRUCT_FUNCTION (node->decl);
6003 : :
6004 : : /* Compute the points-to sets for pointer SSA_NAMEs. */
6005 : 1139786 : FOR_EACH_VEC_ELT (*fn->gimple_df->ssa_names, i, ptr)
6006 : : {
6007 : 1116337 : if (ptr
6008 : 1116337 : && POINTER_TYPE_P (TREE_TYPE (ptr)))
6009 : 107109 : find_what_p_points_to (node->decl, ptr);
6010 : : }
6011 : :
6012 : : /* Compute the call-use and call-clobber sets for indirect calls
6013 : : and calls to external functions. */
6014 : 355106 : FOR_EACH_BB_FN (bb, fn)
6015 : : {
6016 : 331657 : gimple_stmt_iterator gsi;
6017 : :
6018 : 1619518 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
6019 : : {
6020 : 956204 : gcall *stmt;
6021 : 956204 : struct pt_solution *pt;
6022 : 956204 : varinfo_t vi, fi;
6023 : 956204 : tree decl;
6024 : :
6025 : 956204 : stmt = dyn_cast <gcall *> (gsi_stmt (gsi));
6026 : 956204 : if (!stmt)
6027 : 702518 : continue;
6028 : :
6029 : : /* Handle direct calls to functions with body. */
6030 : 253686 : decl = gimple_call_fndecl (stmt);
6031 : :
6032 : 253686 : {
6033 : 253686 : tree called_decl = NULL_TREE;
6034 : 253686 : if (gimple_call_builtin_p (stmt, BUILT_IN_GOMP_PARALLEL))
6035 : 13 : called_decl = TREE_OPERAND (gimple_call_arg (stmt, 0), 0);
6036 : 253673 : else if (gimple_call_builtin_p (stmt, BUILT_IN_GOACC_PARALLEL))
6037 : 13785 : called_decl = TREE_OPERAND (gimple_call_arg (stmt, 1), 0);
6038 : :
6039 : 13798 : if (called_decl != NULL_TREE
6040 : 13798 : && !fndecl_maybe_in_other_partition (called_decl))
6041 : : decl = called_decl;
6042 : : }
6043 : :
6044 : 253686 : if (decl
6045 : 77277 : && (fi = lookup_vi_for_tree (decl))
6046 : 327898 : && fi->is_fn_info)
6047 : : {
6048 : 39668 : *gimple_call_clobber_set (stmt)
6049 : 19834 : = find_what_var_points_to
6050 : 19834 : (node->decl, first_vi_for_offset (fi, fi_clobbers));
6051 : 39668 : *gimple_call_use_set (stmt)
6052 : 19834 : = find_what_var_points_to
6053 : 19834 : (node->decl, first_vi_for_offset (fi, fi_uses));
6054 : : }
6055 : : /* Handle direct calls to external functions. */
6056 : 233852 : else if (decl && (!fi || fi->decl))
6057 : : {
6058 : 57442 : pt = gimple_call_use_set (stmt);
6059 : 57442 : if (gimple_call_flags (stmt) & ECF_CONST)
6060 : 1524 : memset (pt, 0, sizeof (struct pt_solution));
6061 : 55918 : else if ((vi = lookup_call_use_vi (stmt)) != NULL)
6062 : : {
6063 : 52591 : *pt = find_what_var_points_to (node->decl, vi);
6064 : : /* Escaped (and thus nonlocal) variables are always
6065 : : implicitly used by calls. */
6066 : : /* ??? ESCAPED can be empty even though NONLOCAL
6067 : : always escaped. */
6068 : 52591 : pt->nonlocal = 1;
6069 : 52591 : pt->ipa_escaped = 1;
6070 : : }
6071 : : else
6072 : : {
6073 : : /* If there is nothing special about this call then
6074 : : we have made everything that is used also escape. */
6075 : 3327 : *pt = ipa_escaped_pt;
6076 : 3327 : pt->nonlocal = 1;
6077 : : }
6078 : :
6079 : 57442 : pt = gimple_call_clobber_set (stmt);
6080 : 57442 : if (gimple_call_flags (stmt) &
6081 : : (ECF_CONST|ECF_PURE|ECF_NOVOPS))
6082 : 1775 : memset (pt, 0, sizeof (struct pt_solution));
6083 : 55667 : else if ((vi = lookup_call_clobber_vi (stmt)) != NULL)
6084 : : {
6085 : 52356 : *pt = find_what_var_points_to (node->decl, vi);
6086 : : /* Escaped (and thus nonlocal) variables are always
6087 : : implicitly clobbered by calls. */
6088 : : /* ??? ESCAPED can be empty even though NONLOCAL
6089 : : always escaped. */
6090 : 52356 : pt->nonlocal = 1;
6091 : 52356 : pt->ipa_escaped = 1;
6092 : : }
6093 : : else
6094 : : {
6095 : : /* If there is nothing special about this call then
6096 : : we have made everything that is used also escape. */
6097 : 3311 : *pt = ipa_escaped_pt;
6098 : 3311 : pt->nonlocal = 1;
6099 : : }
6100 : : }
6101 : : /* Handle indirect calls. */
6102 : 176410 : else if ((fi = get_fi_for_callee (stmt)))
6103 : : {
6104 : : /* We need to accumulate all clobbers/uses of all possible
6105 : : callees. */
6106 : 176410 : fi = get_varinfo (var_rep[fi->id]);
6107 : : /* If we cannot constrain the set of functions we'll end up
6108 : : calling we end up using/clobbering everything. */
6109 : 176410 : if (bitmap_bit_p (fi->solution, anything_id)
6110 : 677 : || bitmap_bit_p (fi->solution, nonlocal_id)
6111 : 176420 : || bitmap_bit_p (fi->solution, escaped_id))
6112 : : {
6113 : 176400 : pt_solution_reset (gimple_call_clobber_set (stmt));
6114 : 176400 : pt_solution_reset (gimple_call_use_set (stmt));
6115 : : }
6116 : : else
6117 : : {
6118 : 10 : bitmap_iterator bi;
6119 : 10 : unsigned i;
6120 : 10 : struct pt_solution *uses, *clobbers;
6121 : :
6122 : 10 : uses = gimple_call_use_set (stmt);
6123 : 10 : clobbers = gimple_call_clobber_set (stmt);
6124 : 10 : memset (uses, 0, sizeof (struct pt_solution));
6125 : 10 : memset (clobbers, 0, sizeof (struct pt_solution));
6126 : 27 : EXECUTE_IF_SET_IN_BITMAP (fi->solution, 0, i, bi)
6127 : : {
6128 : 17 : struct pt_solution sol;
6129 : :
6130 : 17 : vi = get_varinfo (i);
6131 : 17 : if (!vi->is_fn_info)
6132 : : {
6133 : : /* ??? We could be more precise here? */
6134 : 0 : uses->nonlocal = 1;
6135 : 0 : uses->ipa_escaped = 1;
6136 : 0 : clobbers->nonlocal = 1;
6137 : 0 : clobbers->ipa_escaped = 1;
6138 : 0 : continue;
6139 : : }
6140 : :
6141 : 17 : if (!uses->anything)
6142 : : {
6143 : 17 : sol = find_what_var_points_to
6144 : 17 : (node->decl,
6145 : : first_vi_for_offset (vi, fi_uses));
6146 : 17 : pt_solution_ior_into (uses, &sol);
6147 : : }
6148 : 17 : if (!clobbers->anything)
6149 : : {
6150 : 17 : sol = find_what_var_points_to
6151 : 17 : (node->decl,
6152 : : first_vi_for_offset (vi, fi_clobbers));
6153 : 17 : pt_solution_ior_into (clobbers, &sol);
6154 : : }
6155 : : }
6156 : : }
6157 : : }
6158 : : else
6159 : 0 : gcc_unreachable ();
6160 : : }
6161 : : }
6162 : :
6163 : 23449 : fn->gimple_df->ipa_pta = true;
6164 : :
6165 : : /* We have to re-set the final-solution cache after each function
6166 : : because what is a "global" is dependent on function context. */
6167 : 23449 : final_solutions->empty ();
6168 : 23449 : obstack_free (&final_solutions_obstack, NULL);
6169 : 23449 : gcc_obstack_init (&final_solutions_obstack);
6170 : : }
6171 : :
6172 : 4424 : delete_points_to_sets ();
6173 : :
6174 : 4424 : in_ipa_mode = 0;
6175 : :
6176 : 4424 : return 0;
6177 : : }
6178 : :
6179 : : namespace {
6180 : :
6181 : : const pass_data pass_data_ipa_pta =
6182 : : {
6183 : : SIMPLE_IPA_PASS, /* type */
6184 : : "pta", /* name */
6185 : : OPTGROUP_NONE, /* optinfo_flags */
6186 : : TV_IPA_PTA, /* tv_id */
6187 : : 0, /* properties_required */
6188 : : 0, /* properties_provided */
6189 : : 0, /* properties_destroyed */
6190 : : 0, /* todo_flags_start */
6191 : : 0, /* todo_flags_finish */
6192 : : };
6193 : :
6194 : : class pass_ipa_pta : public simple_ipa_opt_pass
6195 : : {
6196 : : public:
6197 : 562828 : pass_ipa_pta (gcc::context *ctxt)
6198 : 1125656 : : simple_ipa_opt_pass (pass_data_ipa_pta, ctxt)
6199 : : {}
6200 : :
6201 : : /* opt_pass methods: */
6202 : 229994 : bool gate (function *) final override
6203 : : {
6204 : 229994 : return (optimize
6205 : 149691 : && flag_ipa_pta
6206 : : /* Don't bother doing anything if the program has errors. */
6207 : 234418 : && !seen_error ());
6208 : : }
6209 : :
6210 : 281414 : opt_pass * clone () final override { return new pass_ipa_pta (m_ctxt); }
6211 : :
6212 : 4424 : unsigned int execute (function *) final override
6213 : : {
6214 : 4424 : return ipa_pta_execute ();
6215 : : }
6216 : :
6217 : : }; // class pass_ipa_pta
6218 : :
6219 : : } // anon namespace
6220 : :
6221 : : simple_ipa_opt_pass *
6222 : 281414 : make_pass_ipa_pta (gcc::context *ctxt)
6223 : : {
6224 : 281414 : return new pass_ipa_pta (ctxt);
6225 : : }
|